[
  {
    "path": ".github/CODE_OF_CONDUCT.md",
    "content": "# Code of Conduct\n\nThis project has adopted the code of conduct defined by the [Contributor Covenant](http://contributor-covenant.org/)\nto clarify expected behavior in our community.\nFor more information see the [.NET Foundation Code of Conduct](https://dotnetfoundation.org/code-of-conduct)."
  },
  {
    "path": ".github/CONTRIBUTING.md",
    "content": "# Contributions are welcome!\n\nBenchmarkDotNet is already a stable full-featured library which allows performing performance investigation on a professional level.\nAnd it continues to evolve!\nWe add new features all the time, but we have too many new cool ideas.\nAny help will be appreciated.\nYou can develop new features, fix bugs, improve the documentation, or do some other cool stuff.\n\nIf you want to contribute, check out the\n  [Contributing guide](http://benchmarkdotnet.org/Contributing.htm) and\n  [up-for-grabs](https://github.com/dotnet/BenchmarkDotNet/issues?q=is:open+is:issue+label:up-for-grabs) issues.\nIf you have new ideas or want to complain about bugs, feel free to [create a new issue](https://github.com/dotnet/BenchmarkDotNet/issues/new).\nLet's build the best tool for benchmarking together!"
  },
  {
    "path": ".github/FUNDING.yml",
    "content": "github: AndreyAkinshin\n"
  },
  {
    "path": ".github/workflows/generate-changelog.yaml",
    "content": "name: generate-changelog\nrun-name: Generate changelog / ${{ github.event.head_commit.message }}\n\non:\n  push:\n    branches:\n      - master\n  workflow_dispatch:\n\npermissions: write-all\n\njobs:\n  generate:\n    runs-on: ubuntu-latest\n    steps:\n\n    - name: Checkout\n      uses: actions/checkout@v6\n      with:\n        ref: master\n\n    - name: Checkout changelog\n      uses: actions/checkout@v6\n      with:\n        ref: docs-changelog\n        path: docs/_changelog\n\n    - name: Fetch changelog\n      run: ./build.cmd docs-fetch --depth 1 --preview\n      env:\n        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n\n    - name: Push changelog\n      uses: JamesIves/github-pages-deploy-action@9d877eea73427180ae43cf98e8914934fe157a1a # v4.7.6\n      with:\n        branch: docs-changelog\n        folder: docs/_changelog\n        git-config-name: Andrey Akinshin\n        git-config-email: andrey.akinshin@gmail.com\n        clean: true\n"
  },
  {
    "path": ".github/workflows/generate-coverage-report.yaml",
    "content": "name: generate-coverage-report\nrun-name: Generate coverage coverage report  ${{ github.event.head_commit.message }}\n\non:\n  workflow_dispatch:\n    inputs:\n      skip_integration_tests:\n        type: boolean\n        description: Set `true` to skip integration tests.\n        default: true\n        \nconcurrency:\n  group: ${{ github.workflow }}-${{ github.event.inputs.skip_integration_tests }}-${{ github.head_ref || github.ref || github.run_id }}\n  cancel-in-progress: true\n\njobs:\n  collect-coverage:\n    runs-on: ${{ matrix.os }}\n    defaults:\n      run:\n        shell: pwsh\n    strategy:\n      matrix:\n        # Note: ARM64 on linux/macos are not supported.\n        # https://github.com/microsoft/codecoverage/blob/main/docs/supported-os.md\n        os: [windows-latest, ubuntu-latest, macos-15-intel, windows-11-arm]\n    steps:\n      - uses: actions/checkout@v6\n\n      # Ensure DOTNET_ROOT environment variable set on macos-15-intel \n      - uses: actions/setup-dotnet@v5\n        with:\n          dotnet-version: |\n            8.x  \n\n      - name: Install dotnet-coverage\n        run: dotnet tool install --global dotnet-coverage\n\n      - name: Run task 'build'\n        run: dotnet build BenchmarkDotNet.slnx -c Release\n\n      - name: Start dotnet-coverage with background server mode\n        run: dotnet coverage collect --session-id bdn_coverage --settings tests/CodeCoverage.config --server-mode --background\n\n      - name: Collect Code Coverage\n        run: |\n          dotnet coverage connect bdn_coverage \"dotnet test tests/BenchmarkDotNet.Tests -c Release --no-build --framework net8.0\"\n          dotnet coverage connect bdn_coverage \"dotnet test tests/BenchmarkDotNet.Analyzers.Tests  -c Release --no-build --framework net8.0\"\n\n      - name: Collect Code Coverage for BenchmarkDotNet.IntegrationTests \n        if: ${{ github.event.inputs.skip_integration_tests == 'false'}} \n        run: |\n          dotnet coverage connect bdn_coverage 'dotnet test tests/BenchmarkDotNet.IntegrationTests -c Release --no-build --framework net8.0 --filter \"(FullyQualifiedName!~DotMemoryTests) & (FullyQualifiedName!~DotTraceTests) & (FullyQualifiedName!~WasmIsSupported) & (FullyQualifiedName!~WasmSupportsInProcessDiagnosers)\"'\n\n      - name: Shutdown dotnet-coverage server.\n        run: dotnet coverage shutdown bdn_coverage --timeout 60000\n\n      - name: Upload coverage artifact\n        uses: actions/upload-artifact@v6\n        with:\n          name: coverage-${{ matrix.os }}\n          path: \"**/*.cobertura.xml\"\n\n  collect-coverage-netfx:\n    runs-on: windows-latest\n    defaults:\n      run:\n        shell: pwsh\n    steps:\n      - uses: actions/checkout@v6\n\n      - name: Install dotnet-coverage\n        run: dotnet tool install --global dotnet-coverage\n\n      - name: Run task 'build'\n        run: dotnet build BenchmarkDotNet.slnx -c Release\n\n      - name: Start dotnet-coverage with background server mode\n        run: dotnet coverage collect --session-id bdn_coverage --settings tests/CodeCoverage.config --server-mode --background\n\n      - name: Collect Code Coverage\n        run: |\n          dotnet coverage connect bdn_coverage \"dotnet test tests/BenchmarkDotNet.Tests -c Release --no-build --framework net462\"\n          dotnet coverage connect bdn_coverage \"dotnet test tests/BenchmarkDotNet.Analyzers.Tests  -c Release --no-build --framework net462\"\n\n      - name: Collect Code Coverage for BenchmarkDotNet.IntegrationTests \n        if: ${{ github.event.inputs.skip_integration_tests == 'false'}} \n        run: |\n          dotnet coverage connect bdn_coverage 'dotnet test tests/BenchmarkDotNet.IntegrationTests -c Release --no-build --framework net462 --filter \"(FullyQualifiedName!~DotMemoryTests) & (FullyQualifiedName!~DotTraceTests) & (FullyQualifiedName!~WasmIsSupported) & (FullyQualifiedName!~WasmSupportsInProcessDiagnosers)\"'\n\n      - name: Shutdown dotnet-coverage server.\n        run: dotnet coverage shutdown bdn_coverage --timeout 60000\n\n      - name: Upload coverage artifact\n        uses: actions/upload-artifact@v6\n        with:\n          name: coverage-windows-netfx\n          path: \"**/*.cobertura.xml\"\n\n  generate-coverage-report:\n    needs: [collect-coverage, collect-coverage-netfx]\n    runs-on: ubuntu-latest\n    defaults:\n      run:\n        shell: pwsh\n    steps:\n      - uses: actions/checkout@v6\n\n      - uses: actions/download-artifact@v6\n        with:\n          path: coverage\n\n      - name: Upload raw coverage data\n        uses: actions/upload-artifact@v6\n        with:\n          name: coverage\n          path: coverage\n\n      - name: Rewrite file path map to absolute path\n        run: |\n          $baseSourcePath = Get-Location\n          $files =  [IO.Directory]::GetFiles(\"coverage\", \"coverage.cobertura.xml\", [IO.SearchOption]::AllDirectories)\n          foreach($file in $files)\n          {\n            $content = [IO.File]::ReadAllText($file).Replace(\"/_/\", [Environment]::CurrentDirectory + '/')\n            [IO.File]::WriteAllText($file, $content)\n          }\n\n      - name: Install ReportGenerator as global tool\n        run: dotnet tool install --global dotnet-reportgenerator-globaltool\n\n      - name: Geterate reports\n        run: |\n          reportgenerator `\n            -reports:\"coverage/**/coverage.cobertura.xml\" `\n            -targetdir:\"coverage_report/reports\" `\n            -reporttypes:\"Html;MarkdownSummaryGithub\"\n\n      - name: Create index.html\n        run: |\n          $html = @\"\n          <!DOCTYPE html>\n          <html>\n          <head>\n            <meta http-equiv=\"refresh\" content=\"0; url=reports/index.html\">\n            <title>Redirect</title>\n          </head>\n          <body>\n            <p>If you are not redirected automatically, <a href=\"reports/index.html\">click here</a>.</p>\n          </body>\n          </html>\n          \"@\n          [IO.File]::WriteAllText(\"coverage_report/index.html\", $html)\n\n      - name: Write coverage summary\n        run: |\n          $markdown = Get-Content coverage_report/reports/SummaryGithub.md -Raw\n          Write-Output $markdown >> $env:GITHUB_STEP_SUMMARY\n\n      - name: Upload HTML report files\n        uses: actions/upload-artifact@v6\n        with:\n          name: coverage_report\n          path: coverage_report\n"
  },
  {
    "path": ".github/workflows/generate-gh-pages.yaml",
    "content": "name: generate-gh-pages\nrun-name: Generate gh-pages / ${{ github.event.head_commit.message }}\n\non:\n  push:\n    branches:\n      - docs-stable\n  workflow_dispatch:\n\npermissions: write-all\n\njobs:\n  generate:\n    runs-on: windows-latest\n    steps:\n\n    - name: Checkout\n      uses: actions/checkout@v6\n      with:\n        ref: docs-stable\n\n    - name: Checkout changelog\n      uses: actions/checkout@v6\n      with:\n        ref: docs-changelog\n        path: docs/_changelog\n\n    - name: Build BenchmarkDotNet\n      run: ./build.cmd build\n\n    - name: Fetch changelog\n      run: ./build.cmd docs-fetch --depth 2 --preview\n      env:\n        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n\n    - name: Build documentation\n      run: ./build.cmd docs-build\n\n    - name: Upload Artifacts\n      uses: actions/upload-artifact@v6\n      with:\n        name: site\n        path: docs/_site\n\n  deploy:\n    concurrency: ci-${{ github.ref }}\n    needs: [generate]\n    runs-on: ubuntu-latest\n    steps:\n\n    - name: Checkout\n      uses: actions/checkout@v6\n      with:\n        ref: docs-stable\n\n    - name: Download Artifacts\n      uses: actions/download-artifact@v7\n      with:\n        name: site\n        path: site\n\n    - name: Print file tree\n      run: tree $GITHUB_WORKSPACE\n\n    - name: Deploy documentation\n      uses: JamesIves/github-pages-deploy-action@9d877eea73427180ae43cf98e8914934fe157a1a # v4.7.6\n      with:\n        branch: gh-pages\n        folder: site\n        git-config-name: GitHub Actions\n        git-config-email: actions@github.com\n        clean: true\n"
  },
  {
    "path": ".github/workflows/publish-nightly.yaml",
    "content": "name: publish-nightly\nrun-name: Publish nightly nupkg / ${{ github.event.head_commit.message }}\n\non:\n  push:\n    branches:\n      - master\n  workflow_dispatch:\n\njobs:\n  publish:\n    runs-on: ubuntu-latest\n    if: ${{ github.repository == 'dotnet/BenchmarkDotNet' }}\n    steps:\n      - uses: actions/checkout@v6\n      - name: Set date\n        run: echo \"DATE=$(date +'%Y%m%d')\" >> $GITHUB_ENV\n      - name: Pack\n        run: ./build.cmd pack /p:VersionSuffix=nightly.$DATE.$GITHUB_RUN_NUMBER\n      - name: Upload nupkg to artifacts\n        uses: actions/upload-artifact@v6\n        with:\n          name: nupkgs\n          path: \"**/*.*nupkg\"\n      - name: Publish nupkg\n        env:\n          MYGET_API_KEY: ${{ secrets.MYGET_API_KEY }}\n        run: ./.dotnet/dotnet nuget push **/*.nupkg --source https://www.myget.org/F/benchmarkdotnet/api/v3/index.json --api-key $MYGET_API_KEY --timeout 600\n"
  },
  {
    "path": ".github/workflows/release.yaml",
    "content": "name: release\nrun-name: Release new version\n\non:\n  workflow_dispatch:\n\nenv:\n  DOTNET_VERSION: \"8.0.410\"\n\njobs:\n  release:\n    runs-on: ubuntu-latest\n    environment: deploy # Only maintainers can execute this workflow\n    permissions:\n      contents: write\n      discussions: write\n      issues: write\n    steps:\n\n    # --- Init ---\n\n    - name: Checkout sources\n      uses: actions/checkout@v6\n\n    - name: Checkout changelog\n      uses: actions/checkout@v6\n      with:\n        ref: docs-changelog\n        path: docs/_changelog\n\n    - name: Setup .NET Core\n      uses: actions/setup-dotnet@v5\n      with:\n        dotnet-version: ${{ env.DOTNET_VERSION }}\n\n    - name: Read current version\n      id: version\n      run: echo \"VERSION=$(grep -v '^$' build/versions.txt | tail -n 1)\" >> $GITHUB_OUTPUT\n\n    # --- Main ---\n\n    - name: Tag release\n      run: git tag v${{ steps.version.outputs.VERSION }}\n\n    - name: Build\n      run: ./build.cmd build --stable\n\n    - name: Pack\n      run: ./build.cmd pack --stable\n\n    - name: Upload artifacts\n      uses: actions/upload-artifact@v4\n      with:\n        name: nupkgs\n        path: artifacts/*.nupkg\n\n    # --- Analyzer Rules and Next Version ---\n\n    - name: Move analyzer rules\n      run: ./build.cmd move-analyzer-rules\n\n    - name: Generate changelog\n      run: ./build.cmd docs-generate --stable\n      env:\n        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n\n    - name: Version increment\n      run: ./build.cmd version-increment\n\n    - name: Commit changes\n      uses: EndBug/add-and-commit@a94899bca583c204427a224a7af87c02f9b325d5 # v9.1.4\n      with:\n        message: \"Set next BenchmarkDotNet version: ${{ steps.version.outputs.VERSION }} and update released analyzer rules\"\n        author_name: GitHub Actions\n        author_email: actions@github.com\n        committer_name: GitHub Actions\n        committer_email: actions@github.com\n\n    - name: Read next version\n      id: next_version\n      run: echo \"NEXT_VERSION=$(grep -v '^$' build/versions.txt | tail -n 1)\" >> $GITHUB_OUTPUT\n\n    # --- Release ---\n\n    - name: Push git changes\n      uses: ad-m/github-push-action@77c5b412c50b723d2a4fbc6d71fb5723bcd439aa # v1.0.0\n      with:\n        github_token: ${{ secrets.GITHUB_TOKEN }}\n        branch: master\n        tags: true\n\n    - name: Release\n      uses: softprops/action-gh-release@a06a81a03ee405af7f2048a818ed3f03bbf83c7b # v2.5.0\n      with:\n        name: BenchmarkDotNet v${{ steps.version.outputs.VERSION }}\n        tag_name: v${{ steps.version.outputs.VERSION }}\n        body: |\n          Full changelog: https://benchmarkdotnet.org/changelog/v${{ steps.version.outputs.VERSION }}.html\n        discussion_category_name: Announcements\n\n    - name: Close old milestone\n      uses: Akkjon/close-milestone@v2.2.0\n      env:\n        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n      with:\n        milestone_name: v${{ steps.version.outputs.VERSION }}\n\n    - name: Create new milestone\n      uses: WyriHaximus/github-action-create-milestone@bcd9e15439836d6098d353a5bcf82de46591a35d # v1.1.2\n      env:\n        GITHUB_TOKEN: \"${{ secrets.GITHUB_TOKEN }}\"\n      with:\n        title: v${{ steps.next_version.outputs.NEXT_VERSION }}\n\n    - name: Publish to NuGet\n      run: dotnet nuget push ./artifacts/*.nupkg --api-key ${{ secrets.NUGET_API_KEY }} --source https://api.nuget.org/v3/index.json --skip-duplicate\n\n    # --- Documentation ---\n\n    - name: Fetch changelog\n      run: ./build.cmd docs-fetch --depth 2 --preview\n      env:\n        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n\n    - name: Generate changelog\n      run: ./build.cmd docs-generate --preview\n      env:\n        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n\n    - name: Push changelog\n      uses: JamesIves/github-pages-deploy-action@v4\n      with:\n        branch: docs-changelog\n        folder: docs/_changelog\n        git-config-name: GitHub Actions\n        git-config-email: actions@github.com\n        clean: true\n\n    - name: Build documentation\n      run: ./build.cmd docs-build\n\n    - name: Deploy documentation\n      uses: JamesIves/github-pages-deploy-action@9d877eea73427180ae43cf98e8914934fe157a1a # v4.7.6\n      with:\n        branch: gh-pages\n        folder: docs/_site\n        git-config-name: GitHub Actions\n        git-config-email: actions@github.com\n        clean: true\n"
  },
  {
    "path": ".github/workflows/run-tests-selected.yaml",
    "content": "name: run-tests-selected\nrun-name: Run selected tests (${{ inputs.runs_on }} --framework ${{ inputs.framework}} --filter ${{ inputs.filter }})\n\non:\n  workflow_dispatch:\n    inputs:\n      runs_on:\n        type: choice\n        description: GitHub Actions runner image name\n        required: true\n        default: ubuntu-latest\n        options:\n          - windows-latest\n          - ubuntu-latest\n          - macos-latest\n          - windows-11-arm\n          - ubuntu-24.04-arm\n          - macos-15-intel\n      project:\n        type: string\n        description: Specify test project path\n        required: true\n        default: tests/BenchmarkDotNet.IntegrationTests\n        options:\n          - tests/BenchmarkDotNet.Tests\n          - tests/BenchmarkDotNet.IntegrationTests\n          - tests/BenchmarkDotNet.IntegrationTests.ManualRunning\n      framework:\n        type: choice\n        description: Specify target framework\n        required: true\n        options:\n          - net8.0\n          - net462\n      filter:\n        type: string\n        description: Test filter text (It's used for `dotnet test --filter`) Use default value when running all tests\n        required: true\n        default: \"BenchmarkDotNet\"\n      iteration_count:\n        type: number\n        description: Count of test loop (It's expected to be used for flaky tests)\n        required: true\n        default: 1\n\njobs:\n  test:\n    name: test (${{ inputs.runs_on }} --framework ${{ inputs.framework}} --filter ${{ inputs.filter }})\n    runs-on: ${{ inputs.runs_on }}\n    timeout-minutes: 60 # Explicitly set timeout. When wrong input parameter is passed. It may continue to run until it times out (Default:360 minutes))\n    steps:\n      - uses: actions/checkout@v4\n\n      # Setup\n      - name: Setup\n        run: |\n          mkdir artifacts\n\n      - name: Install workloads\n        run: |\n          dotnet workload install wasm-tools\n          dotnet workload install wasm-tools-net8\n\n      - name: Set up node\n        uses: actions/setup-node@v6\n        with:\n          node-version: \"24\"\n      - name: Set up v8\n        shell: pwsh\n        run: |\n          npm install jsvu -g\n          jsvu --os=default --engines=v8\n\n          $homeDir = $env:HOME\n          if (-not $homeDir) {\n              $homeDir = $env:USERPROFILE\n          }\n\n          Add-Content -Path $env:GITHUB_PATH -Value (Join-Path $homeDir \".jsvu/bin\")\n\n      # Build\n      - name: Run build\n        working-directory: ${{ github.event.inputs.project }}\n        run: |\n          dotnet build -c Release --framework ${{ inputs.framework }} -tl:off\n\n      # Test\n      - name: Run tests\n        shell: pwsh\n        working-directory: ${{ github.event.inputs.project }}\n        run: |\n          $PSNativeCommandUseErrorActionPreference = $true\n          $iterationCount = ${{ inputs.iteration_count }}\n\n          foreach($i in 1..$iterationCount) {\n            Write-Output ('##[group]Executing Iteration: {0}/${{ inputs.iteration_count }}' -f $i)\n\n            dotnet test -c Release --framework ${{ inputs.framework }} --filter ${{ inputs.filter }} -tl:off --no-build --logger \"console;verbosity=normal\"\n\n            Write-Output '##[endgroup]'\n          }\n\n      # Upload artifact files that are located at `$(GITHUB_WORKSPACE)/artifacts` directory\n      - name: Upload test results\n        uses: actions/upload-artifact@v6\n        if: always()\n        with:\n          name: results\n          if-no-files-found: ignore\n          path: |\n            artifacts/**/*\n"
  },
  {
    "path": ".github/workflows/run-tests.yaml",
    "content": "name: run-tests\nrun-name: Run tests / ${{ github.event.head_commit.message }}\n\non:\n  pull_request:\n  push:\n  workflow_dispatch:\n\nconcurrency:\n  group: ${{ github.workflow }}-${{ github.head_ref || github.ref || github.run_id }}\n  cancel-in-progress: true\n\njobs:\n\n  test-windows-core:\n    strategy:\n      matrix:\n        os: [windows-latest, windows-11-arm]\n    runs-on: ${{ matrix.os }}\n    steps:\n      - name: Add Windows Defender Exclusions\n        shell: powershell\n        run: |\n          Add-MpPreference -ExclusionPath $env:GITHUB_WORKSPACE\n          Add-MpPreference -ExclusionPath $env:TEMP\n      - uses: actions/checkout@v6\n      # Setup wasm\n      - name: Set up node\n        uses: actions/setup-node@v6\n        with:\n          node-version: \"24\"\n      - name: Set up v8\n        run: |\n          npm install jsvu -g\n          jsvu --os=win64 --engines=v8\n          Add-Content -Path $env:GITHUB_PATH -Value \"$env:USERPROFILE\\.jsvu\\bin\"\n      - name: Install wasm-tools workload\n        run: ./build.cmd install-wasm-tools\n      # Build and Test\n      - name: Run task 'build'\n        shell: cmd\n        run: ./build.cmd build\n      - name: Run task 'unit-tests'\n        shell: cmd\n        run: ./build.cmd unit-tests -e\n      - name: Run task 'analyzer-tests'\n        shell: cmd\n        run: ./build.cmd analyzer-tests -e\n      - name: Run task 'in-tests-core'\n        shell: cmd\n        run: ./build.cmd in-tests-core -e\n      # Report test results with unique name\n      - name: Report tests results\n        uses: dorny/test-reporter@fe45e9537387dac839af0d33ba56eed8e24189e8 # v2.3.0\n        if: always()\n        with:\n          name: test-windows-core-${{ matrix.os }}\n          path: \"**/*.trx\"\n          reporter: dotnet-trx\n      # Upload Artifacts with Unique Name\n      - name: Upload test results\n        uses: actions/upload-artifact@v6\n        if: always()\n        with:\n          name: test-windows-core-trx-${{ github.run_id }}-${{ matrix.os }}\n          path: \"**/*.trx\"\n\n  test-windows-full:\n    strategy:\n      matrix:\n        os: [windows-latest, windows-11-arm]\n    runs-on: ${{ matrix.os }}\n    steps:\n      - name: Add Windows Defender Exclusions\n        shell: powershell\n        run: |\n          Add-MpPreference -ExclusionPath $env:GITHUB_WORKSPACE\n          Add-MpPreference -ExclusionPath $env:TEMP\n      - uses: actions/checkout@v6\n      # Setup wasm\n      - name: Set up node\n        uses: actions/setup-node@v6\n        with:\n          node-version: \"24\"\n      - name: Set up v8\n        run: |\n          npm install jsvu -g\n          jsvu --os=win64 --engines=v8\n          Add-Content -Path $env:GITHUB_PATH -Value \"$env:USERPROFILE\\.jsvu\\bin\"\n      - name: Install wasm-tools workload\n        run: ./build.cmd install-wasm-tools\n      # Build and Test\n      - name: Run task 'build'\n        shell: cmd\n        run: ./build.cmd build\n      - name: Run task 'unit-tests'\n        shell: cmd\n        run: ./build.cmd unit-tests -e\n      - name: Run task 'analyzer-tests'\n        shell: cmd\n        run: ./build.cmd analyzer-tests -e\n      - name: Run task 'in-tests-full'\n        shell: cmd\n        run: ./build.cmd in-tests-full -e\n      # Report test results with unique name\n      - name: Report tests results\n        uses: dorny/test-reporter@fe45e9537387dac839af0d33ba56eed8e24189e8 # v2.3.0\n        if: always()\n        with:\n          name: test-windows-full-${{ matrix.os }}\n          path: \"**/*.trx\"\n          reporter: dotnet-trx\n      # Upload Artifacts with Unique Name\n      - name: Upload test results\n        uses: actions/upload-artifact@v6\n        if: always()\n        with:\n          name: test-windows-full-trx-${{ github.run_id }}-${{ matrix.os }}\n          path: \"**/*.trx\"\n\n  test-linux:\n    strategy:\n      matrix:\n        os: [ubuntu-latest, ubuntu-24.04-arm]\n    runs-on: ${{ matrix.os }}\n    steps:\n      - uses: actions/checkout@v6\n      # Set up the environment\n      - name: Set up Clang\n        uses: egor-tensin/setup-clang@ef434b41eb33a70396fb336b1bae39c76d740c3d # v1.4\n        with:\n          version: latest\n          platform: x64\n      - name: Set up zlib-static\n        run: sudo apt-get install -y libkrb5-dev\n      - name: Set up node\n        uses: actions/setup-node@v6\n        with:\n          node-version: \"24\"\n      - name: Set up v8\n        run: npm install jsvu -g && jsvu --os=linux64 --engines=v8 && echo \"$HOME/.jsvu/bin\" >> $GITHUB_PATH\n      - name: Install wasm-tools workload\n        run: ./build.cmd install-wasm-tools\n      # Build and Test\n      - name: Run task 'build'\n        run: ./build.cmd build\n      - name: Run task 'analyzer-tests'\n        run: ./build.cmd analyzer-tests -e\n      - name: Run task 'unit-tests'\n        run: ./build.cmd unit-tests -e\n      - name: Run task 'in-tests-core'\n        run: ./build.cmd in-tests-core -e\n      # Report test results with unique name\n      - name: Report tests results\n        uses: dorny/test-reporter@fe45e9537387dac839af0d33ba56eed8e24189e8 # v2.3.0\n        if: always()\n        with:\n          name: test-linux-${{ matrix.os }}\n          path: \"**/*.trx\"\n          reporter: dotnet-trx\n      # Upload Artifacts with Unique Name\n      - name: Upload test results\n        uses: actions/upload-artifact@v6\n        if: always()\n        with:\n          name: test-linux-trx-${{ github.run_id }}-${{ matrix.os }}\n          path: \"**/*.trx\"\n\n  test-macos:\n    name: test-macos (${{ matrix.os.arch }})\n    runs-on: ${{ matrix.os.runs-on }}\n    strategy:\n      matrix:\n        os:\n          - runs-on: 'macos-latest'\n            jsvu-os: 'mac64arm'\n            arch: 'arm64'\n          - runs-on: 'macos-15-intel'\n            jsvu-os: 'mac64'\n            arch: 'x64'\n    steps:\n      - uses: actions/checkout@v6\n      - name: Set up node\n        uses: actions/setup-node@v6\n        with:\n          node-version: \"24\"\n      - name: Set up v8\n        run: npm install jsvu -g && jsvu --os=${{ matrix.os.jsvu-os }} --engines=v8 && echo \"$HOME/.jsvu/bin\" >> $GITHUB_PATH\n      - name: Install wasm-tools workload\n        run: ./build.cmd install-wasm-tools\n      # Build and Test\n      - name: Run task 'build'\n        run: ./build.cmd build\n      - name: Run task 'analyzer-tests'\n        run: ./build.cmd analyzer-tests -e\n      - name: Run task 'unit-tests'\n        run: ./build.cmd unit-tests -e\n      - name: Run task 'in-tests-core'\n        run: ./build.cmd in-tests-core -e\n      # Report test results with unique name\n      - name: Report tests results\n        uses: dorny/test-reporter@fe45e9537387dac839af0d33ba56eed8e24189e8 # v2.3.0\n        if: always()\n        with:\n          name: test-macos(${{ matrix.os.arch }})\n          path: \"**/*.trx\"\n          reporter: dotnet-trx\n      # Upload Artifacts with Unique Name\n      - name: Upload test results\n        uses: actions/upload-artifact@v6\n        if: always()\n        with:\n          name: test-macos(${{ matrix.os.arch }})-trx-${{ github.run_id }}\n          path: \"**/*.trx\"\n\n  test-pack:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v6\n      - name: Set up Clang\n        uses: egor-tensin/setup-clang@v1\n        with:\n          version: latest\n          platform: x64\n      - name: Set up zlib-static\n        run: sudo apt-get install -y libkrb5-dev\n      - name: Run task 'pack'\n        run: ./build.cmd pack\n\n  spellcheck-docs:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v6\n      - uses: actions/setup-node@v6\n        name: Setup node\n        with:\n          node-version: \"24\"\n      - name: Install cSpell\n        run: npm install -g cspell@9.0.2\n      - name: Copy cSpell config\n        run: cp ./build/cSpell.json ./cSpell.json\n      - name: Run cSpell\n        run: cspell --config ./cSpell.json \"docs/**/*.md\" --no-progress\n"
  },
  {
    "path": ".gitignore",
    "content": "# use glob syntax\nsyntax: glob\n\n*.obj\n*.pdb\n*.user\n*.aps\n*.pch\n*.vspscc\n*.vssscc\n*_i.c\n*_p.c\n*.ncb\n*.suo\n*.tlb\n*.tlh\n*.bak\n*.cache\n*.ilk\n*.log\n*.lib\n*.sbr\n*.scc\n[Bb]in\n[Dd]ebug*/\nobj/\n[Rr]elease*/\n_ReSharper*/\n[Tt]humbs.db\n[Tt]est[Rr]esult*\n[Bb]uild[Ll]og.*\n*.[Pp]ublish.xml\n*.resharper\n*.received.txt\n*.orig\npackages/\nnuget.exe\ndocs/guidehtml\ndocs/apihtml\n\n.idea/\n*.iml\n\n**/BenchmarkDotNet.Artifacts/*\n**/project.lock.json\ntests/output/*\n.vs/restore.dg\nartifacts/*\nBDN.Generated\nBenchmarkDotNet.Samples/Properties/launchSettings.json\nsrc/BenchmarkDotNet/Disassemblers/net462/*\nsrc/BenchmarkDotNet/Disassemblers/BenchmarkDotNet.Disassembler.*.nupkg\n\n# Visual Studio 2015 cache/options directory\n.vs/\n\n# VSCode directory\n.vscode/\n\n# Cake\ntools/**\n.dotnet\n\n# Xamarin\nResource.designer.cs\n\n# Tests\nTestResults\n\n## Mac OS\n\n# General\n.DS_Store\n.AppleDouble\n.LSOverride\n\n# Thumbnails\n._*\n"
  },
  {
    "path": "BenchmarkDotNet.slnx",
    "content": "<Solution>\n  <Folder Name=\"/build/\">\n    <File Path=\"build/common.props\" />\n    <File Path=\"build/common.targets\" />\n  </Folder>\n  <Folder Name=\"/samples/\">\n    <File Path=\"samples/Directory.Build.props\" />\n    <Project Path=\"samples/BenchmarkDotNet.Samples.FSharp/BenchmarkDotNet.Samples.FSharp.fsproj\" />\n    <Project Path=\"samples/BenchmarkDotNet.Samples/BenchmarkDotNet.Samples.csproj\" DefaultStartup=\"true\" />\n  </Folder>\n  <Folder Name=\"/src/\">\n    <Project Path=\"src/BenchmarkDotNet.Analyzers/BenchmarkDotNet.Analyzers.csproj\" />\n    <Project Path=\"src/BenchmarkDotNet.Annotations/BenchmarkDotNet.Annotations.csproj\" />\n    <Project Path=\"src/BenchmarkDotNet.Diagnostics.dotMemory/BenchmarkDotNet.Diagnostics.dotMemory.csproj\" />\n    <Project Path=\"src/BenchmarkDotNet.Diagnostics.dotTrace/BenchmarkDotNet.Diagnostics.dotTrace.csproj\" />\n    <Project Path=\"src/BenchmarkDotNet.Diagnostics.Windows/BenchmarkDotNet.Diagnostics.Windows.csproj\" />\n    <Project Path=\"src/BenchmarkDotNet.Disassembler/BenchmarkDotNet.Disassembler.csproj\" />\n    <Project Path=\"src/BenchmarkDotNet.Exporters.Plotting/BenchmarkDotNet.Exporters.Plotting.csproj\" />\n    <Project Path=\"src/BenchmarkDotNet.TestAdapter/BenchmarkDotNet.TestAdapter.csproj\" />\n    <Project Path=\"src/BenchmarkDotNet.Weaver/BenchmarkDotNet.Weaver.csproj\" />\n    <Project Path=\"src/BenchmarkDotNet/BenchmarkDotNet.csproj\" />\n  </Folder>\n  <Folder Name=\"/templates/\">\n    <Project Path=\"templates/BenchmarkDotNet.Templates.csproj\" />\n  </Folder>\n  <Folder Name=\"/tests/\">\n    <File Path=\"tests/Directory.Build.props\" />\n    <Project Path=\"tests/BenchmarkDotNet.Analyzers.Tests/BenchmarkDotNet.Analyzers.Tests.csproj\" />\n    <Project Path=\"tests/BenchmarkDotNet.Exporters.Plotting.Tests/BenchmarkDotNet.Exporters.Plotting.Tests.csproj\" />\n    <Project Path=\"tests/BenchmarkDotNet.IntegrationTests.ConfigPerAssembly/BenchmarkDotNet.IntegrationTests.ConfigPerAssembly.csproj\" />\n    <Project Path=\"tests/BenchmarkDotNet.IntegrationTests.CustomPaths/BenchmarkDotNet.IntegrationTests.CustomPaths.csproj\" />\n    <Project Path=\"tests/BenchmarkDotNet.IntegrationTests.DisabledOptimizations/BenchmarkDotNet.IntegrationTests.DisabledOptimizations.csproj\" />\n    <Project Path=\"tests/BenchmarkDotNet.IntegrationTests.EnabledOptimizations/BenchmarkDotNet.IntegrationTests.EnabledOptimizations.csproj\" />\n    <Project Path=\"tests/BenchmarkDotNet.IntegrationTests.FSharp/BenchmarkDotNet.IntegrationTests.FSharp.fsproj\" />\n    <Project Path=\"tests/BenchmarkDotNet.IntegrationTests.ManualRunning.MultipleFrameworks/BenchmarkDotNet.IntegrationTests.ManualRunning.MultipleFrameworks.csproj\" />\n    <Project Path=\"tests/BenchmarkDotNet.IntegrationTests.ManualRunning/BenchmarkDotNet.IntegrationTests.ManualRunning.csproj\" />\n    <Project Path=\"tests/BenchmarkDotNet.IntegrationTests.Static/BenchmarkDotNet.IntegrationTests.Static.csproj\" />\n    <Project Path=\"tests/BenchmarkDotNet.IntegrationTests.VisualBasic/BenchmarkDotNet.IntegrationTests.VisualBasic.vbproj\" />\n    <Project Path=\"tests/BenchmarkDotNet.IntegrationTests/BenchmarkDotNet.IntegrationTests.csproj\" />\n    <Project Path=\"tests/BenchmarkDotNet.Tests/BenchmarkDotNet.Tests.csproj\" />\n  </Folder>\n</Solution>\n\n"
  },
  {
    "path": "BenchmarkDotNet.slnx.DotSettings",
    "content": "﻿<wpf:ResourceDictionary xml:space=\"preserve\" xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\" xmlns:s=\"clr-namespace:System;assembly=mscorlib\" xmlns:ss=\"urn:shemas-jetbrains-com:settings-storage-xaml\" xmlns:wpf=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">\n\t<s:Boolean x:Key=\"/Default/CodeInspection/ExcludedFiles/FileMasksToSkip/=highlightingLabelsScript_002Ejs/@EntryIndexedValue\">True</s:Boolean>\n\t<s:String x:Key=\"/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=95F5D645_002D19E3_002D432F_002D95D4_002DC5EA374DD15B_002Fd_003AExporters_002Fd_003AJson_002Ff_003ASimpleJson_002Ecs/@EntryIndexedValue\">ExplicitlyExcluded</s:String>\n\t<s:String x:Key=\"/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=95F5D645_002D19E3_002D432F_002D95D4_002DC5EA374DD15B_002Fd_003ATemplates/@EntryIndexedValue\">ExplicitlyExcluded</s:String>\n\t<s:String x:Key=\"/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=95F5D645_002D19E3_002D432F_002D95D4_002DC5EA374DD15B_002Fd_003ATemplates_002Ff_003ABenchmarkProject_002Ejson/@EntryIndexedValue\">ExplicitlyExcluded</s:String>\n\t<s:String x:Key=\"/Default/CodeInspection/Highlighting/InspectionSeverities/=AccessToStaticMemberViaDerivedType/@EntryIndexedValue\">DO_NOT_SHOW</s:String>\n\t<s:String x:Key=\"/Default/CodeInspection/Highlighting/InspectionSeverities/=ArgumentsStyleAnonymousFunction/@EntryIndexedValue\">DO_NOT_SHOW</s:String>\n\t<s:String x:Key=\"/Default/CodeInspection/Highlighting/InspectionSeverities/=ArgumentsStyleLiteral/@EntryIndexedValue\">DO_NOT_SHOW</s:String>\n\t<s:String x:Key=\"/Default/CodeInspection/Highlighting/InspectionSeverities/=ArgumentsStyleNamedExpression/@EntryIndexedValue\">DO_NOT_SHOW</s:String>\n\t<s:String x:Key=\"/Default/CodeInspection/Highlighting/InspectionSeverities/=ArgumentsStyleOther/@EntryIndexedValue\">DO_NOT_SHOW</s:String>\n\t<s:String x:Key=\"/Default/CodeInspection/Highlighting/InspectionSeverities/=ArgumentsStyleStringLiteral/@EntryIndexedValue\">DO_NOT_SHOW</s:String>\n\t<s:String x:Key=\"/Default/CodeInspection/Highlighting/InspectionSeverities/=ArrangeAccessorOwnerBody/@EntryIndexedValue\">DO_NOT_SHOW</s:String>\n\t<s:String x:Key=\"/Default/CodeInspection/Highlighting/InspectionSeverities/=ArrangeConstructorOrDestructorBody/@EntryIndexedValue\"></s:String>\n\t<s:Boolean x:Key=\"/Default/CodeInspection/Highlighting/InspectionSeverities/=ArrangeConstructorOrDestructorBody/@EntryIndexRemoved\">True</s:Boolean>\n\t<s:String x:Key=\"/Default/CodeInspection/Highlighting/InspectionSeverities/=ArrangeLocalFunctionBody/@EntryIndexedValue\"></s:String>\n\t<s:Boolean x:Key=\"/Default/CodeInspection/Highlighting/InspectionSeverities/=ArrangeLocalFunctionBody/@EntryIndexRemoved\">True</s:Boolean>\n\t<s:String x:Key=\"/Default/CodeInspection/Highlighting/InspectionSeverities/=ArrangeMethodOrOperatorBody/@EntryIndexedValue\"></s:String>\n\t<s:Boolean x:Key=\"/Default/CodeInspection/Highlighting/InspectionSeverities/=ArrangeMethodOrOperatorBody/@EntryIndexRemoved\">True</s:Boolean>\n\t<s:String x:Key=\"/Default/CodeInspection/Highlighting/InspectionSeverities/=ConvertIfStatementToReturnStatement/@EntryIndexedValue\">DO_NOT_SHOW</s:String>\n\t<s:String x:Key=\"/Default/CodeInspection/Highlighting/InspectionSeverities/=InvertIf/@EntryIndexedValue\">DO_NOT_SHOW</s:String>\n\t<s:String x:Key=\"/Default/CodeInspection/Highlighting/InspectionSeverities/=RedundantArgumentDefaultValue/@EntryIndexedValue\">DO_NOT_SHOW</s:String>\n\t<s:String x:Key=\"/Default/CodeInspection/Highlighting/InspectionSeverities/=RedundantAttributeUsageProperty/@EntryIndexedValue\">DO_NOT_SHOW</s:String>\n\t<s:String x:Key=\"/Default/CodeInspection/Highlighting/InspectionSeverities/=RedundantExplicitTupleComponentName/@EntryIndexedValue\">DO_NOT_SHOW</s:String>\t\n\t<s:String x:Key=\"/Default/CodeInspection/Highlighting/InspectionSeverities/=RemoveRedundantBraces/@EntryIndexedValue\"></s:String>\n\t<s:String x:Key=\"/Default/CodeInspection/Highlighting/InspectionSeverities/=SuggestBaseTypeForParameter/@EntryIndexedValue\">DO_NOT_SHOW</s:String>\n\t<s:String x:Key=\"/Default/CodeInspection/Highlighting/InspectionSeverities/=ParameterTypeCanBeEnumerable_002ELocal/@EntryIndexedValue\">DO_NOT_SHOW</s:String>\n\t<s:String x:Key=\"/Default/CodeInspection/Highlighting/InspectionSeverities/=ParameterTypeCanBeEnumerable_002EGlobal/@EntryIndexedValue\">DO_NOT_SHOW</s:String>\n\t<s:String x:Key=\"/Default/CodeInspection/Highlighting/InspectionSeverities/=ReturnTypeCanBeEnumerable_002EGlobal/@EntryIndexedValue\">DO_NOT_SHOW</s:String>\n\t<s:String x:Key=\"/Default/CodeInspection/Highlighting/InspectionSeverities/=ReturnTypeCanBeEnumerable_002ELocal/@EntryIndexedValue\">DO_NOT_SHOW</s:String>\n\t<s:Boolean x:Key=\"/Default/CodeInspection/Highlighting/ReadSettingsFromFileLevel/@EntryValue\">True</s:Boolean>\n\t<s:String x:Key=\"/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_IFELSE/@EntryValue\">NotRequired</s:String>\n\t<s:String x:Key=\"/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/CONSTRUCTOR_OR_DESTRUCTOR_BODY/@EntryValue\">ExpressionBody</s:String>\n\t<s:String x:Key=\"/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/LOCAL_FUNCTION_BODY/@EntryValue\">ExpressionBody</s:String>\n\t<s:String x:Key=\"/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/METHOD_OR_OPERATOR_BODY/@EntryValue\">ExpressionBody</s:String>\n\t<s:Int64 x:Key=\"/Default/CodeStyle/CodeFormatting/CSharpFormat/BLANK_LINES_AFTER_BLOCK_STATEMENTS/@EntryValue\">0</s:Int64>\n\t<s:String x:Key=\"/Default/CodeStyle/CodeFormatting/CSharpFormat/EMPTY_BLOCK_STYLE/@EntryValue\">TOGETHER_SAME_LINE</s:String>\n\t<s:Boolean x:Key=\"/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_EXISTING_ATTRIBUTE_ARRANGEMENT/@EntryValue\">True</s:Boolean>\n\t<s:String x:Key=\"/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_ACCESSORHOLDER_ATTRIBUTE_ON_SAME_LINE_EX/@EntryValue\">NEVER</s:String>\n\t<s:Boolean x:Key=\"/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_FIELD_ATTRIBUTE_ON_SAME_LINE/@EntryValue\">False</s:Boolean>\n\t<s:String x:Key=\"/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_FIELD_ATTRIBUTE_ON_SAME_LINE_EX/@EntryValue\">NEVER</s:String>\n\t<s:Boolean x:Key=\"/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_METHOD_ATTRIBUTE_ON_SAME_LINE/@EntryValue\">False</s:Boolean>\n\t<s:String x:Key=\"/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_SIMPLE_EMBEDDED_STATEMENT_ON_SAME_LINE/@EntryValue\">NEVER</s:String>\n\t<s:Boolean x:Key=\"/Default/CodeStyle/CodeFormatting/CSharpFormat/SPACE_BEFORE_NEW_PARENTHESES/@EntryValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/CodeStyle/CodeFormatting/CSharpFormat/SPACE_WITHIN_SINGLE_LINE_ARRAY_INITIALIZER_BRACES/@EntryValue\">True</s:Boolean>\n\t<s:Int64 x:Key=\"/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_LIMIT/@EntryValue\">160</s:Int64>\n\t<s:String x:Key=\"/Default/CodeStyle/CSharpVarKeywordUsage/ForBuiltInTypes/@EntryValue\">UseExplicitType</s:String>\n\t<s:String x:Key=\"/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=ASCII/@EntryIndexedValue\">ASCII</s:String>\n\t<s:String x:Key=\"/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=GC/@EntryIndexedValue\">GC</s:String>\n\t<s:String x:Key=\"/Default/CodeStyle/CodeCleanup/Profiles/=BenchmarkDotNet/@EntryIndexedValue\">&lt;?xml version=\"1.0\" encoding=\"utf-16\"?&gt;&lt;Profile name=\"BenchmarkDotNet\"&gt;&lt;CSCodeStyleAttributes ArrangeTypeAccessModifier=\"True\" ArrangeTypeMemberAccessModifier=\"True\" SortModifiers=\"True\" RemoveRedundantParentheses=\"True\" AddMissingParentheses=\"True\" ArrangeBraces=\"True\" ArrangeAttributes=\"True\" ArrangeArgumentsStyle=\"True\" ArrangeCodeBodyStyle=\"True\" ArrangeVarStyle=\"True\" /&gt;&lt;CSFixBuiltinTypeReferences&gt;True&lt;/CSFixBuiltinTypeReferences&gt;&lt;CSOptimizeUsings&gt;&lt;OptimizeUsings&gt;True&lt;/OptimizeUsings&gt;&lt;EmbraceInRegion&gt;False&lt;/EmbraceInRegion&gt;&lt;RegionName&gt;&lt;/RegionName&gt;&lt;/CSOptimizeUsings&gt;&lt;CSReformatCode&gt;True&lt;/CSReformatCode&gt;&lt;/Profile&gt;</s:String>\n\t<s:String x:Key=\"/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=IL/@EntryIndexedValue\">IL</s:String>\n\t<s:String x:Key=\"/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=IO/@EntryIndexedValue\">IO</s:String>\n\t<s:String x:Key=\"/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=OSX/@EntryIndexedValue\">OSX</s:String>\n\t<s:String x:Key=\"/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=RT/@EntryIndexedValue\">RT</s:String>\n\t<s:String x:Key=\"/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateInstanceFields/@EntryIndexedValue\">&lt;Policy Inspect=\"True\" Prefix=\"\" Suffix=\"\" Style=\"aaBb\" /&gt;</s:String>\n\t<s:String x:Key=\"/Default/CodeStyle/Naming/CSharpNaming/UserRules/=4a98fdf6_002D7d98_002D4f5a_002Dafeb_002Dea44ad98c70c/@EntryIndexedValue\">&lt;Policy&gt;&lt;Descriptor Staticness=\"Instance\" AccessRightKinds=\"Private\" Description=\"Instance fields (private)\"&gt;&lt;ElementKinds&gt;&lt;Kind Name=\"FIELD\" /&gt;&lt;Kind Name=\"READONLY_FIELD\" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect=\"True\" Prefix=\"\" Suffix=\"\" Style=\"aaBb\" /&gt;&lt;/Policy&gt;</s:String>\n\t<s:String x:Key=\"/Default/CodeStyle/Naming/CSharpNaming/UserRules/=f9fce829_002De6f4_002D4cb2_002D80f1_002D5497c44f51df/@EntryIndexedValue\">&lt;Policy&gt;&lt;Descriptor Staticness=\"Static\" AccessRightKinds=\"Private\" Description=\"Static fields (private)\"&gt;&lt;ElementKinds&gt;&lt;Kind Name=\"FIELD\" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect=\"True\" Prefix=\"\" Suffix=\"\" Style=\"aaBb\" /&gt;&lt;/Policy&gt;</s:String>\n\t<s:Boolean x:Key=\"/Default/Environment/Filtering/ExcludeCoverageFilters/=_002A_003B_002A_003BJetBrains_002EAnnotations_002E_002A_003B_002A/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/Environment/Filtering/ExcludeCoverageFilters/=_002A_003B_002A_003BSimpleJson_002E_002A_003B_002A/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Int64 x:Key=\"/Default/Environment/Hierarchy/Build/BuildTool/MsbuildVersion/@EntryValue\">983040</s:Int64>\n\t<s:Boolean x:Key=\"/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EdotCover_002EIde_002ECore_002EFilterManagement_002EModel_002ESolutionFilterSettingsManagerMigrateSettings/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpAttributeForSingleLineMethodUpgrade/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpKeepExistingMigration/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpPlaceAttributeOnSameLineMigration/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpPlaceEmbeddedOnSameLineMigration/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpRenamePlacementToArrangementMigration/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpUseContinuousIndentInsideBracesMigration/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EAddAccessorOwnerDeclarationBracesMigration/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002ECSharpPlaceAttributeOnSameLineMigration/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateThisQualifierSettings/@EntryIndexedValue\">True</s:Boolean>\n    <s:String x:Key=\"/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateInstanceFields/@EntryIndexedValue\">&lt;Policy Inspect=\"True\" Prefix=\"\" Suffix=\"\" Style=\"aaBb\" /&gt;</s:String>\n    <s:String x:Key=\"/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateStaticFields/@EntryIndexedValue\">&lt;Policy Inspect=\"True\" Prefix=\"\" Suffix=\"\" Style=\"aaBb\" /&gt;</s:String>\n\t<s:Boolean x:Key=\"/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EPredefinedNamingRulesToUserRulesUpgrade/@EntryIndexedValue\">True</s:Boolean>\n\t<s:String x:Key=\"/Default/FilterSettingsManager/CoverageFilterXml/@EntryValue\">&lt;data&gt;&lt;IncludeFilters /&gt;&lt;ExcludeFilters&gt;&lt;Filter ModuleMask=\"*\" ModuleVersionMask=\"*\" ClassMask=\"JetBrains.Annotations.*\" FunctionMask=\"*\" IsEnabled=\"True\" /&gt;&lt;Filter ModuleMask=\"*\" ModuleVersionMask=\"*\" ClassMask=\"SimpleJson.*\" FunctionMask=\"*\" IsEnabled=\"True\" /&gt;&lt;/ExcludeFilters&gt;&lt;/data&gt;</s:String>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=Acpi/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=Affinitize/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=affinitized/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=Algo/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=appconfig/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=asciidoc/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=Atlassian/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=Autocorrect/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=barplot/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=Baselining/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=Benchmarked/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=boxplot/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=Branchless/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=BYREF/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=canbenull/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=Capitan/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=CODEFILENAME/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=codegen/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=comparers/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=COMPLUS/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=coreclr/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=corefx/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=corert/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=cpuinfo/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=csprojs/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=ctors/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=Diaconis/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=Diagnoser/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=Diagnoser_0027s/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=Diagnosers/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=disasm/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=Disassemblers/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=Disassembly/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=dlls/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=DOCTYPE/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=Dont/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=DONTTOUCH/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=Epilog/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=excel_0027s/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=ffbfd/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=fffffff/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=formattable/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=frac/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=fsproj/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=hacktastic/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=hardcode/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=Hmmss/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=Hpet/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=Hypervisor/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=hypervisors/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=ilcompiler/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=informations/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=Infos/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=infty/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=Inlining/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=intellisense/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=Interquartile/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=Invocator/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=iparam/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=Jits/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=jitting/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=Kurtosis/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=ldarg/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=ldloc/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=libc/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=LINQPAD/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=lscpu/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=macos/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=macrobenchmarks/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=Maoni/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=microarchitecture/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=microarchitectures/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=microbenchmarking/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=mscorlib/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=mspperror/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=Multimodal/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=Multimodal/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=mutators/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=mvalue/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=Mware/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=nano/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=netstandard/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=newguid/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=noconfig/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=noformat/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=nollvm/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=NONINFRINGEMENT/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=notcs/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=nuget/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=openmetrics/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=outofproc/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=parameterless/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=Partitioner/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=pdbonly/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=Perfolizer/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=perfonar/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=poco/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=Prerelease/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=Prettifier/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=profilesources/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=Proj/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=Prolog/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=pvalue/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=Quadrimodal/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=Redstone/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=reimplement/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=runtimes/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=ryzen/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=sgen/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=SHADOWCOPY/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=Shortified/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=sitnik/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=sproj/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=stackoverflow/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=stddev/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=stloc/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=Sturges/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=subfolder/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=subq/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=Sysctl/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=Sysname/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=Tailcall/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=tailedness/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=Tost/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=tracelog/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=transpiler/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=tukey/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=uname/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=Unimodal/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=versioning/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=verylong/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=virtualbox/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=Virtualization/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=vmware/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=Warmup/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=Wasm/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=Welch/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=Welch_0027s/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=Wmic/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=Workgroups/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=xproj/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=xprojs/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=xunit/@EntryIndexedValue\">True</s:Boolean>\n</wpf:ResourceDictionary>"
  },
  {
    "path": "LICENSE.md",
    "content": "### The MIT License\n\nCopyright (c) 2013–2025 .NET Foundation and contributors\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "NuGet.Config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n  <solution>\n    <add key=\"disableSourceControlIntegration\" value=\"true\" />\n  </solution>\n  <packageSources>\n    <!--To inherit the global NuGet package sources remove the <clear/> line below -->\n    <clear />\n\n    <add key=\"api.nuget.org\" value=\"https://api.nuget.org/v3/index.json\" />\n    <!-- required to run Mono AOT benchmarks -->\n    <add key=\"dotnet6\" value=\"https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet6/nuget/v3/index.json\" />\n    <add key=\"dotnet7\" value=\"https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet7/nuget/v3/index.json\" />\n    <add key=\"dotnet8\" value=\"https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet8/nuget/v3/index.json\" />\n    <add key=\"dotnet9\" value=\"https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet9/nuget/v3/index.json\" />\n    <add key=\"dotnet10\" value=\"https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet10/nuget/v3/index.json\" />\n    <add key=\"dotnet11\" value=\"https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet11/nuget/v3/index.json\" />\n\n    <!-- required for Roslyn analyzers -->\n\t<add key=\"dotnet-tools\" value=\"https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json\" />\n\n    <add key=\"benchmarkdotnet.weaver\" value=\"src/BenchmarkDotNet.Weaver/packages\" />\n  </packageSources>\n</configuration>\n"
  },
  {
    "path": "README.md",
    "content": "<div align=\"center\">\n\n  ![](https://raw.githubusercontent.com/dotnet/BenchmarkDotNet/ec962b0bd6854c991d7a3ebd77037579165acb36/docs/logo/logo-wide.png)\n\n</div>\n\n<div align=\"center\">\n\n  [![NuGet](https://img.shields.io/nuget/v/BenchmarkDotNet.svg)](https://www.nuget.org/packages/BenchmarkDotNet/)\n  [![MyGet](https://img.shields.io/myget/benchmarkdotnet/vpre/benchmarkdotnet?label=myget)](https://www.myget.org/feed/benchmarkdotnet/package/nuget/BenchmarkDotNet)\n  [![Downloads](https://img.shields.io/nuget/dt/benchmarkdotnet.svg)](https://www.nuget.org/packages/BenchmarkDotNet/)\n  [![Stars](https://img.shields.io/github/stars/dotnet/BenchmarkDotNet?color=brightgreen)](https://github.com/dotnet/BenchmarkDotNet/stargazers)\n  [![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/dotnet/BenchmarkDotNet/blob/master/LICENSE.md)\n  [![Twitter](https://img.shields.io/twitter/follow/BenchmarkDotNet?style=social&label=Twitter)](https://twitter.com/BenchmarkDotNet)\n\n</div>\n\n<div align=\"center\" style=\"font-size: 130%; margin-bottom: 20px\">\n  <a href=\"#features\">Features</a>\n  <span> · </span>\n  <a href=\"https://benchmarkdotnet.org/articles/guides/getting-started.html\">Getting started</a>\n  <span> · </span>\n  <a href=\"https://benchmarkdotnet.org/articles/overview.html\">Documentation</a>\n  <span> · </span>\n  <a href=\"#learn-more-about-benchmarking\">Learn more about benchmarking</a>\n</div>\n\n**BenchmarkDotNet** helps you to transform methods into benchmarks, track their performance, and share reproducible measurement experiments.\nIt's no harder than writing unit tests!\nUnder the hood, it performs a lot of [magic](#automation) that guarantees [reliable and precise](#reliability) results thanks to the [perfolizer](https://github.com/AndreyAkinshin/perfolizer) and [pragmastat](https://github.com/AndreyAkinshin/pragmastat) statistical engine.\nBenchmarkDotNet protects you from popular benchmarking mistakes and warns you if something is wrong with your benchmark design or obtained measurements.\nThe results are presented in a [user-friendly](#friendliness) form that highlights all the important facts about your experiment.\nBenchmarkDotNet is already adopted by [27400+ GitHub projects](https://github.com/dotnet/BenchmarkDotNet/network/dependents) including\n  [.NET Runtime](https://github.com/dotnet/runtime),\n  [.NET Compiler](https://github.com/dotnet/roslyn),\n  [.NET Performance](https://github.com/dotnet/performance),\n  and many others.\n\nIt's [easy](#simplicity) to start writing benchmarks, check out the following example\n  (copy-pastable version is [here](https://benchmarkdotnet.org/articles/guides/getting-started.html)):\n\n```cs\n[SimpleJob(RuntimeMoniker.Net472, baseline: true)]\n[SimpleJob(RuntimeMoniker.NetCoreApp30)]\n[SimpleJob(RuntimeMoniker.NativeAot70)]\n[SimpleJob(RuntimeMoniker.Mono)]\n[RPlotExporter]\npublic class Md5VsSha256\n{\n    private SHA256 sha256 = SHA256.Create();\n    private MD5 md5 = MD5.Create();\n    private byte[] data;\n\n    [Params(1000, 10000)]\n    public int N;\n\n    [GlobalSetup]\n    public void Setup()\n    {\n        data = new byte[N];\n        new Random(42).NextBytes(data);\n    }\n\n    [Benchmark]\n    public byte[] Sha256() => sha256.ComputeHash(data);\n\n    [Benchmark]\n    public byte[] Md5() => md5.ComputeHash(data);\n}\n```\n\nBenchmarkDotNet automatically\n  runs the benchmarks on all the runtimes,\n  aggregates the measurements,\n  and prints a summary table with the most important information:\n\n```md\nBenchmarkDotNet=v0.12.0, OS=Windows 10.0.17763.805 (1809/October2018Update/Redstone5)\nIntel Core i7-7700K CPU 4.20GHz (Kaby Lake), 1 CPU, 8 logical and 4 physical cores\n  [Host]       : .NET Framework 4.7.2 (4.7.3468.0), X64 RyuJIT\n  Net472       : .NET Framework 4.7.2 (4.7.3468.0), X64 RyuJIT\n  NetCoreApp30 : .NET Core 3.0.0 (CoreCLR 4.700.19.46205, CoreFX 4.700.19.46214), X64 RyuJIT\n  NativeAot70  : .NET 7.0.0-preview.4.22172.7, X64 NativeAOT\n  Mono         : Mono 6.4.0 (Visual Studio), X64\n\n\n| Method |       Runtime |     N |       Mean |     Error |    StdDev | Ratio |\n|------- |-------------- |------ |-----------:|----------:|----------:|------:|\n| Sha256 |    .NET 4.7.2 |  1000 |   7.735 us | 0.1913 us | 0.4034 us |  1.00 |\n| Sha256 | .NET Core 3.0 |  1000 |   3.989 us | 0.0796 us | 0.0745 us |  0.50 |\n| Sha256 | NativeAOT 7.0 |  1000 |   4.091 us | 0.0811 us | 0.1562 us |  0.53 |\n| Sha256 |          Mono |  1000 |  13.117 us | 0.2485 us | 0.5019 us |  1.70 |\n|        |               |       |            |           |           |       |\n|    Md5 |    .NET 4.7.2 |  1000 |   2.872 us | 0.0552 us | 0.0737 us |  1.00 |\n|    Md5 | .NET Core 3.0 |  1000 |   1.848 us | 0.0348 us | 0.0326 us |  0.64 |\n|    Md5 | NativeAOT 7.0 |  1000 |   1.817 us | 0.0359 us | 0.0427 us |  0.63 |\n|    Md5 |          Mono |  1000 |   3.574 us | 0.0678 us | 0.0753 us |  1.24 |\n|        |               |       |            |           |           |       |\n| Sha256 |    .NET 4.7.2 | 10000 |  74.509 us | 1.5787 us | 4.6052 us |  1.00 |\n| Sha256 | .NET Core 3.0 | 10000 |  36.049 us | 0.7151 us | 1.0025 us |  0.49 |\n| Sha256 | NativeAOT 7.0 | 10000 |  36.253 us | 0.7076 us | 0.7571 us |  0.49 |\n| Sha256 |          Mono | 10000 | 116.350 us | 2.2555 us | 3.0110 us |  1.58 |\n|        |               |       |            |           |           |       |\n|    Md5 |    .NET 4.7.2 | 10000 |  17.308 us | 0.3361 us | 0.4250 us |  1.00 |\n|    Md5 | .NET Core 3.0 | 10000 |  15.726 us | 0.2064 us | 0.1930 us |  0.90 |\n|    Md5 | NativeAOT 7.0 | 10000 |  15.627 us | 0.2631 us | 0.2461 us |  0.89 |\n|    Md5 |          Mono | 10000 |  30.205 us | 0.5868 us | 0.6522 us |  1.74 |\n\n```\n\nThe measured data can be exported to different formats (md, html, csv, xml, json, etc.) including plots:\n\n![](https://raw.githubusercontent.com/dotnet/BenchmarkDotNet/ec962b0bd6854c991d7a3ebd77037579165acb36/docs/images/v0.12.0/rplot.png)\n\n*Supported runtimes:* .NET 5+, .NET Framework 4.6.1+, .NET Core 2.0+, Mono, NativeAOT  \n*Supported languages:* C#, F#, Visual Basic  \n*Supported OS:* Windows, Linux, macOS  \n*Supported architectures:* x86, x64, ARM, ARM64, Wasm and LoongArch64\n\n## Features\n\nBenchmarkDotNet has tons of features that are essential in comprehensive performance investigations.\nFour aspects define the design of these features:\n  *simplicity*, *automation*, *reliability*, and *friendliness*.\n\n### Simplicity\n\nYou shouldn't have to be an experienced performance engineer if you want to write benchmarks.\nYou can design very complicated performance experiments in the declarative style using simple APIs.\n\nFor example, if you want to [parameterize](https://benchmarkdotnet.org/articles/features/parameterization.html) your benchmark,\n  mark a field or a property with `[Params(1, 2, 3)]`: BenchmarkDotNet will enumerate all of the specified values\n  and run benchmarks for each case.\nIf you want to compare benchmarks with each other,\n  mark one of the benchmarks as the [baseline](https://benchmarkdotnet.org/articles/features/baselines.html)\n  via `[Benchmark(Baseline = true)]`: BenchmarkDotNet will compare it with all of the other benchmarks.\nIf you want to compare performance in different environments, use [jobs](https://benchmarkdotnet.org/articles/configs/jobs.html).\nFor example, you can run all the benchmarks on .NET 8.0 and Mono via\n  `[SimpleJob(RuntimeMoniker.Net80)]` and `[SimpleJob(RuntimeMoniker.Mono)]`.\n\nIf you don't like attributes, you can call most of the APIs via the fluent style and write code like this:\n\n```cs\nManualConfig.CreateEmpty() // A configuration for our benchmarks\n    .AddJob(Job.Default // Adding first job\n        .WithRuntime(ClrRuntime.Net472) // .NET Framework 4.7.2\n        .WithPlatform(Platform.X64) // Run as x64 application\n        .WithJit(Jit.LegacyJit) // Use LegacyJIT instead of the default RyuJIT\n        .WithGcServer(true) // Use Server GC\n    ).AddJob(Job.Default // Adding second job\n        .AsBaseline() // It will be marked as baseline\n        .WithEnvironmentVariable(\"Key\", \"Value\") // Setting an environment variable\n        .WithWarmupCount(0) // Disable warm-up stage\n    );\n```\n\nIf you prefer command-line experience, you can configure your benchmarks via\n  the [console arguments](https://benchmarkdotnet.org/articles/guides/console-args.html)\n  in any console application (other types of applications are not supported).\n\n### Automation\n\nReliable benchmarks always include a lot of boilerplate code.\n\nLet's think about what you should do in a typical case.\nFirst, you should perform a pilot experiment and determine the best number of method invocations.\nNext, you should execute several warm-up iterations and ensure that your benchmark achieved a steady state.\nAfter that, you should execute the main iterations and calculate some basic statistics.\nIf you calculate some values in your benchmark, you should use it somehow to prevent dead code elimination.\nIf you use loops, you should care about the effect of the loop unrolling on your results\n  (which may depend on the processor architecture).\nOnce you get results, you should check for some special properties of the obtained performance distribution\n  like multimodality or extremely high outliers.\nYou should also evaluate the overhead of your infrastructure and deduct it from your results.\nIf you want to test several environments, you should perform the measurements in each of them and manually aggregate the results.\n\nIf you write this code from scratch, it's easy to make a mistake and spoil your measurements.\nNote that it's a shortened version of the full checklist that you should follow during benchmarking:\n  there are a lot of additional hidden pitfalls that should be handled appropriately.\nFortunately, you shouldn't worry about it because\n  BenchmarkDotNet [will perform](https://benchmarkdotnet.org/articles/guides/how-it-works.html) this boring and time-consuming stuff for you.\n\nMoreover, the library can help you with some advanced tasks that you may want to perform during the investigation.\nFor example,\n  BenchmarkDotNet can measure the [managed](https://benchmarkdotnet.org/articles/configs/diagnosers.html#usage) and\n  [native](https://benchmarkdotnet.org/articles/samples/IntroNativeMemory.html) memory traffic\n  and print [disassembly listings](https://benchmarkdotnet.org/articles/configs/diagnosers.html#sample-introdisassembly) for your benchmarks.\n\n### Reliability\n\nA lot of hand-written benchmarks produce wrong numbers that lead to incorrect business decisions.\nBenchmarkDotNet protects you from most of the benchmarking pitfalls and allows achieving high measurement precision.\n\nYou shouldn't worry about the perfect number of method invocation, the number of warm-up and actual iterations:\n  BenchmarkDotNet tries to choose the best benchmarking parameters and\n  achieve a good trade-off between the measurement prevision and the total duration of all benchmark runs.\nSo, you shouldn't use any magic numbers (like \"We should perform 100 iterations here\"),\n  the library will do it for you based on the values of statistical metrics.\n\nBenchmarkDotNet also prevents benchmarking of non-optimized assemblies that were built using DEBUG mode because\n  the corresponding results will be unreliable.\nThe library will print a warning if you have an attached debugger,\n  if you use a hypervisor (HyperV, VMware, VirtualBox),\n  or if you have any other problems with the current environment.\n\nDuring 6+ years of development, we faced dozens of different problems that may spoil your measurements.\nInside BenchmarkDotNet, there are a lot of heuristics, checks, hacks, and tricks that help you to\n  increase the reliability of the results.\n\n### Friendliness\n\nAnalysis of performance data is a time-consuming activity that requires attentiveness, knowledge, and experience.\nBenchmarkDotNet performs the main part of this analysis for you and presents results in a user-friendly form.\n\nAfter the experiments, you get a summary table that contains a lot of useful data about the executed benchmarks.\nBy default, it includes only the most important columns,\n  but they can be [easily customized](https://benchmarkdotnet.org/articles/configs/columns.html).\nThe column set is adaptive and depends on the benchmark definition and measured values.\nFor example, if you mark one of the benchmarks as a [baseline](https://benchmarkdotnet.org/articles/features/baselines.html),\n  you will get additional columns that will help you to compare all the benchmarks with the baseline.\nBy default, it always shows the Mean column,\n  but if we detected a vast difference between the Mean and the Median values,\n  both columns will be presented.\n\nBenchmarkDotNet tries to find some unusual properties of your performance distributions and prints nice messages about it.\nFor example, it will warn you in case of multimodal distribution or high outliers.\nIn this case, you can scroll the results up and check out ASCII-style histograms for each distribution\n  or generate beautiful png plots using `[RPlotExporter]`.\n\nBenchmarkDotNet doesn't overload you with data; it shows only the essential information depending on your results:\n  it allows you to keep the summary small for primitive cases and extend it only for complicated cases.\nOf course, you can request any additional statistics and visualizations manually.\nIf you don't customize the summary view,\n  the default presentation will be as much user-friendly as possible. :)\n\n## Learn more about benchmarking\n\nBenchmarkDotNet is not a silver bullet that magically makes all of your benchmarks correct and analyzes the measurements for you.\nEven if you use this library, you still should know how to design benchmark experiments and how to make correct conclusions based on the raw data.\nIf you want to know more about benchmarking methodology and good practices,\n  it's recommended to read a book by Andrey Akinshin (the BenchmarkDotNet project lead): [\"Pro .NET Benchmarking\"](https://aakinshin.net/prodotnetbenchmarking/).\nUse this in-depth guide to correctly design benchmarks, measure key performance metrics of .NET applications, and analyze results.\nThis book presents dozens of case studies to help you understand complicated benchmarking topics.\nYou will avoid common pitfalls, control the accuracy of your measurements, and improve the performance of your software.\n\n<div align=\"center\">\n  <a href=\"https://aakinshin.net/prodotnetbenchmarking/\">\n    <img src=\"https://aakinshin.net/img/misc/prodotnetbenchmarking-cover.png\" width=\"400\" />\n  </a>\n</div>\n\n## Contributions are welcome!\n\nBenchmarkDotNet is already a stable full-featured library that allows performing performance investigation on a professional level.\nAnd it continues to evolve!\nWe add new features all the time, but we have too many new cool ideas.\nAny help will be appreciated.\nYou can develop new features, fix bugs, improve the documentation, or do some other cool stuff.\n\nIf you want to contribute, check out the\n  [Contributing guide](https://benchmarkdotnet.org/articles/contributing/building.html) and\n  [up-for-grabs](https://github.com/dotnet/BenchmarkDotNet/issues?q=is:open+is:issue+label:up-for-grabs) issues.\nIf you have new ideas or want to complain about bugs, feel free to [create a new issue](https://github.com/dotnet/BenchmarkDotNet/issues/new).\nLet's build the best tool for benchmarking together!\n\n## Code of Conduct\n\nThis project has adopted the code of conduct defined by the [Contributor Covenant](https://www.contributor-covenant.org/)\nto clarify expected behavior in our community.\nFor more information, see the [.NET Foundation Code of Conduct](https://dotnetfoundation.org/code-of-conduct).\n"
  },
  {
    "path": "build/BenchmarkDotNet.Build/BenchmarkDotNet.Build.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n  <PropertyGroup>\n    <OutputType>Exe</OutputType>\n    <TargetFramework>net10.0</TargetFramework>\n    <RunWorkingDirectory>$(MSBuildProjectDirectory)</RunWorkingDirectory>\n    <Nullable>enable</Nullable>\n  </PropertyGroup>\n  <ItemGroup>\n    <PackageReference Include=\"Cake.Frosting\" Version=\"6.0.0\" />\n    <PackageReference Include=\"Cake.FileHelpers\" Version=\"7.0.0\" />\n    <PackageReference Include=\"Cake.Git\" Version=\"5.0.1\" />\n    <PackageReference Include=\"Docfx.App\" Version=\"2.78.5\" />\n    <PackageReference Include=\"Octokit\" Version=\"14.0.0\" />\n  </ItemGroup>\n</Project>\n"
  },
  {
    "path": "build/BenchmarkDotNet.Build/BuildContext.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Text;\nusing BenchmarkDotNet.Build.Helpers;\nusing BenchmarkDotNet.Build.Meta;\nusing BenchmarkDotNet.Build.Options;\nusing BenchmarkDotNet.Build.Runners;\nusing Cake.Common;\nusing Cake.Common.Build;\nusing Cake.Common.Diagnostics;\nusing Cake.Common.IO;\nusing Cake.Common.Tools.DotNet;\nusing Cake.Common.Tools.DotNet.MSBuild;\nusing Cake.Core;\nusing Cake.Core.IO;\nusing Cake.FileHelpers;\nusing Cake.Frosting;\n\nnamespace BenchmarkDotNet.Build;\n\npublic class BuildContext : FrostingContext\n{\n    public string BuildConfiguration { get; set; } = \"Release\";\n    public DotNetVerbosity BuildVerbosity { get; set; } = DotNetVerbosity.Minimal;\n\n    public DirectoryPath RootDirectory { get; }\n    public DirectoryPath BuildDirectory { get; }\n    public DirectoryPath ArtifactsDirectory { get; }\n\n    public FilePath SolutionFile { get; }\n    public FilePath AnalyzersProjectFile { get; }\n    public FilePath TemplatesTestsProjectFile { get; }\n    public FilePathCollection AllPackableSrcProjects { get; }\n    public FilePath VersionsFile { get; }\n    public FilePath CommonPropsFile { get; }\n    public FilePath ReadmeFile { get; }\n\n    public DotNetMSBuildSettings MsBuildSettingsRestore { get; }\n    public DotNetMSBuildSettings MsBuildSettingsBuild { get; }\n    public DotNetMSBuildSettings MsBuildSettingsPack { get; }\n\n    private bool IsCiBuild => !this.BuildSystem().IsLocalBuild;\n\n    public IReadOnlyCollection<string> NuGetPackageNames { get; }\n\n    public VersionHistory VersionHistory { get; }\n\n    public GitRunner GitRunner { get; }\n    public UnitTestRunner UnitTestRunner { get; }\n    public DocumentationRunner DocumentationRunner { get; }\n    public BuildRunner BuildRunner { get; }\n    public ReleaseRunner ReleaseRunner { get; }\n\n    public BuildContext(ICakeContext context)\n        : base(context)\n    {\n        RootDirectory = new DirectoryPath(new DirectoryInfo(Directory.GetCurrentDirectory()).Parent?.Parent?.FullName);\n        BuildDirectory = RootDirectory.Combine(\"build\");\n        ArtifactsDirectory = RootDirectory.Combine(\"artifacts\");\n\n        var toolFileName = context.IsRunningOnWindows() ? \"dotnet.exe\" : \"dotnet\";\n        var toolFilePath = RootDirectory.Combine(\".dotnet\").CombineWithFilePath(toolFileName);\n        context.Tools.RegisterFile(toolFilePath);\n\n        SolutionFile = RootDirectory.CombineWithFilePath(\"BenchmarkDotNet.slnx\");\n        AnalyzersProjectFile = RootDirectory.Combine(\"src\").Combine(\"BenchmarkDotNet.Analyzers\").CombineWithFilePath(\"BenchmarkDotNet.Analyzers.csproj\");\n\n        TemplatesTestsProjectFile = RootDirectory.Combine(\"templates\")\n            .CombineWithFilePath(\"BenchmarkDotNet.Templates.csproj\");\n        AllPackableSrcProjects = new FilePathCollection(context.GetFiles(RootDirectory.FullPath + \"/src/**/*.csproj\")\n            .Where(p => !p.FullPath.Contains(\"Disassembler\")));\n\n        VersionsFile = BuildDirectory.CombineWithFilePath(\"versions.txt\");\n        CommonPropsFile = BuildDirectory.CombineWithFilePath(\"common.props\");\n        ReadmeFile = RootDirectory.CombineWithFilePath(\"README.md\");\n\n        MsBuildSettingsRestore = new DotNetMSBuildSettings();\n        MsBuildSettingsBuild = new DotNetMSBuildSettings();\n        MsBuildSettingsPack = new DotNetMSBuildSettings();\n\n        if (IsCiBuild)\n        {\n            System.Environment.SetEnvironmentVariable(\"BDN_CI_BUILD\", \"true\");\n\n            MsBuildSettingsBuild.MaxCpuCount = 1;\n            MsBuildSettingsBuild.WithProperty(\"UseSharedCompilation\", \"false\");\n        }\n\n\n        if (context.Arguments.HasArgument(\"msbuild\"))\n        {\n            var msBuildParameters = context.Arguments.GetArguments().First(it => it.Key == \"msbuild\").Value;\n            foreach (var msBuildParameter in msBuildParameters)\n            {\n                var split = msBuildParameter.Split(new[] { '=' }, 2);\n                if (split.Length == 2)\n                {\n                    var name = split[0];\n                    var value = split[1];\n\n                    MsBuildSettingsRestore.WithProperty(name, value);\n                    MsBuildSettingsBuild.WithProperty(name, value);\n                    MsBuildSettingsPack.WithProperty(name, value);\n\n                    if (name.Equals(\"configuration\", StringComparison.OrdinalIgnoreCase)) BuildConfiguration = value;\n\n                    if (name.Equals(\"verbosity\", StringComparison.OrdinalIgnoreCase))\n                    {\n                        var parsedVerbosity = Utils.ParseVerbosity(value);\n                        if (parsedVerbosity != null)\n                            BuildVerbosity = parsedVerbosity.Value;\n                    }\n                }\n            }\n        }\n\n        if (KnownOptions.Stable.Resolve(this))\n        {\n            const string name = \"NoVersionSuffix\";\n            const string value = \"true\";\n            MsBuildSettingsRestore.WithProperty(name, value);\n            MsBuildSettingsBuild.WithProperty(name, value);\n            MsBuildSettingsPack.WithProperty(name, value);\n        }\n\n        // NativeAOT build requires VS C++ tools to be added to $path via vcvars64.bat\n        // but once we do that, dotnet restore fails with:\n        // \"Please specify a valid solution configuration using the Configuration and Platform properties\"\n        if (context.IsRunningOnWindows())\n        {\n            MsBuildSettingsRestore.WithProperty(\"Platform\", \"Any CPU\");\n            MsBuildSettingsBuild.WithProperty(\"Platform\", \"Any CPU\");\n        }\n\n        var nuGetPackageNames = new List<string>();\n        nuGetPackageNames.AddRange(this\n            .GetSubDirectories(RootDirectory.Combine(\"src\"))\n            .Select(directoryPath => directoryPath.GetDirectoryName())\n            .Where(name => !name.Contains(\"Disassembler\", StringComparison.OrdinalIgnoreCase)));\n        nuGetPackageNames.Add(\"BenchmarkDotNet.Templates\");\n        nuGetPackageNames.Sort();\n        NuGetPackageNames = nuGetPackageNames;\n\n        VersionHistory = new VersionHistory(this, VersionsFile);\n\n        GitRunner = new GitRunner(this);\n        UnitTestRunner = new UnitTestRunner(this);\n        DocumentationRunner = new DocumentationRunner(this);\n        BuildRunner = new BuildRunner(this);\n        ReleaseRunner = new ReleaseRunner(this);\n    }\n\n    public void GenerateFile(FilePath filePath, StringBuilder content)\n    {\n        GenerateFile(filePath, content.ToString());\n    }\n\n    public void GenerateFile(FilePath filePath, string content, bool reportNoChanges = false)\n    {\n        this.EnsureDirectoryExists(filePath.GetDirectory());\n        var relativePath = RootDirectory.GetRelativePath(filePath);\n        if (this.FileExists(filePath))\n        {\n            var oldContent = this.FileReadText(filePath);\n            if (content == oldContent)\n            {\n                if (reportNoChanges)\n                    this.Information(\"[NoChanges] \" + relativePath);\n                return;\n            }\n\n            this.FileWriteText(filePath, content);\n            this.Information(\"[Updated] \" + relativePath);\n        }\n        else\n        {\n            this.FileWriteText(filePath, content);\n            this.Information(\"[Generated] \" + relativePath);\n        }\n    }\n\n    public void RunOnlyInPushMode(Action action)\n    {\n        if (KnownOptions.Push.Resolve(this))\n        {\n            action();\n        }\n        else\n            this.Information(\"  Skip because PushMode is disabled\");\n    }\n}"
  },
  {
    "path": "build/BenchmarkDotNet.Build/CommandLineParser.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Reflection;\nusing System.Runtime.InteropServices;\nusing BenchmarkDotNet.Build.Options;\nusing Cake.Frosting;\n\nnamespace BenchmarkDotNet.Build;\n\npublic class CommandLineParser\n{\n    private const string ScriptName = \"build.cmd\";\n\n    private static readonly string CallScriptName =\n        (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) ? ScriptName : \"./\" + ScriptName;\n\n    public static readonly CommandLineParser Instance = new();\n\n    public string[]? Parse(string[]? args)\n    {\n        if (args == null || args.Length == 0 || (args.Length == 1 && Is(args[0], \"help\", \"--help\", \"-h\")))\n        {\n            PrintHelp();\n            return null;\n        }\n\n        if (Is(args[0], \"cake\"))\n            return args.Skip(1).ToArray();\n\n        var argsToProcess = new Queue<string>(args);\n\n        var taskName = argsToProcess.Dequeue();\n        if (Is(taskName, \"-t\", \"--target\") && argsToProcess.Any())\n            taskName = argsToProcess.Dequeue();\n\n        var taskNames = GetTaskNames();\n        var matchedTaskName = taskNames\n            .FirstOrDefault(name => string.Equals(name.Replace(\"-\", \"\"), taskName.Replace(\"-\", \"\"),\n                StringComparison.OrdinalIgnoreCase));\n        if (matchedTaskName == null)\n        {\n            PrintError($\"'{taskName}' is not a task\");\n            return null;\n        }\n\n        taskName = matchedTaskName;\n\n        if (argsToProcess.Count == 1 && Is(argsToProcess.Peek(), \"-h\", \"--help\"))\n        {\n            PrintTaskHelp(taskName);\n            return null;\n        }\n\n        var cakeArgs = new List<string>\n        {\n            \"--target\",\n            taskName\n        };\n        while (argsToProcess.Any())\n        {\n            var arg = argsToProcess.Dequeue();\n\n            if (arg.StartsWith(\"/p:\"))\n            {\n                cakeArgs.Add(\"--msbuild\");\n                cakeArgs.Add(arg[3..]);\n                continue;\n            }\n\n            if (arg.StartsWith('-'))\n            {\n                cakeArgs.Add(arg);\n                if (argsToProcess.Any() && !argsToProcess.Peek().StartsWith('-'))\n                    cakeArgs.Add(argsToProcess.Dequeue());\n                continue;\n            }\n\n            PrintError(\"Unknown option: \" + arg);\n            return null;\n        }\n\n        return cakeArgs.ToArray();\n    }\n\n\n    private readonly IOption[] baseOptions =\n    {\n        KnownOptions.Verbosity, KnownOptions.Exclusive, KnownOptions.Help, KnownOptions.Stable\n    };\n\n    private void PrintHelp()\n    {\n        WriteHeader(\"Description:\");\n\n        WritePrefix();\n        WriteLine(\"BenchmarkDotNet build script\");\n\n        WriteLine();\n\n        WriteHeader(\"Usage:\");\n\n        WritePrefix();\n        Write(CallScriptName + \" \");\n        WriteTask(\"<TASK> \");\n        WriteOption(\"[OPTIONS]\");\n        WriteLine();\n\n        WriteLine();\n\n        PrintExamples(GetTasks().SelectMany(task => task.HelpInfo.Examples).ToList());\n\n        PrintOptions(baseOptions);\n\n        WriteHeader(\"Tasks:\");\n        var taskWidth = GetTaskNames().Max(name => name.Length) + 3;\n        foreach (var (taskName, taskDescription, _) in GetTasks())\n        {\n            if (taskName.Equals(\"Default\", StringComparison.OrdinalIgnoreCase))\n                continue;\n\n            WriteTask(\"    \" + taskName.PadRight(taskWidth));\n            Write(taskDescription);\n\n            WriteLine();\n        }\n    }\n\n    private void PrintTaskHelp(string taskName)\n    {\n        var taskType = typeof(BuildContext).Assembly\n            .GetTypes()\n            .Where(type => type.IsSubclassOf(typeof(FrostingTask<BuildContext>)) && !type.IsAbstract)\n            .First(type => Is(type.GetCustomAttribute<TaskNameAttribute>()?.Name, taskName));\n        taskName = taskType.GetCustomAttribute<TaskNameAttribute>()!.Name;\n        var taskDescription = taskType.GetCustomAttribute<TaskDescriptionAttribute>()?.Description ?? \"\";\n        var helpInfo = GetHelpInfo(taskType);\n\n        WriteHeader(\"Description:\");\n\n        WritePrefix();\n        WriteLine(!string.IsNullOrWhiteSpace(taskDescription)\n            ? $\"Task '{taskName}': {taskDescription}\"\n            : $\"Task '{taskName}'\");\n\n        if (!string.IsNullOrWhiteSpace(helpInfo.Description))\n            foreach (var line in helpInfo.Description.Split('\\n', StringSplitOptions.RemoveEmptyEntries))\n            {\n                WritePrefix();\n                WriteLine(line.TrimEnd());\n            }\n\n        WriteLine();\n\n        WriteHeader(\"Usage:\");\n\n        WritePrefix();\n        Write(CallScriptName + \" \");\n        WriteTask(taskName + \" \");\n        WriteOption(\"[OPTIONS]\");\n        WriteLine();\n\n        WriteLine();\n\n        PrintExamples(helpInfo.Examples);\n\n        PrintOptions(helpInfo.Options.Concat(baseOptions).ToArray());\n\n        if (helpInfo.EnvironmentVariables.Any())\n        {\n            WriteHeader(\"Environment variables:\");\n            foreach (var envVar in helpInfo.EnvironmentVariables)\n            {\n                WritePrefix();\n                WriteOption(envVar.Name);\n                WriteLine();\n            }\n        }\n    }\n\n    private void PrintOptions(IOption[] options)\n    {\n        const string valuePlaceholder = \"<VALUE>\";\n\n        WriteLine(\"Options:\", ConsoleColor.DarkCyan);\n\n        int GetWidth(IOption option)\n        {\n            int width = option.CommandLineName.Length;\n            foreach (var alias in option.Aliases)\n                width += 1 + alias.Length;\n            if (option is StringOption)\n                width += 1 + valuePlaceholder.Length;\n            return width;\n        }\n\n        const int descriptionGap = 3;\n        var maxWidth = options.Max(GetWidth) + descriptionGap;\n\n        foreach (var option in options)\n        {\n            var allNames = option.Aliases.Append(option.CommandLineName).OrderBy(name => name.Length);\n            var joinName = string.Join(',', allNames);\n\n            WritePrefix();\n            WriteOption(joinName);\n            if (option is StringOption)\n            {\n                Write(\" \");\n                WriteArg(valuePlaceholder);\n            }\n\n            Write(new string(' ',\n                maxWidth - joinName.Length - (option is StringOption ? valuePlaceholder.Length + 1 : 0)));\n            var descriptionLines = option.Description.Split(new[] { '\\n' }, StringSplitOptions.RemoveEmptyEntries);\n            Write(descriptionLines.FirstOrDefault() ?? \"\");\n            for (int i = 1; i < descriptionLines.Length; i++)\n            {\n                WriteLine();\n                WritePrefix();\n                Write(new string(' ', maxWidth));\n                Write(descriptionLines[i]);\n            }\n\n            WriteLine();\n        }\n\n        WritePrefix();\n        WriteOption(\"/p:\");\n        WriteArg(\"<KEY>\");\n        WriteOption(\"=\");\n        WriteArg(valuePlaceholder);\n        Write(new string(' ', maxWidth - \"/p:<KEY>=\".Length - valuePlaceholder.Length));\n        Write(\"Passes custom properties to MSBuild\");\n        WriteLine();\n\n        WriteLine();\n    }\n\n    private void PrintExamples(IReadOnlyList<Example> examples)\n    {\n        if (!examples.Any())\n            return;\n        WriteHeader(\"Examples:\");\n\n        foreach (var example in examples)\n        {\n            WritePrefix();\n            Write(CallScriptName + \" \");\n            WriteTask(example.TaskName + \" \");\n            foreach (var (name, value, isMsBuild) in example.Arguments)\n            {\n                if (isMsBuild)\n                {\n                    WriteOption(\"/p:\");\n                    WriteArg(name);\n                    WriteOption(\"=\");\n                    WriteArg(value + \" \");\n                }\n                else\n                {\n                    WriteOption(name + \" \");\n                    if (value != null)\n                        WriteArg(value + \" \");\n                }\n            }\n\n            WriteLine();\n        }\n\n        WriteLine();\n    }\n\n    private static HashSet<string> GetTaskNames()\n    {\n        return GetTasks().Select(task => task.Name).ToHashSet(StringComparer.OrdinalIgnoreCase);\n    }\n\n    private static List<(string Name, string Description, HelpInfo HelpInfo)> GetTasks()\n    {\n        return typeof(BuildContext).Assembly\n            .GetTypes()\n            .Where(type => type.IsSubclassOf(typeof(FrostingTask<BuildContext>)) && !type.IsAbstract)\n            .Select(type => (\n                Name: type.GetCustomAttribute<TaskNameAttribute>()?.Name ?? \"\",\n                Description: type.GetCustomAttribute<TaskDescriptionAttribute>()?.Description ?? \"\",\n                HelpInfo: GetHelpInfo(type)\n            ))\n            .Where(task => task.Name != \"\")\n            .ToList();\n    }\n\n    private static HelpInfo GetHelpInfo(Type taskType)\n    {\n        return Activator.CreateInstance(taskType) is IHelpProvider helpProvider\n            ? helpProvider.GetHelp()\n            : new HelpInfo();\n    }\n\n    private static bool Is(string? arg, params string[] values) =>\n        values.Any(value => value.Equals(arg, StringComparison.OrdinalIgnoreCase));\n\n    private void PrintError(string text)\n    {\n        Console.ForegroundColor = ConsoleColor.Red;\n        Console.Error.WriteLine(\"ERROR: \" + text);\n        Console.WriteLine();\n        Console.ResetColor();\n        PrintHelp();\n    }\n\n    private void WritePrefix() => Write(\"    \");\n    private void WriteTask(string message) => Write(message, ConsoleColor.Green);\n    private void WriteOption(string message) => Write(message, ConsoleColor.Blue);\n    private void WriteArg(string message) => Write(message, ConsoleColor.DarkYellow);\n    private void WriteObsolete(string message) => Write(message, ConsoleColor.Gray);\n\n    private void WriteHeader(string message)\n    {\n        WriteLine(message, ConsoleColor.DarkCyan);\n    }\n\n    private void Write(string message, ConsoleColor? color = null)\n    {\n        if (color != null)\n            Console.ForegroundColor = color.Value;\n        Console.Write(message);\n        if (color != null)\n            Console.ResetColor();\n    }\n\n    private void WriteLine(string message = \"\", ConsoleColor? color = null)\n    {\n        Write(message, color);\n        Console.WriteLine();\n    }\n}"
  },
  {
    "path": "build/BenchmarkDotNet.Build/EnvVar.cs",
    "content": "using System;\n\nnamespace BenchmarkDotNet.Build;\n\npublic class EnvVar\n{\n    public static readonly EnvVar GitHubToken = new(\"GITHUB_TOKEN\");\n    public static readonly EnvVar NuGetToken = new(\"NUGET_TOKEN\");\n\n    public string Name { get; }\n\n    private EnvVar(string name) => Name = name;\n\n    public string? GetValue() => Environment.GetEnvironmentVariable(Name);\n\n    public void AssertHasValue()\n    {\n        if (string.IsNullOrEmpty(GetValue()))\n            throw new Exception($\"Environment variable '{Name}' is not specified!\");\n    }\n\n    public void SetEmpty() => Environment.SetEnvironmentVariable(Name, \"\");\n}"
  },
  {
    "path": "build/BenchmarkDotNet.Build/Example.cs",
    "content": "using System.Collections.Generic;\nusing BenchmarkDotNet.Build.Options;\n\nnamespace BenchmarkDotNet.Build;\n\npublic class Example\n{\n    private readonly List<Argument> arguments = new();\n\n    public string TaskName { get; }\n    public IReadOnlyCollection<Argument> Arguments => arguments;\n\n    public Example(string taskName)\n    {\n        TaskName = taskName;\n    }\n\n    public Example WithMsBuildArgument(string name, string value)\n    {\n        arguments.Add(new Argument(name, value, true));\n        return this;\n    }\n\n    public Example WithArgument(BoolOption option)\n    {\n        arguments.Add(new Argument(option.CommandLineName, null, false));\n        return this;\n    }\n\n    public Example WithArgument(StringOption option, string value)\n    {\n        arguments.Add(new Argument(option.CommandLineName, value, false));\n        return this;\n    }\n\n\n    public record Argument(string Name, string? Value, bool IsMsBuild);\n}"
  },
  {
    "path": "build/BenchmarkDotNet.Build/Folder.DotSettings",
    "content": "﻿<wpf:ResourceDictionary xml:space=\"preserve\" xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\" xmlns:s=\"clr-namespace:System;assembly=mscorlib\" xmlns:ss=\"urn:shemas-jetbrains-com:settings-storage-xaml\" xmlns:wpf=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">\n\t<s:String x:Key=\"/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateInstanceFields/@EntryIndexedValue\">&lt;Policy Inspect=\"True\" Prefix=\"\" Suffix=\"\" Style=\"aaBb\" /&gt;</s:String>\n\t<s:String x:Key=\"/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateStaticFields/@EntryIndexedValue\">&lt;Policy Inspect=\"True\" Prefix=\"\" Suffix=\"\" Style=\"aaBb\" /&gt;</s:String>\n\t<s:String x:Key=\"/Default/CodeStyle/Naming/CSharpNaming/UserRules/=4a98fdf6_002D7d98_002D4f5a_002Dafeb_002Dea44ad98c70c/@EntryIndexedValue\">&lt;Policy&gt;&lt;Descriptor Staticness=\"Instance\" AccessRightKinds=\"Private\" Description=\"Instance fields (private)\"&gt;&lt;ElementKinds&gt;&lt;Kind Name=\"FIELD\" /&gt;&lt;Kind Name=\"READONLY_FIELD\" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect=\"True\" Prefix=\"\" Suffix=\"\" Style=\"aaBb\" /&gt;&lt;/Policy&gt;</s:String>\n\t<s:String x:Key=\"/Default/CodeStyle/Naming/CSharpNaming/UserRules/=f9fce829_002De6f4_002D4cb2_002D80f1_002D5497c44f51df/@EntryIndexedValue\">&lt;Policy&gt;&lt;Descriptor Staticness=\"Static\" AccessRightKinds=\"Private\" Description=\"Static fields (private)\"&gt;&lt;ElementKinds&gt;&lt;Kind Name=\"FIELD\" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect=\"True\" Prefix=\"\" Suffix=\"\" Style=\"aaBb\" /&gt;&lt;/Policy&gt;</s:String>\n\t<s:Boolean x:Key=\"/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EPredefinedNamingRulesToUserRulesUpgrade/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/UserDictionary/Words/=Nupkg/@EntryIndexedValue\">True</s:Boolean></wpf:ResourceDictionary>"
  },
  {
    "path": "build/BenchmarkDotNet.Build/HelpInfo.cs",
    "content": "using System;\nusing BenchmarkDotNet.Build.Options;\n\nnamespace BenchmarkDotNet.Build;\n\npublic class HelpInfo\n{\n    public string Description { get; init; } = \"\";\n    public IOption[] Options { get; init; } = Array.Empty<IOption>();\n    public EnvVar[] EnvironmentVariables { get; init; } = Array.Empty<EnvVar>();\n    public Example[] Examples { get; init; } = Array.Empty<Example>();\n}"
  },
  {
    "path": "build/BenchmarkDotNet.Build/Helpers/OctokitExtensions.cs",
    "content": "using System;\nusing System.Linq;\nusing Octokit;\n\nnamespace BenchmarkDotNet.Build.Helpers;\n\npublic static class OctokitExtensions\n{\n    public static string ToStr(this User? user, string prefix) => user != null\n        ? $\" ({prefix} [@{user.Login}]({user.HtmlUrl}))\"\n        : \"\";\n\n    private static string ToStr(this Author? user, string prefix) => user != null\n        ? $\" ({prefix} {user.ToLink()})\"\n        : \"\";\n\n    private static string ToStr(this Committer? user, string prefix) => user != null\n        ? $\" ({prefix} {user.Name})\"\n        : \"\";\n\n    public static string ToLink(this Author user) => $\"[@{user.Login}]({user.HtmlUrl})\";\n\n    public static string ToLinkWithName(this Author user, string name) => $\"[@{user.Login} ({name})]({user.HtmlUrl})\";\n\n    public static string ToCommitMessage(this Commit commit)\n    {\n        var message = commit.Message.Trim().Split(new[] { '\\r', '\\n' }, StringSplitOptions.RemoveEmptyEntries)\n            .FirstOrDefault() ?? \"\";\n        return message.Length > 80 ? message.Substring(0, 77) + \"...\" : message;\n    }\n\n    public static string ToLink(this GitHubCommit commit) => $\"[{commit.Sha.Substring(0, 6)}]({commit.HtmlUrl})\";\n\n    public static string ToByStr(this GitHubCommit commit)\n    {\n        if (commit.Author != null)\n            return commit.Author.ToStr(\"by\");\n        return commit.Commit.Author != null ? commit.Commit.Author.ToStr(\"by\") : \"\";\n    }\n}"
  },
  {
    "path": "build/BenchmarkDotNet.Build/Helpers/Utils.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Runtime.InteropServices;\nusing System.Text.RegularExpressions;\nusing Cake.Common.Tools.DotNet;\nusing Octokit;\n\nnamespace BenchmarkDotNet.Build.Helpers;\n\npublic static class Utils\n{\n    public static string GetOs()\n    {\n        if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))\n            return \"linux\";\n        if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))\n            return \"windows\";\n        if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))\n            return \"macos\";\n        return \"unknown\";\n    }\n\n    public static DotNetVerbosity? ParseVerbosity(string verbosity)\n    {\n        var lookup = new Dictionary<string, DotNetVerbosity>(StringComparer.OrdinalIgnoreCase)\n        {\n            { \"q\", DotNetVerbosity.Quiet },\n            { \"quiet\", DotNetVerbosity.Quiet },\n            { \"m\", DotNetVerbosity.Minimal },\n            { \"minimal\", DotNetVerbosity.Minimal },\n            { \"n\", DotNetVerbosity.Normal },\n            { \"normal\", DotNetVerbosity.Normal },\n            { \"d\", DotNetVerbosity.Detailed },\n            { \"detailed\", DotNetVerbosity.Detailed },\n            { \"diag\", DotNetVerbosity.Diagnostic },\n            { \"diagnostic\", DotNetVerbosity.Diagnostic }\n        };\n        return lookup.TryGetValue(verbosity, out var value) ? value : null;\n    }\n\n    public static GitHubClient CreateGitHubClient()\n    {\n        EnvVar.GitHubToken.AssertHasValue();\n\n        var client = new GitHubClient(new ProductHeaderValue(\"BenchmarkDotNet\"));\n        var tokenAuth = new Credentials(EnvVar.GitHubToken.GetValue());\n        client.Credentials = tokenAuth;\n        return client;\n    }\n\n    public static string ApplyRegex(string content, string pattern, string newValue)\n    {\n        var regex = new Regex(pattern);\n        var match = regex.Match(content);\n        if (!match.Success)\n            throw new Exception(\"Failed to apply regex\");\n\n        var oldValue = match.Groups[1].Value;\n        return content.Replace(oldValue, newValue);\n    }\n}"
  },
  {
    "path": "build/BenchmarkDotNet.Build/IHelpProvider.cs",
    "content": "namespace BenchmarkDotNet.Build;\n\npublic interface IHelpProvider\n{\n    HelpInfo GetHelp();\n}"
  },
  {
    "path": "build/BenchmarkDotNet.Build/Meta/Repo.cs",
    "content": "using System;\nusing System.Net.Http;\nusing System.Text.RegularExpressions;\nusing System.Threading.Tasks;\n\nnamespace BenchmarkDotNet.Build.Meta;\n\npublic static class Repo\n{\n    public const string Owner = \"dotnet\";\n    public const string Name = \"BenchmarkDotNet\";\n    private const string HttpsUrlBase = $\"https://github.com/{Owner}/{Name}\";\n    public const string SshGitUrl = $\"git@github.com:{Owner}/{Name}.git\";\n    \n    public const string ChangelogBranch = \"docs-changelog\";\n    public const string DocsStableBranch = \"docs-stable\";\n    public const string MasterBranch = \"master\";\n\n    public const string MaintainerAuthorName = \"GitHub Actions\";\n    public const string MaintainerAuthorEmail = \"actions@github.com\";\n    \n    public static async Task<int> GetDependentProjectsNumber()\n    {\n        using var httpClient = new HttpClient();\n        const string url = $\"{HttpsUrlBase}/network/dependents\";\n        var response = await httpClient.GetAsync(new Uri(url));\n        var dependentsPage = await response.Content.ReadAsStringAsync();\n        var match = new Regex(@\"([0-9\\,]+)[\\n\\r\\s]+Repositories\").Match(dependentsPage);\n        var number = int.Parse(match.Groups[1].Value.Replace(\",\", \"\"));\n        number = number / 100 * 100;\n        return number;\n    }\n\n}"
  },
  {
    "path": "build/BenchmarkDotNet.Build/Meta/VersionHistory.cs",
    "content": "using System.Linq;\nusing Cake.Core.IO;\nusing Cake.FileHelpers;\n\nnamespace BenchmarkDotNet.Build.Meta;\n\npublic class VersionHistory\n{\n    public string FirstCommit { get; }\n    public string[] StableVersions { get; }\n    public string CurrentVersion { get; }\n    \n    public VersionHistory(BuildContext context, FilePath versionFilePath)\n    {\n        var lines = context.FileReadLines(versionFilePath).Where(line => !string.IsNullOrWhiteSpace(line)).ToArray();\n        FirstCommit = lines.First();\n        CurrentVersion = lines.Last();\n        StableVersions = lines.Skip(1).SkipLast(1).ToArray();\n    }\n}"
  },
  {
    "path": "build/BenchmarkDotNet.Build/Options/BoolOption.cs",
    "content": "using System;\n\nnamespace BenchmarkDotNet.Build.Options;\n\npublic class BoolOption : Option<bool>\n{\n    public BoolOption(string commandLineName) : base(commandLineName)\n    {\n    }\n\n    public override bool Resolve(BuildContext context)\n    {\n        if (!HasArgument(context))\n            return false;\n        var value = GetArgument(context);\n        if (value == null)\n            return true;\n        return !value.Equals(false.ToString(), StringComparison.OrdinalIgnoreCase);\n    }\n\n    public void AssertTrue(BuildContext context)\n    {\n        var value = Resolve(context);\n        if (!value)\n            throw new Exception($\"{CommandLineName} is not specified\");\n    }\n}"
  },
  {
    "path": "build/BenchmarkDotNet.Build/Options/IOption.cs",
    "content": "namespace BenchmarkDotNet.Build.Options;\n\npublic interface IOption\n{\n    string CommandLineName { get; }\n    string Description { get; }\n    string[] Aliases { get; }\n}"
  },
  {
    "path": "build/BenchmarkDotNet.Build/Options/KnownOptions.cs",
    "content": "namespace BenchmarkDotNet.Build.Options;\n\npublic static class KnownOptions\n{\n    public static readonly StringOption Verbosity = new(\"--verbosity\"\n    )\n    {\n        Description = \"Specifies the amount of information to be displayed\\n\" +\n                      \"(Quiet, Minimal, Normal, Verbose, Diagnostic)\",\n        Aliases = new[] { \"-v\" }\n    };\n\n    public static readonly BoolOption Exclusive = new(\"--exclusive\")\n    {\n        Description = \"Executes the target task without any dependencies\",\n        Aliases = new[] { \"-e\" }\n    };\n\n    public static readonly BoolOption DocsPreview = new(\"--preview\")\n    {\n        Description = \"When specified, documentation changelog includes the upcoming version\",\n        Aliases = new[] { \"-p\" }\n    };\n\n    public static readonly StringOption DocsDepth = new(\"--depth\")\n    {\n        Description = \"The number of last stable versions that requires changelog regenerations\\n\" +\n                      \"Use 'all' for all values. The default is zero.\",\n        Aliases = new[] { \"-d\" }\n    };\n\n    public static readonly BoolOption ForceClone = new(\"--force-clone\")\n    {\n        Description = \"Forces re-cloning of the changelog repository, deleting any existing directory.\",\n        Aliases = new[] { \"-f\" }\n    };\n\n    public static readonly BoolOption Help = new(\"--help\")\n    {\n        Description = \"Prints help information\",\n        Aliases = new[] { \"-h\" }\n    };\n\n    public static readonly BoolOption Stable = new(\"--stable\")\n    {\n        Description = \"Removes VersionSuffix in MSBuild settings\",\n        Aliases = new[] { \"-s\" }\n    };\n\n    public static readonly StringOption NextVersion = new(\"--next-version\")\n    {\n        Description = \"Specifies next version number\",\n        Aliases = new[] { \"-n\" }\n    };\n    \n    public static readonly BoolOption Push = new(\"--push\")\n    {\n        Description = \"When specified, the task actually perform push to GitHub and nuget.org\"\n    };\n}"
  },
  {
    "path": "build/BenchmarkDotNet.Build/Options/Option.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing Cake.Common;\nusing Cake.Core;\n\nnamespace BenchmarkDotNet.Build.Options;\n\npublic abstract class Option<T> : IOption\n{\n    public string CommandLineName { get; }\n    public string Description { get; init; } = \"\";\n    public string[] Aliases { get; init; } = Array.Empty<string>();\n\n    private IEnumerable<string> AllNames\n    {\n        get\n        {\n            yield return CommandLineName;\n            foreach (var alias in Aliases)\n                yield return alias;\n        }\n    }\n\n    private IEnumerable<string> AllStrippedNames => AllNames.Select(name => name.TrimStart('-'));\n\n    protected Option(string commandLineName)\n    {\n        CommandLineName = commandLineName;\n    }\n\n    public abstract T Resolve(BuildContext context);\n\n    protected bool HasArgument(BuildContext context) => AllStrippedNames.Any(context.HasArgument);\n\n    protected string? GetArgument(BuildContext context) => AllStrippedNames\n        .Where(context.HasArgument)\n        .Select(name => context.Arguments.GetArgument(name))\n        .FirstOrDefault();\n}"
  },
  {
    "path": "build/BenchmarkDotNet.Build/Options/StringOption.cs",
    "content": "using System;\n\nnamespace BenchmarkDotNet.Build.Options;\n\npublic class StringOption : Option<string>\n{\n    public StringOption(string commandLineName) : base(commandLineName)\n    {\n    }\n\n\n    public override string Resolve(BuildContext context)\n    {\n        if (!HasArgument(context))\n            return \"\";\n        var value = GetArgument(context);\n        if (value == null || string.IsNullOrWhiteSpace(value))\n            return \"\";\n        return value.Trim();\n    }\n\n    public string AssertHasValue(BuildContext context)\n    {\n        var value = Resolve(context);\n        if (string.IsNullOrWhiteSpace(value))\n            throw new Exception($\"{CommandLineName} is not specified\");\n        return value;\n    }\n}"
  },
  {
    "path": "build/BenchmarkDotNet.Build/Program.cs",
    "content": "using BenchmarkDotNet.Build.Meta;\nusing BenchmarkDotNet.Build.Options;\nusing Cake.Common;\nusing Cake.Frosting;\n\nnamespace BenchmarkDotNet.Build;\n\npublic static class Program\n{\n    public static int Main(string[] args)\n    {\n        var cakeArgs = CommandLineParser.Instance.Parse(args);\n        return cakeArgs == null\n            ? 0\n            : new CakeHost().UseContext<BuildContext>().Run(cakeArgs);\n    }\n}\n\n[TaskName(Name)]\n[TaskDescription(\"Pack Weaver\")]\npublic class PackWeaverTask : FrostingTask<BuildContext>, IHelpProvider\n{\n    private const string Name = \"pack-weaver\";\n\n    public override void Run(BuildContext context) => context.BuildRunner.PackWeaver();\n\n    public HelpInfo GetHelp()\n    {\n        return new HelpInfo\n        {\n            Examples = new[]\n            {\n                new Example(Name)\n            }\n        };\n    }\n}\n\n[TaskName(Name)]\n[TaskDescription(\"Restore NuGet packages\")]\n[IsDependentOn(typeof(PackWeaverTask))]\npublic class RestoreTask : FrostingTask<BuildContext>, IHelpProvider\n{\n    private const string Name = \"restore\";\n\n    public override void Run(BuildContext context) => context.BuildRunner.Restore();\n\n    public HelpInfo GetHelp()\n    {\n        return new HelpInfo\n        {\n            Examples =\n            [\n                new Example(Name)\n            ]\n        };\n    }\n}\n\n[TaskName(Name)]\n[TaskDescription(\"Build BenchmarkDotNet.slnx solution\")]\n[IsDependentOn(typeof(RestoreTask))]\npublic class BuildTask : FrostingTask<BuildContext>, IHelpProvider\n{\n    private const string Name = \"build\";\n    public override void Run(BuildContext context) => context.BuildRunner.Build();\n\n    public HelpInfo GetHelp()\n    {\n        return new HelpInfo\n        {\n            Examples =\n            [\n                new Example(Name).WithMsBuildArgument(\"Configuration\", \"Debug\")\n            ]\n        };\n    }\n}\n\n[TaskName(Name)]\n[TaskDescription(\"Install wasm-tools workload\")]\npublic class InstallWasmToolsWorkload : FrostingTask<BuildContext>, IHelpProvider\n{\n    private const string Name = \"install-wasm-tools\";\n\n    public override void Run(BuildContext context)\n    {\n        context.BuildRunner.InstallWorkload(\"wasm-tools-net8\");\n        context.BuildRunner.InstallWorkload(\"wasm-tools\");\n    }\n\n    public HelpInfo GetHelp()\n    {\n        return new HelpInfo\n        {\n            Examples =\n            [\n                new Example(Name)\n            ]\n        };\n    }\n}\n\n[TaskName(Name)]\n[TaskDescription(\"Run unit tests (fast)\")]\n[IsDependentOn(typeof(BuildTask))]\npublic class UnitTestsTask : FrostingTask<BuildContext>, IHelpProvider\n{\n    private const string Name = \"unit-tests\";\n    public override void Run(BuildContext context) => context.UnitTestRunner.RunUnitTests();\n\n    public HelpInfo GetHelp()\n    {\n        return new HelpInfo\n        {\n            Examples =\n            [\n                new Example(Name)\n                    .WithArgument(KnownOptions.Exclusive)\n                    .WithArgument(KnownOptions.Verbosity, \"Diagnostic\")\n            ]\n        };\n    }\n}\n\n[TaskName(Name)]\n[TaskDescription(\"Run analyzer tests\")]\n[IsDependentOn(typeof(BuildTask))]\npublic class AnalyzerTestsTask : FrostingTask<BuildContext>, IHelpProvider\n{\n    private const string Name = \"analyzer-tests\";\n    public override void Run(BuildContext context) => context.UnitTestRunner.RunAnalyzerTests();\n\n    public HelpInfo GetHelp()\n    {\n        return new HelpInfo\n        {\n            Examples =\n            [\n                new Example(Name)\n                    .WithArgument(KnownOptions.Exclusive)\n                    .WithArgument(KnownOptions.Verbosity, \"Diagnostic\")\n            ]\n        };\n    }\n}\n\n[TaskName(Name)]\n[TaskDescription(\"Run integration tests using .NET Framework 4.6.2+ (slow)\")]\n[IsDependentOn(typeof(BuildTask))]\npublic class InTestsFullTask : FrostingTask<BuildContext>, IHelpProvider\n{\n    private const string Name = \"in-tests-full\";\n\n    public override bool ShouldRun(BuildContext context) => context.IsRunningOnWindows();\n\n    public override void Run(BuildContext context) => context.UnitTestRunner.RunInTests(\"net462\");\n\n    public HelpInfo GetHelp() => new();\n}\n\n[TaskName(Name)]\n[TaskDescription(\"Run integration tests using .NET 8 (slow)\")]\n[IsDependentOn(typeof(BuildTask))]\npublic class InTestsCoreTask : FrostingTask<BuildContext>, IHelpProvider\n{\n    private const string Name = \"in-tests-core\";\n    public override void Run(BuildContext context) => context.UnitTestRunner.RunInTests(\"net8.0\");\n    public HelpInfo GetHelp() => new();\n}\n\n[TaskName(Name)]\n[TaskDescription(\"Run all unit, analyzer, and integration tests (slow)\")]\n[IsDependentOn(typeof(UnitTestsTask))]\n[IsDependentOn(typeof(AnalyzerTestsTask))]\n[IsDependentOn(typeof(InTestsFullTask))]\n[IsDependentOn(typeof(InTestsCoreTask))]\npublic class AllTestsTask : FrostingTask<BuildContext>, IHelpProvider\n{\n    private const string Name = \"all-tests\";\n    public HelpInfo GetHelp() => new();\n}\n\n[TaskName(Name)]\n[TaskDescription(\"Build BenchmarkDotNet.Analyzers\")]\npublic class BuildAnalyzersTask : FrostingTask<BuildContext>, IHelpProvider\n{\n    private const string Name = \"build-analyzers\";\n    public override void Run(BuildContext context) => context.BuildRunner.BuildAnalyzers();\n\n    public HelpInfo GetHelp()\n    {\n        return new HelpInfo\n        {\n            Examples =\n            [\n                new Example(Name)\n            ]\n        };\n    }\n}\n\n[TaskName(Name)]\n[TaskDescription(\"Move updated analyzer rules from unshipped to shipped file\")]\npublic class MoveAnalyzerRulesTask : FrostingTask<BuildContext>, IHelpProvider\n{\n    private const string Name = \"move-analyzer-rules\";\n    public override void Run(BuildContext context) => context.DocumentationRunner.MoveAnalyzerRules();\n\n    public HelpInfo GetHelp()\n    {\n        return new HelpInfo\n        {\n            Examples =\n            [\n                new Example(Name)\n            ]\n        };\n    }\n}\n\n[TaskName(Name)]\n[TaskDescription(\"Pack Nupkg packages\")]\n[IsDependentOn(typeof(BuildTask))]\n[IsDependentOn(typeof(BuildAnalyzersTask))]\npublic class PackTask : FrostingTask<BuildContext>, IHelpProvider\n{\n    public const string Name = \"pack\";\n    public override void Run(BuildContext context) => context.BuildRunner.Pack();\n\n    public HelpInfo GetHelp()\n    {\n        return new HelpInfo\n        {\n            Examples =\n            [\n                new Example(Name)\n                    .WithMsBuildArgument(\"VersionPrefix\", \"0.1.1729\")\n                    .WithMsBuildArgument(\"VersionSuffix\", \"preview\"),\n                new Example(Name).WithArgument(KnownOptions.Stable)\n            ]\n        };\n    }\n}\n\n[TaskName(Name)]\n[TaskDescription(\"Fetch changelog files\")]\npublic class DocsFetchTask : FrostingTask<BuildContext>, IHelpProvider\n{\n    private const string Name = \"docs-fetch\";\n    public override void Run(BuildContext context) => context.DocumentationRunner.Fetch();\n\n    public HelpInfo GetHelp()\n    {\n        return new HelpInfo\n        {\n            Description = $\"This task updates the following files:\\n\" +\n                          $\"* Clones or fetches branch 'docs-changelog' to docs/_changelog\\n\" +\n                          $\"* Last changelog footer (if {KnownOptions.Stable.CommandLineName} is specified)\\n\" +\n                          $\"* All changelog details in docs/_changelog\\n\" +\n                          $\"  (This dir is a cloned version of this repo from branch {Repo.ChangelogBranch})\",\n            Options = [KnownOptions.DocsPreview, KnownOptions.DocsDepth, KnownOptions.ForceClone],\n            EnvironmentVariables = [EnvVar.GitHubToken],\n            Examples =\n            [\n                new Example(Name)\n                    .WithArgument(KnownOptions.DocsDepth, \"3\")\n                    .WithArgument(KnownOptions.DocsPreview)\n                    .WithArgument(KnownOptions.ForceClone)\n            ]\n        };\n    }\n}\n\n[TaskName(Name)]\n[TaskDescription(\"Generate auxiliary documentation files\")]\npublic class DocsGenerateTask : FrostingTask<BuildContext>, IHelpProvider\n{\n    private const string Name = \"docs-generate\";\n    public override void Run(BuildContext context) => context.DocumentationRunner.Generate();\n\n    public HelpInfo GetHelp()\n    {\n        return new HelpInfo\n        {\n            Options = [KnownOptions.DocsPreview, KnownOptions.Stable],\n            Examples =\n            [\n                new Example(Name).WithArgument(KnownOptions.DocsPreview),\n                new Example(Name).WithArgument(KnownOptions.Stable)\n            ]\n        };\n    }\n}\n\n[TaskName(Name)]\n[TaskDescription(\"Build final documentation\")]\n[IsDependentOn(typeof(DocsGenerateTask))]\npublic class DocsBuildTask : FrostingTask<BuildContext>, IHelpProvider\n{\n    private const string Name = \"docs-build\";\n    public override void Run(BuildContext context) => context.DocumentationRunner.Build();\n\n    public HelpInfo GetHelp() => new()\n    {\n        Description = \"The 'build' task should be run manually to build api docs\",\n        Options = [KnownOptions.DocsPreview],\n        Examples =\n        [\n            new Example(Name).WithArgument(KnownOptions.DocsPreview)\n        ]\n    };\n}\n\n[TaskName(Name)]\n[TaskDescription(\"Increments the current version\")]\npublic class VersionIncrementTask : FrostingTask<BuildContext>, IHelpProvider\n{\n    private const string Name = \"version-increment\";\n    public override void Run(BuildContext context)\n    {\n        context.ReleaseRunner.VersionIncrement();\n        context.BuildRunner.PackWeaver();\n    }\n\n    public HelpInfo GetHelp() => new()\n    {\n        Options = [KnownOptions.NextVersion],\n        Examples =\n        [\n            new Example(Name),\n            new Example(Name)\n                .WithArgument(KnownOptions.NextVersion, \"0.1.1729\")\n        ]\n    };\n}\n\n[TaskName(Name)]\n[TaskDescription(\"Release new version\")]\n[IsDependentOn(typeof(BuildTask))]\n[IsDependentOn(typeof(PackTask))]\n[IsDependentOn(typeof(DocsFetchTask))]\n[IsDependentOn(typeof(DocsGenerateTask))]\n[IsDependentOn(typeof(DocsBuildTask))]\npublic class ReleaseTask : FrostingTask<BuildContext>, IHelpProvider\n{\n    public const string Name = \"release\";\n    public override void Run(BuildContext context) => context.ReleaseRunner.Run();\n\n    public HelpInfo GetHelp() => new()\n    {\n        Options = [KnownOptions.NextVersion, KnownOptions.Push],\n        EnvironmentVariables = [EnvVar.GitHubToken, EnvVar.NuGetToken],\n        Examples =\n        [\n            new Example(Name)\n                .WithArgument(KnownOptions.Stable)\n                .WithArgument(KnownOptions.NextVersion, \"0.1.1729\")\n                .WithArgument(KnownOptions.Push),\n            new Example(Name)\n                .WithArgument(KnownOptions.Stable)\n                .WithArgument(KnownOptions.Push)\n        ]\n    };\n}"
  },
  {
    "path": "build/BenchmarkDotNet.Build/Runners/BuildRunner.cs",
    "content": "using Cake.Common.Build;\nusing Cake.Common.Diagnostics;\nusing Cake.Common.IO;\nusing Cake.Common.Tools.DotNet;\nusing Cake.Common.Tools.DotNet.Build;\nusing Cake.Common.Tools.DotNet.Pack;\nusing Cake.Common.Tools.DotNet.Restore;\nusing Cake.Common.Tools.DotNet.Workload.Install;\nusing Cake.Core;\nusing Cake.Core.IO;\nusing System;\nusing System.IO;\nusing System.Linq;\n\nnamespace BenchmarkDotNet.Build.Runners;\n\npublic class BuildRunner\n{\n    private readonly BuildContext context;\n    private readonly bool isFullPack;\n\n    public BuildRunner(BuildContext context)\n    {\n        this.context = context;\n        isFullPack = context.Arguments.GetArgument(\"target\") is PackTask.Name or ReleaseTask.Name;\n    }\n\n    private void MaybeAppendArgument(DotNetSettings settings)\n    {\n        if (isFullPack)\n        {\n            settings.ArgumentCustomization = args => args.Append(\"-p:IsFullPack=true\");\n        }\n    }\n\n    public void PackWeaver()\n    {\n        var weaverPath = context.AllPackableSrcProjects.Single(p => p.GetFilename() == \"BenchmarkDotNet.Weaver.csproj\");\n        var outputPackageDir = weaverPath.GetDirectory().Combine(\"packages\");\n\n        if (!isFullPack)\n        {\n            // Delete old package.\n            foreach (var file in Directory.EnumerateFiles(outputPackageDir.FullPath))\n            {\n                File.Delete(file);\n            }\n        }\n\n        var restoreSettings = new DotNetRestoreSettings\n        {\n            MSBuildSettings = context.MsBuildSettingsRestore,\n        };\n        MaybeAppendArgument(restoreSettings);\n        context.DotNetRestore(weaverPath.GetDirectory().FullPath, restoreSettings);\n\n        context.Information(\"BuildSystemProvider: \" + context.BuildSystem().Provider);\n        var buildSettings = new DotNetBuildSettings\n        {\n            NoRestore = true,\n            DiagnosticOutput = true,\n            MSBuildSettings = context.MsBuildSettingsBuild,\n            Configuration = context.BuildConfiguration,\n            Verbosity = context.BuildVerbosity\n        };\n        MaybeAppendArgument(buildSettings);\n        context.DotNetBuild(weaverPath.FullPath, buildSettings);\n\n        var packSettings = new DotNetPackSettings\n        {\n            OutputDirectory = outputPackageDir,\n            MSBuildSettings = context.MsBuildSettingsPack,\n            Configuration = context.BuildConfiguration\n        };\n        MaybeAppendArgument(packSettings);\n        context.DotNetPack(weaverPath.FullPath, packSettings);\n    }\n\n    public void Restore()\n    {\n        var restoreSettings = new DotNetRestoreSettings\n        {\n            MSBuildSettings = context.MsBuildSettingsRestore,\n        };\n        MaybeAppendArgument(restoreSettings);\n        context.DotNetRestore(context.SolutionFile.FullPath, restoreSettings);\n    }\n\n    public void InstallWorkload(string workloadId)\n    {\n        context.DotNetWorkloadInstall(workloadId,\n            new DotNetWorkloadInstallSettings\n            {\n                IncludePreviews = true,\n                NoCache = true\n            });\n    }\n\n    public void Build()\n    {\n        context.Information(\"BuildSystemProvider: \" + context.BuildSystem().Provider);\n        var buildSettings = new DotNetBuildSettings\n        {\n            NoRestore = true,\n            DiagnosticOutput = true,\n            MSBuildSettings = context.MsBuildSettingsBuild,\n            Configuration = context.BuildConfiguration,\n            Verbosity = context.BuildVerbosity\n        };\n        MaybeAppendArgument(buildSettings);\n        context.DotNetBuild(context.SolutionFile.FullPath, buildSettings);\n    }\n\n    public void BuildProjectSilent(FilePath projectFile)\n    {\n        var buildSettings = new DotNetBuildSettings\n        {\n            NoRestore = false,\n            DiagnosticOutput = false,\n            MSBuildSettings = context.MsBuildSettingsBuild,\n            Configuration = context.BuildConfiguration,\n            Verbosity = DotNetVerbosity.Quiet\n        };\n        MaybeAppendArgument(buildSettings);\n        context.DotNetBuild(projectFile.FullPath, buildSettings);\n    }\n\n    public void BuildAnalyzers()\n    {\n        context.Information(\"BuildSystemProvider: \" + context.BuildSystem().Provider);\n        string[] mccVersions = [\"2.8\", \"3.8\", \"4.8\"];\n        foreach (string version in mccVersions)\n        {\n            context.DotNetBuild(context.AnalyzersProjectFile.FullPath, new DotNetBuildSettings\n            {\n                NoRestore = true,\n                DiagnosticOutput = true,\n                MSBuildSettings = context.MsBuildSettingsBuild,\n                Configuration = context.BuildConfiguration,\n                Verbosity = context.BuildVerbosity,\n                ArgumentCustomization = args => args.Append($\"-p:MccVersion={version}\")\n            });\n        }\n    }\n\n    public void Pack()\n    {\n        context.CleanDirectory(context.ArtifactsDirectory);\n\n        var settingsSrc = new DotNetPackSettings\n        {\n            OutputDirectory = context.ArtifactsDirectory,\n            ArgumentCustomization = args => args.Append(\"--include-symbols\").Append(\"-p:SymbolPackageFormat=snupkg\").Append(\"-p:IsFullPack=true\"),\n            MSBuildSettings = context.MsBuildSettingsPack,\n            Configuration = context.BuildConfiguration\n        };\n\n        foreach (var project in context.AllPackableSrcProjects)\n            context.DotNetPack(project.FullPath, settingsSrc);\n\n        var settingsTemplate = new DotNetPackSettings\n        {\n            OutputDirectory = context.ArtifactsDirectory,\n            MSBuildSettings = context.MsBuildSettingsPack,\n            Configuration = context.BuildConfiguration\n        };\n        context.DotNetPack(context.TemplatesTestsProjectFile.FullPath, settingsTemplate);\n    }\n}"
  },
  {
    "path": "build/BenchmarkDotNet.Build/Runners/Changelog/ChangelogBuilder.cs",
    "content": "using System;\nusing System.Globalization;\nusing System.IO;\nusing System.Linq;\nusing System.Text;\nusing BenchmarkDotNet.Build.Meta;\nusing BenchmarkDotNet.Build.Options;\nusing Cake.Common.Diagnostics;\nusing Cake.Common.IO;\nusing Cake.Core.IO;\nusing Cake.FileHelpers;\n\nnamespace BenchmarkDotNet.Build.Runners.Changelog;\n\npublic class ChangelogBuilder\n{\n    private readonly BuildContext context;\n    private readonly bool preview;\n    private readonly string depth;\n    private readonly bool forceClone;\n\n    /// <summary>\n    /// Directory with original changelog part files from branch 'docs-changelog'\n    /// </summary>\n    public DirectoryPath SrcDirectory { get; }\n\n    /// <summary>\n    /// Final changelog files to be used by docfx\n    /// </summary>\n    public DirectoryPath DocfxDirectory { get; }\n\n    public ChangelogBuilder(BuildContext context)\n    {\n        this.context = context;\n        preview = KnownOptions.DocsPreview.Resolve(context);\n        depth = KnownOptions.DocsDepth.Resolve(context);\n        forceClone = KnownOptions.ForceClone.Resolve(context);\n\n        var docsDirectory = context.RootDirectory.Combine(\"docs\");\n        SrcDirectory = docsDirectory.Combine(\"_changelog\");\n        DocfxDirectory = docsDirectory.Combine(\"changelog\");\n    }\n\n    public void Fetch()\n    {\n        EnvVar.GitHubToken.AssertHasValue();\n\n        EnsureSrcDirectoryExist(forceClone);\n\n        var history = context.VersionHistory;\n        var stableVersionCount = history.StableVersions.Length;\n\n        if (depth.Equals(\"all\", StringComparison.OrdinalIgnoreCase))\n        {\n            FetchDetails(\n                history.StableVersions.First(),\n                history.FirstCommit);\n\n            for (var i = 1; i < stableVersionCount; i++)\n                FetchDetails(\n                    history.StableVersions[i],\n                    history.StableVersions[i - 1]);\n        }\n        else if (depth != \"\")\n        {\n            if (!int.TryParse(depth, CultureInfo.InvariantCulture, out var depthValue))\n                throw new InvalidDataException($\"Failed to parse the depth value: '{depth}'\");\n\n            for (var i = Math.Max(stableVersionCount - depthValue, 1); i < stableVersionCount; i++)\n                FetchDetails(\n                    history.StableVersions[i],\n                    history.StableVersions[i - 1]);\n        }\n\n        if (preview)\n            FetchDetails(\n                history.CurrentVersion,\n                history.StableVersions.Last(),\n                \"HEAD\");\n        \n        context.GitRunner.AddAll(SrcDirectory);\n        context.GitRunner.Commit(\"Update changelog\", SrcDirectory);\n    }\n\n    private void FetchDetails(string version, string versionPrevious, string lastCommit = \"\")\n    {\n        EnsureSrcDirectoryExist();\n        context.Information($\"Downloading changelog details for v{version}\");\n        var detailsDirectory = SrcDirectory.Combine(\"details\");\n        ChangelogDetailsBuilder.Run(context, detailsDirectory, version, versionPrevious, lastCommit);\n    }\n\n    public void Generate()\n    {\n        GenerateLastHeader();\n        GenerateLastFooter();\n\n        foreach (var version in context.VersionHistory.StableVersions)\n            GenerateVersion(version);\n        if (preview)\n            GenerateVersion(context.VersionHistory.CurrentVersion);\n\n        GenerateIndex();\n        GenerateFull();\n        GenerateToc();\n    }\n\n    public void GenerateLastHeader()\n    {\n        var fileName = \"v\" + context.VersionHistory.CurrentVersion + \".md\";\n        var filePath = SrcDirectory.Combine(\"header\").CombineWithFilePath(fileName);\n        if (!context.FileExists(filePath))\n        {\n            var relativePath = context.RootDirectory.GetRelativePath(filePath);\n            context.FileWriteText(filePath, \"\");\n            context.Information(\"[Created] \" + relativePath);\n        }\n    }\n\n    public void GenerateLastFooter()\n    {\n        var version = context.VersionHistory.CurrentVersion;\n        var previousVersion = context.VersionHistory.StableVersions.Last();\n        var date = KnownOptions.Stable.Resolve(context)\n            ? DateTime.Now.ToString(\"MMMM dd, yyyy\", CultureInfo.InvariantCulture)\n            : \"TBA\";\n\n        var content = new StringBuilder();\n        content.AppendLine($\"_Date: {date}_\");\n        content.AppendLine(\"\");\n        content.AppendLine(\n            $\"_Milestone: [v{version}](https://github.com/dotnet/BenchmarkDotNet/issues?q=milestone%3Av{version})_\");\n        content.AppendLine(\n            $\"([List of commits](https://github.com/dotnet/BenchmarkDotNet/compare/v{previousVersion}...v{version}))\");\n        content.AppendLine(\"\");\n        content.AppendLine(\"_NuGet Packages:_\");\n        foreach (var packageName in context.NuGetPackageNames)\n            content.AppendLine($\"* https://www.nuget.org/packages/{packageName}/{version}\");\n\n        var fileName = \"v\" + context.VersionHistory.CurrentVersion + \".md\";\n        var filePath = SrcDirectory.Combine(\"footer\").CombineWithFilePath(fileName);\n        context.GenerateFile(filePath, content);\n    }\n\n    private void GenerateVersion(string version)\n    {\n        EnsureSrcDirectoryExist();\n        var md = $\"v{version}.md\";\n        var header = SrcDirectory.Combine(\"header\").CombineWithFilePath(md);\n        var footer = SrcDirectory.Combine(\"footer\").CombineWithFilePath(md);\n        var details = SrcDirectory.Combine(\"details\").CombineWithFilePath(md);\n        var release = DocfxDirectory.CombineWithFilePath(md);\n\n        var content = new StringBuilder();\n        content.AppendLine(\"---\");\n        content.AppendLine(\"uid: changelog.v\" + version);\n        content.AppendLine(\"---\");\n        content.AppendLine(\"\");\n        content.AppendLine(\"# BenchmarkDotNet v\" + version);\n        content.AppendLine(\"\");\n        content.AppendLine(\"\");\n\n        if (context.FileExists(header))\n        {\n            content.AppendLine(context.FileReadText(header));\n            content.AppendLine(\"\");\n            content.AppendLine(\"\");\n        }\n\n        if (context.FileExists(details))\n        {\n            content.AppendLine(context.FileReadText(details));\n            content.AppendLine(\"\");\n            content.AppendLine(\"\");\n        }\n\n        if (context.FileExists(footer))\n        {\n            content.AppendLine(\"## Additional details\");\n            content.AppendLine(\"\");\n            content.AppendLine(context.FileReadText(footer));\n        }\n\n        context.GenerateFile(release, content.ToString());\n    }\n\n    private void GenerateIndex()\n    {\n        var content = new StringBuilder();\n        content.AppendLine(\"---\");\n        content.AppendLine(\"uid: changelog\");\n        content.AppendLine(\"---\");\n        content.AppendLine(\"\");\n        content.AppendLine(\"# ChangeLog\");\n        content.AppendLine(\"\");\n        if (preview)\n            content.AppendLine($\"* @changelog.v{context.VersionHistory.CurrentVersion}\");\n        foreach (var version in context.VersionHistory.StableVersions.Reverse())\n            content.AppendLine($\"* @changelog.v{version}\");\n        content.AppendLine(\"* @changelog.full\");\n\n        context.GenerateFile(DocfxDirectory.CombineWithFilePath(\"index.md\"), content);\n    }\n\n    private void GenerateFull()\n    {\n        var content = new StringBuilder();\n        content.AppendLine(\"---\");\n        content.AppendLine(\"uid: changelog.full\");\n        content.AppendLine(\"---\");\n        content.AppendLine(\"\");\n        content.AppendLine(\"# Full ChangeLog\");\n        content.AppendLine(\"\");\n        if (preview)\n            content.AppendLine(\n                $\"[!include[v{context.VersionHistory.CurrentVersion}](v{context.VersionHistory.CurrentVersion}.md)]\");\n        foreach (var version in context.VersionHistory.StableVersions.Reverse())\n            content.AppendLine($\"[!include[v{version}](v{version}.md)]\");\n\n        context.GenerateFile(DocfxDirectory.CombineWithFilePath(\"full.md\"), content);\n    }\n\n    private void GenerateToc()\n    {\n        var content = new StringBuilder();\n\n        if (preview)\n        {\n            content.AppendLine($\"- name: v{context.VersionHistory.CurrentVersion}\");\n            content.AppendLine($\"  href: v{context.VersionHistory.CurrentVersion}.md\");\n        }\n\n        foreach (var version in context.VersionHistory.StableVersions.Reverse())\n        {\n            content.AppendLine($\"- name: v{version}\");\n            content.AppendLine($\"  href: v{version}.md\");\n        }\n\n        content.AppendLine(\"- name: Full ChangeLog\");\n        content.AppendLine(\"  href: full.md\");\n\n        context.GenerateFile(DocfxDirectory.CombineWithFilePath(\"toc.yml\"), content);\n    }\n\n    private void EnsureSrcDirectoryExist(bool forceClone = false)\n    {\n        void Log(string message) => context.Information($\"[Changelog] {message}\");\n\n        if (context.DirectoryExists(SrcDirectory) && forceClone)\n        {\n            Log($\"Directory '{SrcDirectory}' already exists and forceClean is specified. \" +\n                $\"Deleting the current directory...\");\n            context.DeleteDirectory(\n                SrcDirectory,\n                new DeleteDirectorySettings { Force = true, Recursive = true });\n            Log($\"Directory '{SrcDirectory}' deleted successfully.\");\n        }\n\n        if (!context.DirectoryExists(SrcDirectory))\n        {\n            Log($\"Cloning branch '{Repo.ChangelogBranch}' from '{Repo.SshGitUrl}' to '{SrcDirectory}'.\");\n            context.GitRunner.Clone(SrcDirectory, Repo.SshGitUrl, Repo.ChangelogBranch);\n            Log($\"Clone completed: '{Repo.ChangelogBranch}' -> '{SrcDirectory}'.\");\n        }\n        else if (forceClone)\n        {\n            Log($\"Fetching branch '{Repo.ChangelogBranch}' from '{Repo.SshGitUrl}' to '{SrcDirectory}'.\");\n            context.GitRunner.Pull(SrcDirectory);\n            Log($\"Fetch completed: '{Repo.ChangelogBranch}' -> '{SrcDirectory}'.\");\n        }\n    }\n}"
  },
  {
    "path": "build/BenchmarkDotNet.Build/Runners/Changelog/ChangelogDetailsBuilder.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Collections.Immutable;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing BenchmarkDotNet.Build.Helpers;\nusing BenchmarkDotNet.Build.Meta;\nusing Cake.Common.Diagnostics;\nusing Cake.Core.IO;\nusing Octokit;\n\nnamespace BenchmarkDotNet.Build.Runners.Changelog;\n\npublic static class ChangelogDetailsBuilder\n{\n    private class Config(string currentVersion, string previousVersion, string lastCommit)\n    {\n        public string CurrentVersion { get; } = currentVersion;\n        public string PreviousVersion { get; } = previousVersion;\n        public string LastCommit { get; } = lastCommit;\n\n        public void Deconstruct(out string currentMilestone, out string previousMilestone, out string lastCommit)\n        {\n            currentMilestone = CurrentVersion;\n            previousMilestone = PreviousVersion;\n            lastCommit = LastCommit;\n        }\n    }\n\n    private class MarkdownBuilder\n    {\n        private static IReadOnlyList<Milestone>? allMilestones;\n        private static readonly Dictionary<string, string> AuthorNames = new();\n\n        private readonly Config config;\n        private readonly StringBuilder builder;\n\n        public static async Task<string> Build(Config config)\n        {\n            return await new MarkdownBuilder(config).Build();\n        }\n\n        private MarkdownBuilder(Config config)\n        {\n            this.config = config;\n            builder = new StringBuilder();\n        }\n\n        private async Task<string> Build()\n        {\n            var (currentVersion, previousVersion, lastCommit) = config;\n            if (string.IsNullOrEmpty(lastCommit))\n                lastCommit = $\"v{currentVersion}\";\n\n            var client = Utils.CreateGitHubClient();\n\n            if (currentVersion == \"_\")\n            {\n                var allContributors = await client.Repository.GetAllContributors(Repo.Owner, Repo.Name);\n                builder.AppendLine(\"# All contributors\");\n                builder.AppendLine();\n                foreach (var contributor in allContributors)\n                {\n                    var user = await client.User.Get(contributor.Login);\n                    var name = user?.Name;\n                    builder.AppendLine(\"* \" + (string.IsNullOrEmpty(name)\n                        ? contributor.ToLink()\n                        : contributor.ToLinkWithName(name)));\n                }\n\n                return builder.ToString();\n            }\n\n            if (allMilestones == null)\n            {\n                var milestoneRequest = new MilestoneRequest\n                {\n                    State = ItemStateFilter.All\n                };\n                allMilestones =\n                    await client.Issue.Milestone.GetAllForRepository(Repo.Owner, Repo.Name, milestoneRequest);\n            }\n\n            IReadOnlyList<Issue> allIssues = Array.Empty<Issue>();\n            var targetMilestone = allMilestones.FirstOrDefault(m => m.Title == $\"v{currentVersion}\");\n            if (targetMilestone != null)\n            {\n                var issueRequest = new RepositoryIssueRequest\n                {\n                    State = ItemStateFilter.Closed,\n                    Milestone = targetMilestone.Number.ToString()\n                };\n\n                allIssues = await client.Issue.GetAllForRepository(Repo.Owner, Repo.Name, issueRequest);\n            }\n\n            var issues = allIssues\n                .Where(issue => issue.PullRequest == null)\n                .OrderBy(issue => issue.Number)\n                .ToList();\n            var pullRequests = allIssues\n                .Where(issue => issue.PullRequest != null)\n                .OrderBy(issue => issue.Number)\n                .ToList();\n\n            var compare =\n                await client.Repository.Commit.Compare(Repo.Owner, Repo.Name, $\"v{previousVersion}\", lastCommit);\n            var commits = compare.Commits;\n\n            foreach (var contributor in commits.Select(commit => commit.Author))\n                if (contributor != null && !AuthorNames.ContainsKey(contributor.Login))\n                {\n                    var user = await client.User.Get(contributor.Login);\n                    var name = user?.Name;\n                    AuthorNames[contributor.Login] = string.IsNullOrWhiteSpace(name) ? contributor.Login : name;\n                }\n\n            string PresentContributor(GitHubCommit commit)\n            {\n                if (commit.Author != null)\n                    return $\"{AuthorNames[commit.Author.Login]} ({commit.Author.ToLink()})\".Trim();\n                return commit.Commit.Author.Name;\n            }\n\n            var contributors = compare.Commits\n                .Select(PresentContributor)\n                .OrderBy(it => it)\n                .Distinct()\n                .ToImmutableList();\n\n            var milestoneHtmlUlr = $\"https://github.com/{Repo.Owner}/{Repo.Name}/issues?q=milestone:v{currentVersion}\";\n\n            builder.AppendLine(\"## Milestone details\");\n            builder.AppendLine();\n            builder.AppendLine($\"In the [v{currentVersion}]({milestoneHtmlUlr}) scope, \");\n            builder.Append(issues.Count + \" issues were resolved and \");\n            builder.AppendLine(pullRequests.Count + \" pull requests were merged.\");\n            builder.AppendLine($\"This release includes {commits.Count} commits by {contributors.Count} contributors.\");\n            builder.AppendLine();\n\n            AppendList(\"Resolved issues\", issues, issue =>\n                $\"[#{issue.Number}]({issue.HtmlUrl}) {issue.Title.Trim()}{issue.Assignee.ToStr(\"assignee:\")}\");\n            AppendList(\"Merged pull requests\", pullRequests, pr =>\n                $\"[#{pr.Number}]({pr.HtmlUrl}) {pr.Title.Trim()}{pr.User.ToStr(\"by\")}\");\n            AppendList(\"Commits\", commits, commit =>\n                $\"{commit.ToLink()} {commit.Commit.ToCommitMessage()}{commit.ToByStr()}\");\n            AppendList(\"Contributors\", contributors, it => it, \"Thank you very much!\");\n\n            return builder.ToString();\n        }\n\n        private void AppendList<T>(string title, IReadOnlyList<T> items, Func<T, string> format,\n            string? conclusion = null)\n        {\n            builder.AppendLine($\"## {title} ({items.Count})\");\n            builder.AppendLine();\n            foreach (var item in items)\n                builder.AppendLine(\"* \" + format(item));\n            if (!string.IsNullOrWhiteSpace(conclusion))\n            {\n                builder.AppendLine();\n                builder.AppendLine(conclusion);\n            }\n\n            builder.AppendLine();\n        }\n    }\n\n    public static void Run(BuildContext context, DirectoryPath path,\n        string currentVersion, string previousVersion, string lastCommit)\n    {\n        try\n        {\n            var config = new Config(currentVersion, previousVersion, lastCommit);\n            var releaseNotes = MarkdownBuilder.Build(config).Result;\n            context.GenerateFile(path.Combine($\"v{config.CurrentVersion}.md\").FullPath, releaseNotes, true);\n        }\n        catch (Exception e)\n        {\n            context.Error(e.ToString());\n        }\n    }\n}"
  },
  {
    "path": "build/BenchmarkDotNet.Build/Runners/DocumentationRunner.cs",
    "content": "using System.IO;\nusing System.Linq;\nusing System.Text;\nusing BenchmarkDotNet.Build.Helpers;\nusing BenchmarkDotNet.Build.Meta;\nusing BenchmarkDotNet.Build.Options;\nusing BenchmarkDotNet.Build.Runners.Changelog;\nusing Cake.Common.Diagnostics;\nusing Cake.Common.IO;\nusing Cake.Core.IO;\nusing Cake.FileHelpers;\n\nnamespace BenchmarkDotNet.Build.Runners;\n\npublic class DocumentationRunner\n{\n    private readonly BuildContext context;\n    private readonly ChangelogBuilder changelogBuilder;\n    private readonly DirectoryPath docsGeneratedDirectory;\n\n    private readonly FilePath docfxJsonFile;\n    private readonly FilePath redirectFile;\n    private readonly FilePath readmeFile;\n    private readonly FilePath rootIndexFile;\n    private readonly FilePath analyzersShippedFile;\n    private readonly FilePath analyzersUnshippedFile;\n    private readonly FilePath analyzersPageFile;\n\n    public DirectoryPath ChangelogSrcDirectory => changelogBuilder.SrcDirectory;\n\n    public DocumentationRunner(BuildContext context)\n    {\n        this.context = context;\n        changelogBuilder = new ChangelogBuilder(context);\n\n        var docsDirectory = context.RootDirectory.Combine(\"docs\");\n        docsGeneratedDirectory = docsDirectory.Combine(\"_site\");\n        redirectFile = docsDirectory.Combine(\"_redirects\").CombineWithFilePath(\"_redirects\");\n        docfxJsonFile = docsDirectory.CombineWithFilePath(\"docfx.json\");\n        readmeFile = context.RootDirectory.CombineWithFilePath(\"README.md\");\n        rootIndexFile = docsDirectory.CombineWithFilePath(\"index.md\");\n\n        var analyzersDirectory = context.RootDirectory.Combine(\"src\").Combine(\"BenchmarkDotNet.Analyzers\");\n        analyzersShippedFile = analyzersDirectory.CombineWithFilePath(\"AnalyzerReleases.Shipped.md\");\n        analyzersUnshippedFile = analyzersDirectory.CombineWithFilePath(\"AnalyzerReleases.Unshipped.md\");\n        analyzersPageFile = docsDirectory.Combine(\"articles\").CombineWithFilePath(\"analyzers.md\");\n    }\n\n    public void MoveAnalyzerRules()\n    {\n        if (new FileInfo(analyzersUnshippedFile.FullPath).Length == 0)\n        {\n            return;\n        }\n\n        string tempFile = System.IO.Path.GetTempFileName();\n        using (var writer = new StreamWriter(tempFile))\n        {\n            writer.WriteLine($\"## v{context.VersionHistory.CurrentVersion}\");\n            CopyLines(writer, analyzersUnshippedFile);\n            writer.WriteLine();\n            writer.WriteLine();\n            CopyLines(writer, analyzersShippedFile);\n        }\n\n        File.Delete(analyzersShippedFile.FullPath);\n        File.Move(tempFile, analyzersShippedFile.FullPath);\n        File.WriteAllText(analyzersUnshippedFile.FullPath, string.Empty);\n    }\n\n    public void Fetch()\n    {\n        EnvVar.GitHubToken.AssertHasValue();\n        changelogBuilder.Fetch();\n    }\n\n    public void Generate()\n    {\n        GenerateAnalyzersPage();\n\n        changelogBuilder.Generate();\n\n        UpdateReadme();\n        GenerateIndexMd();\n    }\n\n    public void Build()\n    {\n        RunDocfx();\n        GenerateRedirects();\n    }\n\n    private void UpdateReadme()\n    {\n        var content = Utils.ApplyRegex(\n            context.FileReadText(context.ReadmeFile),\n            @\"\\[(\\d+)\\+ GitHub projects\\]\",\n            Repo.GetDependentProjectsNumber().Result.ToString()\n        );\n\n        context.GenerateFile(context.ReadmeFile, content, true);\n    }\n\n\n    private void RunDocfx()\n    {\n        context.Information($\"Running docfx for '{docfxJsonFile}'\");\n\n        var currentDirectory = Directory.GetCurrentDirectory();\n        Directory.SetCurrentDirectory(docfxJsonFile.GetDirectory().FullPath);\n        Docfx.Dotnet.DotnetApiCatalog.GenerateManagedReferenceYamlFiles(docfxJsonFile.FullPath).Wait();\n        Docfx.Docset.Build(docfxJsonFile.FullPath).Wait();\n        Directory.SetCurrentDirectory(currentDirectory);\n    }\n\n    private void GenerateIndexMd()\n    {\n        var content = new StringBuilder();\n        content.AppendLine(\"---\");\n        content.AppendLine(\"title: Home\");\n        content.AppendLine(\"---\");\n        content.Append(context.FileReadText(readmeFile));\n\n        context.GenerateFile(rootIndexFile, content);\n    }\n\n    private void GenerateAnalyzersPage()\n    {\n        context.EnsureDirectoryExists(analyzersPageFile.GetDirectory());\n        using var writer = new StreamWriter(analyzersPageFile.FullPath);\n        writer.WriteLine($\"# Roslyn Analyzers for C#\");\n        writer.WriteLine();\n        CopyLines(writer, analyzersShippedFile);\n    }\n\n    private static void CopyLines(StreamWriter writer, FilePath filePath)\n    {\n        using var reader = new StreamReader(filePath.FullPath);\n        while (reader.ReadLine() is { } line)\n        {\n            writer.WriteLine();\n            writer.Write(line);\n        }\n    }\n\n    private void GenerateRedirects()\n    {\n        if (!context.FileExists(redirectFile))\n        {\n            context.Error($\"Redirect file '{redirectFile}' does not exist\");\n            return;\n        }\n\n        context.EnsureDirectoryExists(docsGeneratedDirectory);\n\n        var redirects = context.FileReadLines(redirectFile)\n            .Select(line => line.Split(' '))\n            .Select(parts => (source: parts[0], target: parts[1]))\n            .ToList();\n\n        foreach (var (source, target) in redirects)\n        {\n            var fileName = source.StartsWith(\"/\") || source.StartsWith(\"\\\\\") ? source[1..] : source;\n            var fullFilePath = docsGeneratedDirectory.CombineWithFilePath(fileName);\n            var content =\n                $\"<!doctype html>\" +\n                $\"<html lang=en-us>\" +\n                $\"<head>\" +\n                $\"<title>{target}</title>\" +\n                $\"<link rel=canonical href='{target}'>\" +\n                $\"<meta name=robots content=\\\"noindex\\\">\" +\n                $\"<meta charset=utf-8><meta http-equiv=refresh content=\\\"0; url={target}\\\">\" +\n                $\"</head>\" +\n                $\"</html>\";\n            context.EnsureDirectoryExists(fullFilePath.GetDirectory());\n            context.GenerateFile(fullFilePath, content);\n        }\n    }\n}"
  },
  {
    "path": "build/BenchmarkDotNet.Build/Runners/GitRunner.cs",
    "content": "using System;\nusing BenchmarkDotNet.Build.Meta;\nusing Cake.Common;\nusing Cake.Common.Diagnostics;\nusing Cake.Core.IO;\nusing Cake.Git;\n\nnamespace BenchmarkDotNet.Build.Runners;\n\n// Cake.Git 3.0.0 may experience the following issues on macOS:\n// > Error: System.TypeInitializationException: The type initializer for 'LibGit2Sharp.Core.NativeMethods' threw an exception.\n// >    ---> System.DllNotFoundException: Unable to load shared library 'git2-6777db8' or one of its dependencies. In order to help diagnose loading problems, consider setting the DYLD_PRINT_LIBRARIES environment variable\n// In order to workaround this problem, we provide command-line fallbacks for all the used commands.\npublic class GitRunner\n{\n    private BuildContext context;\n\n    public GitRunner(BuildContext context)\n    {\n        this.context = context;\n    }\n\n    public void Clone(DirectoryPath workDirectoryPath, string sourceUrl, string branchName)\n    {\n        context.Information($\"[GitClone]\");\n        context.Information($\"  Repo: {sourceUrl}\");\n        context.Information($\"  Branch: {branchName}\");\n        context.Information($\"  Path: {workDirectoryPath}\");\n\n        var settings = new GitCloneSettings { Checkout = true, BranchName = branchName };\n        RunCommand(\n            () => context.GitClone(sourceUrl, workDirectoryPath, settings),\n            $\"clone -b {branchName} {sourceUrl} {workDirectoryPath}\");\n    }\n\n    public void Pull(DirectoryPath workDirectoryPath)\n    {\n        context.Information($\"[GitPull]\");\n        context.Information($\"  Path: {workDirectoryPath}\");\n\n        RunCommand(\n            () => context.GitPull(workDirectoryPath, null, null),\n            $\"-C {workDirectoryPath} pull\");\n    }\n\n    public void Tag(string tagName)\n    {\n        context.Information(\"[GitTag]\");\n        context.Information($\"  Path: {context.RootDirectory}\");\n        context.Information($\"  TagName: {tagName}\");\n\n        RunCommand(\n            () => context.GitTag(context.RootDirectory, tagName),\n            $\"tag {tagName}\");\n    }\n\n    public void BranchMove(string branchName, string target)\n    {\n        context.Information(\"[GitBranchMove]\");\n        context.Information($\"  Branch: {branchName}\");\n        context.Information($\"  Target: {target}\");\n        RunCommand($\"branch -f {branchName} {target}\");\n    }\n\n    public void AddAll(DirectoryPath? repoDirectory = null)\n    {\n        var repoFlag = repoDirectory != null ? $\"-C {repoDirectory}\" : \"\";\n        context.Information(\"[GitAddAll]\");\n        RunCommand($\"{repoFlag} add -A\");\n    }\n\n    public void Commit(string message, DirectoryPath? repoDirectory = null)\n    {\n        context.Information(\"[GitCommit]\");\n        context.Information($\"  Message: {message}\");\n        var repoFlag = repoDirectory != null ? $\"-C {repoDirectory}\" : \"\";\n        RunCommand($\"{repoFlag} \" +\n                   $\"-c user.name=\\\"{Repo.MaintainerAuthorName}\\\" \" +\n                   $\"-c user.email=\\\"{Repo.MaintainerAuthorEmail}\\\" \" +\n                   $\"commit \" +\n                   $\"--author=\\\"{Repo.MaintainerAuthorName} <{Repo.MaintainerAuthorEmail}>\\\" \" +\n                   $\"--all \" +\n                   $\"--message \\\"{message}\\\"\".Trim());\n    }\n\n    public void Push(string target, bool force = false, DirectoryPath? repoDirectory = null)\n    {\n        context.Information(\"[GitPush]\");\n        context.Information($\"  Target: {target}\");\n        context.Information($\"  Force: {force}\");\n        context.RunOnlyInPushMode(() =>\n        {\n            var forceFlag = force ? \" --force\" : \"\";\n            var repoFlag = repoDirectory != null ? $\"-C {repoDirectory}\" : \"\";\n            RunCommand($\"{repoFlag} push origin {target}{forceFlag}\".Trim());\n        });\n    }\n\n    private void RunCommand(string commandLineArgs) => RunCommand(null, commandLineArgs);\n\n    private void RunCommand(Action? call, string commandLineArgs)\n    {\n        try\n        {\n            if (call == null)\n                throw new NotImplementedException();\n            call();\n            context.Information(\"  Success\");\n        }\n        catch (Exception e)\n        {\n            if (e is not NotImplementedException)\n                context.Warning($\"  Failed to perform operation via API ({e.Message})\");\n            try\n            {\n                context.Information($\"  Run command in terminal: 'git {commandLineArgs}'\");\n                context.StartProcess(\"git\", new ProcessSettings\n                {\n                    Arguments = commandLineArgs,\n                    WorkingDirectory = context.RootDirectory\n                });\n                context.Information(\"  Success\");\n            }\n            catch (Exception e2)\n            {\n                throw new Exception($\"Failed to run 'git ${commandLineArgs}'\", e2);\n            }\n        }\n    }\n}"
  },
  {
    "path": "build/BenchmarkDotNet.Build/Runners/ReleaseRunner.cs",
    "content": "using System;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing BenchmarkDotNet.Build.Helpers;\nusing BenchmarkDotNet.Build.Meta;\nusing BenchmarkDotNet.Build.Options;\nusing Cake.Common.Diagnostics;\nusing Cake.Common.IO;\nusing Cake.Common.Tools.DotNet;\nusing Cake.Common.Tools.DotNet.NuGet.Push;\nusing Cake.FileHelpers;\nusing Octokit;\n\nnamespace BenchmarkDotNet.Build.Runners;\n\npublic class ReleaseRunner\n{\n    private readonly BuildContext context;\n\n    public ReleaseRunner(BuildContext context)\n    {\n        this.context = context;\n    }\n\n    public void VersionIncrement()\n    {\n        var currentVersion = context.VersionHistory.CurrentVersion;\n        var nextVersion = KnownOptions.NextVersion.Resolve(context);\n        if (nextVersion == \"\")\n        {\n            var version = Version.Parse(currentVersion);\n            nextVersion = $\"{version.Major}.{version.Minor}.{version.Build + 1}\";\n            context.Information($\"Evaluated NextVersion: {nextVersion}\");\n        }\n        UpdateVersionsTxt(nextVersion);\n        UpdateCommonPropsVersion(nextVersion);\n        UpdateTemplateVersion(nextVersion);\n    }\n\n    public void Run()\n    {\n        KnownOptions.Stable.AssertTrue(context);\n\n        EnvVar.GitHubToken.AssertHasValue();\n        if (KnownOptions.Push.Resolve(context))\n            EnvVar.NuGetToken.AssertHasValue();\n        else\n            EnvVar.NuGetToken.SetEmpty();\n\n        var currentVersion = context.VersionHistory.CurrentVersion;\n        var tag = \"v\" + currentVersion;\n        var nextVersion = KnownOptions.NextVersion.Resolve(context);\n        if (nextVersion == \"\")\n        {\n            var version = Version.Parse(currentVersion);\n            nextVersion = $\"{version.Major}.{version.Minor}.{version.Build + 1}\";\n            context.Information($\"Evaluated NextVersion: {nextVersion}\");\n        }\n\n        context.GitRunner.Tag(tag);\n\n        // Upgrade current version and commit changes\n        UpdateVersionsTxt(nextVersion);\n        UpdateCommonPropsVersion(nextVersion);\n        context.Information($\"Building {context.TemplatesTestsProjectFile}\");\n        context.BuildRunner.BuildProjectSilent(context.TemplatesTestsProjectFile);\n        context.GitRunner.Commit($\"Set next BenchmarkDotNet version: {nextVersion}\");\n\n        UpdateMilestones(nextVersion).Wait();\n\n        context.GitRunner.BranchMove(Repo.DocsStableBranch, \"HEAD\");\n        context.GitRunner.Push(Repo.MasterBranch);\n        context.GitRunner.Push(Repo.DocsStableBranch, true, context.DocumentationRunner.ChangelogSrcDirectory);\n        context.GitRunner.Push(tag);\n\n        PushNupkg();\n\n        PublishGitHubRelease();\n    }\n\n    private void UpdateVersionsTxt(string versionToAppend)\n    {\n        var content = context.FileReadText(context.VersionsFile).Trim();\n        context.GenerateFile(context.VersionsFile, $\"{content}\\n{versionToAppend}\");\n        context.Information($\"Added v{versionToAppend} to {context.VersionsFile}\");\n    }\n\n    private void UpdateCommonPropsVersion(string newCurrentVersion)\n    {\n        var content = Utils.ApplyRegex(\n            context.FileReadText(context.CommonPropsFile),\n            @\"<VersionPrefix>([\\d\\.]+)</VersionPrefix>\",\n            newCurrentVersion);\n        context.GenerateFile(context.CommonPropsFile, content);\n        context.Information($\"Set v{newCurrentVersion} as VersionPrefix in {context.CommonPropsFile}\");\n    }\n\n    private void UpdateTemplateVersion(string newCurrentVersion)\n    {\n        context.BuildRunner.BuildProjectSilent(context.TemplatesTestsProjectFile);\n        context.Information($\"Set v{newCurrentVersion} in templates from {context.TemplatesTestsProjectFile}\");\n    }\n\n    private async Task UpdateMilestones(string nextVersion)\n    {\n        var currentVersion = context.VersionHistory.CurrentVersion;\n\n        var client = Utils.CreateGitHubClient();\n        var allMilestones = await client.Issue.Milestone.GetAllForRepository(Repo.Owner, Repo.Name);\n        var currentMilestone = allMilestones.First(milestone => milestone.Title == $\"v{currentVersion}\");\n\n        context.Information($\"[GitHub] Close milestone v{currentVersion}\");\n        context.RunOnlyInPushMode(() =>\n        {\n            var milestoneUpdate = new MilestoneUpdate { State = ItemState.Closed, DueOn = DateTimeOffset.Now };\n            client.Issue.Milestone.Update(Repo.Owner, Repo.Name, currentMilestone.Number, milestoneUpdate).Wait();\n        });\n\n        context.Information($\"[GitHub] Create milestone v{nextVersion}\");\n        context.RunOnlyInPushMode(() =>\n        {\n            client.Issue.Milestone.Create(Repo.Owner, Repo.Name, new NewMilestone($\"v{nextVersion}\")).Wait();\n        });\n    }\n\n    private void PushNupkg()\n    {\n        var nuGetToken = EnvVar.NuGetToken.GetValue();\n\n        var files = context\n            .GetFiles(context.ArtifactsDirectory.CombineWithFilePath(\"*.nupkg\").FullPath)\n            .OrderBy(file => file.FullPath);\n        var settings = new DotNetNuGetPushSettings\n        {\n            ApiKey = nuGetToken,\n            SymbolApiKey = nuGetToken,\n            Source = \"https://api.nuget.org/v3/index.json\"\n        };\n\n        foreach (var file in files)\n        {\n            context.Information($\"Push: {file}\");\n            context.RunOnlyInPushMode(() => context.DotNetNuGetPush(file, settings));\n        }\n    }\n\n    private void PublishGitHubRelease()\n    {\n        var version = context.VersionHistory.CurrentVersion;\n        var tag = $\"v{version}\";\n        var notesFile = context.DocumentationRunner\n            .ChangelogSrcDirectory\n            .Combine(\"header\")\n            .CombineWithFilePath($\"{tag}.md\");\n        var notes = $\"Full changelog: https://benchmarkdotnet.org/changelog/{tag}.html\\n\\n\" +\n                    PreprocessMarkdown(context.FileReadText(notesFile));\n\n        context.Information($\"[GitHub] Creating release '{version}'\");\n        var client = Utils.CreateGitHubClient();\n        context.RunOnlyInPushMode(() =>\n        {\n            client.Repository.Release.Create(Repo.Owner, Repo.Name, new NewRelease(tag)\n            {\n                Name = version,\n                Draft = false,\n                Prerelease = false,\n                GenerateReleaseNotes = false,\n                DiscussionCategoryName = \"Announcements\",\n                Body = notes\n            }).Wait();\n            context.Information(\"  Success\");\n        });\n    }\n\n    private static string PreprocessMarkdown(string content)\n    {\n        var lines = content.Split(\"\\n\");\n        var newContent = new StringBuilder();\n        for (var i = 0; i < lines.Length; i++)\n        {\n            newContent.Append(lines[i]);\n            if (i == lines.Length - 1)\n                continue;\n            if (!lines[i].EndsWith(\"  \") && lines[i + 1].StartsWith(\"  \"))\n                continue;\n            newContent.Append(\"\\n\");\n        }\n\n        return newContent.ToString();\n    }\n}"
  },
  {
    "path": "build/BenchmarkDotNet.Build/Runners/UnitTestRunner.cs",
    "content": "using BenchmarkDotNet.Build.Helpers;\nusing Cake.Common;\nusing Cake.Common.Diagnostics;\nusing Cake.Common.Tools.DotNet;\nusing Cake.Common.Tools.DotNet.Test;\nusing Cake.Core.IO;\nusing System.Runtime.InteropServices;\n\nnamespace BenchmarkDotNet.Build.Runners;\n\npublic class UnitTestRunner(BuildContext context)\n{\n    private FilePath UnitTestsProjectFile { get; } = context.RootDirectory\n        .Combine(\"tests\")\n        .Combine(\"BenchmarkDotNet.Tests\")\n        .CombineWithFilePath(\"BenchmarkDotNet.Tests.csproj\");\n\n    private FilePath ExporterTestsProjectFile { get; } = context.RootDirectory\n        .Combine(\"tests\")\n        .Combine(\"BenchmarkDotNet.Exporters.Plotting.Tests\")\n        .CombineWithFilePath(\"BenchmarkDotNet.Exporters.Plotting.Tests.csproj\");\n\n    private FilePath AnalyzerTestsProjectFile { get; } = context.RootDirectory\n        .Combine(\"tests\")\n        .Combine(\"BenchmarkDotNet.Analyzers.Tests\")\n        .CombineWithFilePath(\"BenchmarkDotNet.Analyzers.Tests.csproj\");\n\n    private FilePath IntegrationTestsProjectFile { get; } = context.RootDirectory\n        .Combine(\"tests\")\n        .Combine(\"BenchmarkDotNet.IntegrationTests\")\n        .CombineWithFilePath(\"BenchmarkDotNet.IntegrationTests.csproj\");\n\n    private DirectoryPath TestOutputDirectory { get; } = context.RootDirectory\n        .Combine(\"TestResults\");\n\n    private DotNetTestSettings GetTestSettingsParameters(FilePath logFile, string tfm)\n    {\n        var settings = new DotNetTestSettings\n        {\n            Configuration = context.BuildConfiguration,\n            Framework = tfm,\n            NoBuild = true,\n            NoRestore = true,\n            Loggers = new[] { \"trx\", $\"trx;LogFileName={logFile.FullPath}\", \"console;verbosity=detailed\" },\n            EnvironmentVariables =\n            {\n                [\"Platform\"] = \"\" // force the tool to not look for the .dll in platform-specific directory\n            }\n        };\n        return settings;\n    }\n\n    private void RunTests(FilePath projectFile, string alias, string tfm)\n    {\n        var os = Utils.GetOs();\n        var arch = RuntimeInformation.OSArchitecture.ToString().ToLower();\n        var trxFileName = $\"{os}({arch})-{alias}-{tfm}.trx\";\n        var trxFile = TestOutputDirectory.CombineWithFilePath(trxFileName);\n        var settings = GetTestSettingsParameters(trxFile, tfm);\n\n        context.Information($\"Run tests for {projectFile} ({tfm}), result file: '{trxFile}'\");\n        context.DotNetTest(projectFile.FullPath, settings);\n    }\n\n    private void RunUnitTests(string tfm)\n    {\n        RunTests(UnitTestsProjectFile, \"unit\", tfm);\n        RunTests(ExporterTestsProjectFile, \"exporters\", tfm);\n    }\n\n    public void RunUnitTests()\n    {\n        string[] targetFrameworks = context.IsRunningOnWindows() ? [\"net462\", \"net8.0\"] : [\"net8.0\"];\n        foreach (var targetFramework in targetFrameworks)\n            RunUnitTests(targetFramework);\n    }\n\n    public void RunAnalyzerTests()\n    {\n        string[] targetFrameworks = context.IsRunningOnWindows() ? [\"net462\", \"net8.0\"] : [\"net8.0\"];\n        foreach (var targetFramework in targetFrameworks)\n            RunTests(AnalyzerTestsProjectFile, \"analyzer\", targetFramework);\n    }\n\n    public void RunInTests(string tfm) => RunTests(IntegrationTestsProjectFile, \"integration\", tfm);\n}"
  },
  {
    "path": "build/CodingStyle.ruleset",
    "content": "﻿<RuleSet Name=\"Microsoft.Analyzers.ManagedCodeAnalysis\" Description=\"Microsoft.Analyzers.ManagedCodeAnalysis\" ToolsVersion=\"14.0\">\n  <Rules AnalyzerId=\"Microsoft.Analyzers.ManagedCodeAnalysis\" RuleNamespace=\"Microsoft.Rules.Managed\">\n    <Rule Id=\"CA1000\" Action=\"None\" /> <!-- Do not declare static members on generic types -->\n    <Rule Id=\"CA1001\" Action=\"None\" /> <!-- Non disposable class owns disposable fields -->\n    <Rule Id=\"CA1010\" Action=\"None\" /> <!-- Collections should implement generic interface -->\n    <Rule Id=\"CA1028\" Action=\"None\" /> <!-- Enum storage should be Int32 -->\n    <Rule Id=\"CA1030\" Action=\"None\" /> <!-- Use events where appropriate -->\n    <Rule Id=\"CA1031\" Action=\"None\" /> <!-- Do not catch general exception types -->\n    <Rule Id=\"CA1032\" Action=\"None\" /> <!-- Implement standard exception constructors -->\n    <Rule Id=\"CA1034\" Action=\"None\" /> <!-- Nested types should not be visible -->\n    <Rule Id=\"CA1036\" Action=\"None\" /> <!-- Overload comparison operators when implementing System.IComparable -->\n    <Rule Id=\"CA1043\" Action=\"None\" /> <!-- Use integral or string argument for indexers -->\n    <Rule Id=\"CA1044\" Action=\"None\" /> <!-- Properties should not be write only -->\n    <Rule Id=\"CA1051\" Action=\"None\" /> <!-- Do not declare visible instance fields -->\n    <Rule Id=\"CA1052\" Action=\"None\" /> <!-- Static holder types should be sealed -->\n    <Rule Id=\"CA1054\" Action=\"None\" /> <!-- URI parameters should not be strings -->\n    <Rule Id=\"CA1055\" Action=\"None\" /> <!-- URI return values should not be strings -->\n    <Rule Id=\"CA1056\" Action=\"None\" /> <!-- URI properties should not be strings -->\n    <Rule Id=\"CA1058\" Action=\"None\" /> <!-- Types should not extend certain base types -->\n    <Rule Id=\"CA1061\" Action=\"None\" /> <!-- Do not hide base class methods -->\n    <Rule Id=\"CA1062\" Action=\"None\" /> <!-- Validate arguments of public methods -->\n    <Rule Id=\"CA1063\" Action=\"None\" /> <!-- Implement IDisposable correctly -->\n    <Rule Id=\"CA1064\" Action=\"None\" /> <!-- Exceptions should be public -->\n    <Rule Id=\"CA1065\" Action=\"None\" /> <!-- Do not raise exceptions in unexpected locations -->\n    <Rule Id=\"CA1066\" Action=\"None\" /> <!-- Type should implement IEquatable -->\n    <Rule Id=\"CA1067\" Action=\"None\" /> <!-- Override Object.Equals(object) when implementing IEquatable -->\n    <Rule Id=\"CA1068\" Action=\"None\" /> <!-- CancellationToken parameters must come last -->\n    <Rule Id=\"CA1303\" Action=\"None\" /> <!-- Do not pass literals as localized parameters -->\n    <Rule Id=\"CA1304\" Action=\"None\" /> <!-- Specify CultureInfo -->\n    <Rule Id=\"CA1305\" Action=\"None\" /> <!-- Specify IFormatProvider -->\n    <Rule Id=\"CA1307\" Action=\"None\" /> <!-- Specify StringComparison -->\n    <Rule Id=\"CA1308\" Action=\"None\" /> <!-- Normalize strings to upper case -->\n    <Rule Id=\"CA1707\" Action=\"None\" /> <!-- Identifers should not contain underscores -->\n    <Rule Id=\"CA1710\" Action=\"None\" /> <!-- Identifers should have correct suffix -->\n    <Rule Id=\"CA1712\" Action=\"None\" /> <!-- Do not prefix enum values with type name -->\n    <Rule Id=\"CA1714\" Action=\"None\" /> <!-- Flags enums should have plural names -->\n    <Rule Id=\"CA1715\" Action=\"None\" /> <!-- Type parameters names should be prefixed with T -->\n    <Rule Id=\"CA1716\" Action=\"None\" /> <!-- Identifiers should not match keywords -->\n    <Rule Id=\"CA1717\" Action=\"None\" /> <!-- Only FlagsAttribute enums should have plural names -->\n    <Rule Id=\"CA1720\" Action=\"None\" /> <!-- Identifier contains type name -->\n    <Rule Id=\"CA1721\" Action=\"None\" /> <!-- Property names should not match get methods -->\n    <Rule Id=\"CA1724\" Action=\"None\" /> <!-- Type names should not match namespaces -->\n    <Rule Id=\"CA1801\" Action=\"None\" /> <!-- Review unused parameters -->\n    <Rule Id=\"CA1806\" Action=\"None\" /> <!-- Do not ignore method results -->\n    <Rule Id=\"CA1810\" Action=\"None\" /> <!-- Initialize reference type static fields inline -->\n    <Rule Id=\"CA1812\" Action=\"None\" /> <!-- Avoid uninstantiated internal classes -->\n    <Rule Id=\"CA1814\" Action=\"None\" /> <!-- Prefer jagged arrays over multidimensional -->\n    <Rule Id=\"CA1815\" Action=\"None\" /> <!-- Override equals and operator equals on value types -->\n    <Rule Id=\"CA1816\" Action=\"None\" /> <!-- Dispose methods should call SuppressFinalize -->\n    <Rule Id=\"CA1819\" Action=\"None\" /> <!-- Properties should not return arrays -->\n    <Rule Id=\"CA1820\" Action=\"None\" /> <!-- Test for empty strings using string length -->\n    <Rule Id=\"CA1822\" Action=\"None\" /> <!-- Mark members as static -->\n    <Rule Id=\"CA1826\" Action=\"None\" /> <!-- Do not use Enumerable methods on indexable collections. Instead use the collection directly -->\n    <Rule Id=\"CA2208\" Action=\"None\" /> <!-- Instantiate argument exceptions correctly -->\n    <Rule Id=\"CA2000\" Action=\"None\" /> <!-- Dispose objects before losing scope -->\n    <Rule Id=\"CA2008\" Action=\"None\" /> <!-- Do not create tasks without passing a TaskScheduler -->\n    <Rule Id=\"CA2010\" Action=\"None\" /> <!-- Always consume the value returned by methods marked with PreserveSigAttribute -->\n    <Rule Id=\"CA2100\" Action=\"None\" /> <!-- Review SQL queries for security vulnerabilities -->\n    <Rule Id=\"CA2101\" Action=\"None\" /> <!-- Specify marshaling for P/Invoke string arguments -->\n    <Rule Id=\"CA2119\" Action=\"None\" /> <!-- Seal methods that satisfy private interfaces -->\n    <Rule Id=\"CA2211\" Action=\"None\" /> <!-- Non-constant fields should not be visible -->\n    <Rule Id=\"CA2214\" Action=\"None\" /> <!-- Do not call overridable methods in constructors -->\n    <Rule Id=\"CA2216\" Action=\"None\" /> <!-- Disposable types should declare finalizer -->\n    <Rule Id=\"CA2219\" Action=\"None\" /> <!-- Do not raise exceptions in finally clauses -->\n    <Rule Id=\"CA2225\" Action=\"None\" /> <!-- Operator overloads have named alternates -->\n    <Rule Id=\"CA2231\" Action=\"None\" /> <!-- Overload operator equals when overriding ValueType.Equals -->\n    <Rule Id=\"CA2235\" Action=\"None\" /> <!-- Serializable type has non serializable field -->\n    <Rule Id=\"CA2237\" Action=\"None\" /> <!-- Add [Serializable] to types that implement ISerializable -->\n    <Rule Id=\"CA5366\" Action=\"None\" /> <!-- Use XmlReader For DataSet Read Xml -->\n    <Rule Id=\"CA5369\" Action=\"None\" /> <!-- Use XmlReader For Deserialize -->\n    <Rule Id=\"CA5371\" Action=\"None\" /> <!-- Use XmlReader For Schema Read -->\n    <Rule Id=\"CA5372\" Action=\"None\" /> <!-- Use XmlReader For XPathDocument -->\n  </Rules>\n  <Rules AnalyzerId=\"StyleCop.Analyzers\" RuleNamespace=\"StyleCop.Analyzers\">\n    <Rule Id=\"AD0001\" Action=\"None\" /> <!-- Analyzer threw an exception -->\n    <Rule Id=\"SA0001\" Action=\"None\" /> <!-- XML comments -->\n    <Rule Id=\"SA1002\" Action=\"None\" /> <!-- Semicolons should not be preceded by a space -->\n    <Rule Id=\"SA1003\" Action=\"None\" /> <!-- Operator should not appear at the end of a line -->\n    <Rule Id=\"SA1004\" Action=\"None\" /> <!-- Documentation line should begin with a space -->\n    <Rule Id=\"SA1005\" Action=\"None\" /> <!-- Single line comment should begin with a space -->\n    <Rule Id=\"SA1008\" Action=\"None\" /> <!-- Opening parenthesis should not be preceded by a space -->\n    <Rule Id=\"SA1009\" Action=\"None\" /> <!-- Closing parenthesis should not be followed by a space -->\n    <Rule Id=\"SA1010\" Action=\"None\" /> <!-- Opening square brackets should not be preceded by a space -->\n    <Rule Id=\"SA1011\" Action=\"None\" /> <!-- Closing square bracket should be followed by a space -->\n    <Rule Id=\"SA1012\" Action=\"None\" /> <!-- Opening brace should be followed by a space -->\n    <Rule Id=\"SA1013\" Action=\"None\" /> <!-- Closing brace should be preceded by a space -->\n    <Rule Id=\"SA1015\" Action=\"None\" /> <!-- Closing generic bracket should not be followed by a space -->\n    <Rule Id=\"SA1021\" Action=\"None\" /> <!-- Negative sign should be preceded by a space -->\n    <Rule Id=\"SA1023\" Action=\"None\" /> <!-- Dereference symbol '*' should not be preceded by a space.\" -->\n    <Rule Id=\"SA1024\" Action=\"None\" /> <!-- Colon should be followed by a space -->\n    <Rule Id=\"SA1025\" Action=\"None\" /> <!-- Code should not contain multiple whitespace characters in a row -->\n    <Rule Id=\"SA1100\" Action=\"None\" /> <!-- Do not prefix calls with base unless local implementation exists -->\n    <Rule Id=\"SA1101\" Action=\"None\" /> <!-- Prefix local calls with this -->\n    <Rule Id=\"SA1106\" Action=\"None\" /> <!-- Code should not contain empty statements -->\n    <Rule Id=\"SA1107\" Action=\"None\" /> <!-- Code should not contain multiple statements on one line -->\n    <Rule Id=\"SA1108\" Action=\"None\" /> <!-- Block statements should not contain embedded comments -->\n    <Rule Id=\"SA1110\" Action=\"None\" /> <!-- Opening parenthesis or bracket should be on declaration line -->\n    <Rule Id=\"SA1111\" Action=\"None\" /> <!-- Closing parenthesis should be on line of last parameter -->\n    <Rule Id=\"SA1114\" Action=\"None\" /> <!-- Parameter list should follow declaration -->\n    <Rule Id=\"SA1115\" Action=\"None\" /> <!-- The parameter should begin on the line after the previous parameter -->\n    <Rule Id=\"SA1116\" Action=\"None\" /> <!-- Split parameters should start on line after declaration -->\n    <Rule Id=\"SA1117\" Action=\"None\" /> <!-- Parameters should be on same line or separate lines -->\n    <Rule Id=\"SA1118\" Action=\"None\" /> <!-- Parameter should not span multiple lines -->\n    <Rule Id=\"SA1119\" Action=\"None\" /> <!-- Statement should not use unnecessary parenthesis -->\n    <Rule Id=\"SA1120\" Action=\"None\" /> <!-- Comments should contain text -->\n    <Rule Id=\"SA1122\" Action=\"None\" /> <!-- Use string.Empty for empty strings -->\n    <Rule Id=\"SA1123\" Action=\"None\" /> <!-- Region should not be located within a code element -->\n    <Rule Id=\"SA1124\" Action=\"None\" /> <!-- Do not use regions -->\n    <Rule Id=\"SA1125\" Action=\"None\" /> <!-- Use shorthand for nullable types -->\n    <Rule Id=\"SA1127\" Action=\"None\" /> <!-- Generic type constraints should be on their own line -->\n    <Rule Id=\"SA1128\" Action=\"None\" /> <!-- Put constructor initializers on their own line -->\n    <Rule Id=\"SA1129\" Action=\"None\" /> <!-- Do not use default value type constructor -->\n    <Rule Id=\"SA1130\" Action=\"None\" /> <!-- Use lambda syntax -->\n    <Rule Id=\"SA1131\" Action=\"None\" /> <!-- Constant values should appear on the right-hand side of comparisons -->\n    <Rule Id=\"SA1132\" Action=\"None\" /> <!-- Do not combine fields -->\n    <Rule Id=\"SA1133\" Action=\"None\" /> <!-- Do not combine attributes -->\n    <Rule Id=\"SA1134\" Action=\"None\" /> <!-- Each attribute should be placed on its own line of code -->\n    <Rule Id=\"SA1135\" Action=\"None\" /> <!-- Using directive should be qualified -->\n    <Rule Id=\"SA1136\" Action=\"None\" /> <!-- Enum values should be on separate lines -->\n    <Rule Id=\"SA1137\" Action=\"None\" /> <!-- Elements should have the same indentation -->\n    <Rule Id=\"SA1139\" Action=\"None\" /> <!-- Use literal suffix notation instead of casting -->\n    <Rule Id=\"SA1200\" Action=\"None\" /> <!-- Using directive should appear within a namespace declaration -->\n    <Rule Id=\"SA1201\" Action=\"None\" /> <!-- Elements should appear in the correct order -->\n    <Rule Id=\"SA1202\" Action=\"None\" /> <!-- Elements should be ordered by access -->\n    <Rule Id=\"SA1203\" Action=\"None\" /> <!-- Constants should appear before fields -->\n    <Rule Id=\"SA1204\" Action=\"None\" /> <!-- Static elements should appear before instance elements -->\n    <Rule Id=\"SA1206\" Action=\"None\" /> <!-- The 'static' modifier should appear before 'new' -->\n    <Rule Id=\"SA1208\" Action=\"None\" /> <!-- Using directive ordering -->\n    <Rule Id=\"SA1209\" Action=\"None\" /> <!-- Using alias directives should be placed after all using namespace directives -->\n    <Rule Id=\"SA1210\" Action=\"None\" /> <!-- Using directives should be ordered alphabetically by the namespaces -->\n    <Rule Id=\"SA1211\" Action=\"None\" /> <!-- Using alias directive ordering -->\n    <Rule Id=\"SA1214\" Action=\"None\" /> <!-- Readonly fields should appear before non-readonly fields -->\n    <Rule Id=\"SA1216\" Action=\"None\" /> <!-- Using static directives should be placed at the correct location -->\n    <Rule Id=\"SA1300\" Action=\"None\" /> <!-- Element should begin with an uppercase letter -->\n    <Rule Id=\"SA1303\" Action=\"None\" /> <!-- Const field names should begin with upper-case letter -->\n    <Rule Id=\"SA1304\" Action=\"None\" /> <!-- Non-private readonly fields should begin with upper-case letter -->\n    <Rule Id=\"SA1306\" Action=\"None\" /> <!-- Field should begin with lower-case letter -->\n    <Rule Id=\"SA1307\" Action=\"None\" /> <!-- Field should begin with upper-case letter -->\n    <Rule Id=\"SA1308\" Action=\"None\" /> <!-- Field should not begin with the prefix 's_' -->\n    <Rule Id=\"SA1309\" Action=\"None\" /> <!-- Field names should not begin with underscore -->\n    <Rule Id=\"SA1310\" Action=\"None\" /> <!-- Field should not contain an underscore -->\n    <Rule Id=\"SA1311\" Action=\"None\" /> <!-- Static readonly fields should begin with upper-case letter -->\n    <Rule Id=\"SA1312\" Action=\"None\" /> <!-- Variable should begin with lower-case letter -->\n    <Rule Id=\"SA1313\" Action=\"None\" /> <!-- Parameter should begin with lower-case letter -->\n    <Rule Id=\"SA1314\" Action=\"None\" /> <!-- Type parameter names should begin with T -->\n    <Rule Id=\"SA1316\" Action=\"None\" /> <!-- Tuple element names should use correct casing -->\n    <Rule Id=\"SA1401\" Action=\"None\" /> <!-- Fields should be private -->\n    <Rule Id=\"SA1402\" Action=\"None\" /> <!-- File may only contain a single type -->\n    <Rule Id=\"SA1403\" Action=\"None\" /> <!-- File may only contain a single namespace -->\n    <Rule Id=\"SA1404\" Action=\"None\" /> <!-- Code analysis suppression should have justification -->\n    <Rule Id=\"SA1405\" Action=\"None\" /> <!-- Debug.Assert should provide message text -->\n    <Rule Id=\"SA1407\" Action=\"None\" /> <!-- Arithmetic expressions should declare precedence -->\n    <Rule Id=\"SA1408\" Action=\"None\" /> <!-- Conditional expressions should declare precedence -->\n    <Rule Id=\"SA1413\" Action=\"None\" /> <!-- Use trailing comma in multi-line initializers -->\n    <Rule Id=\"SA1414\" Action=\"None\" /> <!-- Tuple types in signatures should have element names -->\n    <Rule Id=\"SA1500\" Action=\"None\" /> <!-- Braces for multi-line statements should not share line -->\n    <Rule Id=\"SA1501\" Action=\"None\" /> <!-- Statement should not be on a single line -->\n    <Rule Id=\"SA1502\" Action=\"None\" /> <!-- Element should not be on a single line -->\n    <Rule Id=\"SA1503\" Action=\"None\" /> <!-- Braces should not be omitted -->\n    <Rule Id=\"SA1504\" Action=\"None\" /> <!-- All accessors should be single-line or multi-line -->\n    <Rule Id=\"SA1505\" Action=\"None\" /> <!-- An opening brace should not be followed by a blank line -->\n    <Rule Id=\"SA1506\" Action=\"None\" /> <!-- Element documentation headers should not be followed by blank line -->\n    <Rule Id=\"SA1507\" Action=\"None\" /> <!-- Code should not contain multiple blank lines in a row -->\n    <Rule Id=\"SA1508\" Action=\"None\" /> <!-- A closing brace should not be preceded by a blank line -->\n    <Rule Id=\"SA1509\" Action=\"None\" /> <!-- Opening braces should not be preceded by blank line -->\n    <Rule Id=\"SA1510\" Action=\"None\" /> <!-- 'else' statement should not be preceded by a blank line -->\n    <Rule Id=\"SA1512\" Action=\"None\" /> <!-- Single-line comments should not be followed by blank line -->\n    <Rule Id=\"SA1513\" Action=\"None\" /> <!-- Closing brace should be followed by blank line -->\n    <Rule Id=\"SA1514\" Action=\"None\" /> <!-- Element documentation header should be preceded by blank line -->\n    <Rule Id=\"SA1515\" Action=\"None\" /> <!-- Single-line comment should be preceded by blank line -->\n    <Rule Id=\"SA1516\" Action=\"None\" /> <!-- Elements should be separated by blank line -->\n    <Rule Id=\"SA1519\" Action=\"None\" /> <!-- Braces should not be omitted from multi-line child statement -->\n    <Rule Id=\"SA1520\" Action=\"None\" /> <!-- Use braces consistently -->\n    <Rule Id=\"SA1600\" Action=\"None\" /> <!-- Elements should be documented -->\n    <Rule Id=\"SA1601\" Action=\"None\" /> <!-- Partial elements should be documented -->\n    <Rule Id=\"SA1602\" Action=\"None\" /> <!-- Enumeration items should be documented -->\n    <Rule Id=\"SA1604\" Action=\"None\" /> <!-- Element documentation should have summary -->\n    <Rule Id=\"SA1605\" Action=\"None\" /> <!-- Partial element documentation should have summary -->\n    <Rule Id=\"SA1606\" Action=\"None\" /> <!-- Element documentation should have summary text -->\n    <Rule Id=\"SA1608\" Action=\"None\" /> <!-- Element documentation should not have default summary -->\n    <Rule Id=\"SA1610\" Action=\"None\" /> <!-- Property documentation should have value text -->\n    <Rule Id=\"SA1611\" Action=\"None\" /> <!-- The documentation for parameter 'message' is missing -->\n    <Rule Id=\"SA1612\" Action=\"None\" /> <!-- The parameter documentation is at incorrect position -->\n    <Rule Id=\"SA1614\" Action=\"None\" /> <!-- Element parameter documentation should have text -->\n    <Rule Id=\"SA1615\" Action=\"None\" /> <!-- Element return value should be documented -->\n    <Rule Id=\"SA1616\" Action=\"None\" /> <!-- Element return value documentation should have text -->\n    <Rule Id=\"SA1618\" Action=\"None\" /> <!-- The documentation for type parameter is missing -->\n    <Rule Id=\"SA1619\" Action=\"None\" /> <!-- The documentation for type parameter is missing -->\n    <Rule Id=\"SA1622\" Action=\"None\" /> <!-- Generic type parameter documentation should have text -->\n    <Rule Id=\"SA1623\" Action=\"None\" /> <!-- Property documentation text -->\n    <Rule Id=\"SA1624\" Action=\"None\" /> <!-- Because the property only contains a visible get accessor, the documentation summary text should begin with 'Gets' -->\n    <Rule Id=\"SA1625\" Action=\"None\" /> <!-- Element documentation should not be copied and pasted -->\n    <Rule Id=\"SA1626\" Action=\"None\" /> <!-- Single-line comments should not use documentation style slashes -->\n    <Rule Id=\"SA1627\" Action=\"None\" /> <!-- The documentation text within the \\'exception\\' tag should not be empty -->\n    <Rule Id=\"SA1629\" Action=\"None\" /> <!-- Documentation text should end with a period -->\n    <Rule Id=\"SA1633\" Action=\"None\" /> <!-- File should have header -->\n    <Rule Id=\"SA1642\" Action=\"None\" /> <!-- Constructor summary documentation should begin with standard text -->\n    <Rule Id=\"SA1643\" Action=\"None\" /> <!-- Destructor summary documentation should begin with standard text -->\n    <Rule Id=\"SA1649\" Action=\"None\" /> <!-- File name should match first type name -->\n  </Rules>\n</RuleSet>"
  },
  {
    "path": "build/build.bat",
    "content": "@ECHO OFF\nPowerShell -NoProfile -NoLogo -ExecutionPolicy unrestricted -Command \"[System.Threading.Thread]::CurrentThread.CurrentCulture = ''; [System.Threading.Thread]::CurrentThread.CurrentUICulture = '';& '%~dp0build.ps1' %*; exit $LASTEXITCODE\""
  },
  {
    "path": "build/build.ps1",
    "content": "#!/usr/bin/env pwsh\n\n$DotNetInstallerUri = 'https://dot.net/v1/dotnet-install.ps1';\n$BuildPath = Split-Path $MyInvocation.MyCommand.Path -Parent\n$PSScriptRoot = Split-Path $PSScriptRoot -Parent\n\nif ($PSVersionTable.PSEdition -ne 'Core') {\n    # Attempt to set highest encryption available for SecurityProtocol.\n    # PowerShell will not set this by default (until maybe .NET 4.6.x). This\n    # will typically produce a message for PowerShell v2 (just an info\n    # message though)\n    try {\n        # Set TLS 1.2 (3072), then TLS 1.1 (768), then TLS 1.0 (192), finally SSL 3.0 (48)\n        # Use integers because the enumeration values for TLS 1.2 and TLS 1.1 won't\n        # exist in .NET 4.0, even though they are addressable if .NET 4.5+ is\n        # installed (.NET 4.5 is an in-place upgrade).\n        [System.Net.ServicePointManager]::SecurityProtocol = 3072 -bor 768 -bor 192 -bor 48\n      } catch {\n        Write-Output 'Unable to set PowerShell to use TLS 1.2 and TLS 1.1 due to old .NET Framework installed. If you see underlying connection closed or trust errors, you may need to upgrade to .NET Framework 4.5+ and PowerShell v3'\n      }\n}\n\n###########################################################################\n# INSTALL .NET CORE CLI\n###########################################################################\n\n$env:DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1\n$env:DOTNET_CLI_TELEMETRY_OPTOUT=1\n\nFunction Remove-PathVariable([string]$VariableToRemove)\n{\n    $SplitChar = ';'\n    if ($IsMacOS -or $IsLinux) {\n        $SplitChar = ':'\n    }\n\n    $path = [Environment]::GetEnvironmentVariable(\"PATH\", \"User\")\n    if ($path -ne $null)\n    {\n        $newItems = $path.Split($SplitChar, [StringSplitOptions]::RemoveEmptyEntries) | Where-Object { \"$($_)\" -inotlike $VariableToRemove }\n        [Environment]::SetEnvironmentVariable(\"PATH\", [System.String]::Join($SplitChar, $newItems), \"User\")\n    }\n\n    $path = [Environment]::GetEnvironmentVariable(\"PATH\", \"Process\")\n    if ($path -ne $null)\n    {\n        $newItems = $path.Split($SplitChar, [StringSplitOptions]::RemoveEmptyEntries) | Where-Object { \"$($_)\" -inotlike $VariableToRemove }\n        [Environment]::SetEnvironmentVariable(\"PATH\", [System.String]::Join($SplitChar, $newItems), \"Process\")\n    }\n}\n\n$InstallPath = Join-Path $PSScriptRoot \".dotnet\"\n$SdkPath = Join-Path $BuildPath \"sdk\"\n$GlobalJsonPath = Join-Path $SdkPath \"global.json\"\nif (!(Test-Path $InstallPath)) {\n    New-Item -Path $InstallPath -ItemType Directory -Force | Out-Null;\n    $ScriptPath = Join-Path $InstallPath 'dotnet-install.ps1'\n    (New-Object System.Net.WebClient).DownloadFile($DotNetInstallerUri, $ScriptPath);\n    & $ScriptPath -JSonFile $GlobalJsonPath -InstallDir $InstallPath;\n\n    # Install .NET 8 SDK\n    & $ScriptPath -Channel 8.0 -InstallDir $InstallPath -NoPath;\n}\n\nRemove-PathVariable \"$InstallPath\"\n$env:PATH = \"$InstallPath;$env:PATH\"\n$env:DOTNET_ROOT=$InstallPath\n\n###########################################################################\n# RUN BUILD SCRIPT\n###########################################################################\n& dotnet run --configuration Release --project build/BenchmarkDotNet.Build/BenchmarkDotNet.Build.csproj -- $args\n\nexit $LASTEXITCODE;"
  },
  {
    "path": "build/build.sh",
    "content": "#!/usr/bin/env bash\n\n# Define variables\nPROJECT_ROOT=$( cd \"$( dirname \"${BASH_SOURCE[0]}\" )\" && cd .. && pwd )\n\n###########################################################################\n# INSTALL .NET CORE CLI\n###########################################################################\n\nexport DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1\nexport DOTNET_CLI_TELEMETRY_OPTOUT=1\nexport DOTNET_SYSTEM_NET_HTTP_USESOCKETSHTTPHANDLER=0\n\nif [ ! -d \"$PROJECT_ROOT/.dotnet\" ]; then\n    mkdir \"$PROJECT_ROOT/.dotnet\"\n    curl -Lsfo \"$PROJECT_ROOT/.dotnet/dotnet-install.sh\" https://dot.net/v1/dotnet-install.sh\n    bash \"$PROJECT_ROOT/.dotnet/dotnet-install.sh\" --jsonfile ./build/sdk/global.json --install-dir .dotnet --no-path\n\n    # Install .NET 8 SDK\n    bash \"$PROJECT_ROOT/.dotnet/dotnet-install.sh\" --channel 8.0 --install-dir .dotnet --no-path\nfi\n\nexport PATH=\"$PROJECT_ROOT/.dotnet\":$PATH\nexport DOTNET_ROOT=\"$PROJECT_ROOT/.dotnet\"\n\n###########################################################################\n# RUN BUILD SCRIPT\n###########################################################################\n\ndotnet run --configuration Release --project \"$PROJECT_ROOT/build/BenchmarkDotNet.Build/BenchmarkDotNet.Build.csproj\" -- \"$@\"\n"
  },
  {
    "path": "build/cSpell.json",
    "content": "{\n  \"version\": \"0.2\",\n  \"language\": \"en\",\n  \"words\": [\n    \"Alloc\",\n    \"analyse\",\n    \"analyser\",\n    \"Analysers\",\n    \"Autofac\",\n    \"bitness\",\n    \"corlib\",\n    \"Cygwin\",\n    \"Diagnoser\",\n    \"diagnosers\",\n    \"diagsession\",\n    \"disassemblers\",\n    \"disassm\",\n    \"Jits\",\n    \"Jitting\",\n    \"LINQ\",\n    \"microbenchmarking\",\n    \"microbenchmarks\",\n    \"Mispredict\",\n    \"Mispredictions\",\n    \"msbuild\",\n    \"Multimodal\",\n    \"multimodality\",\n    \"netcoreapp\",\n    \"powerplans\",\n    \"Pseudocode\",\n    \"runtimes\",\n    \"Serilog\",\n    \"slnx\",\n    \"vsprofiler\",\n    \"vstest\",\n    \"Tailcall\",\n    \"toolchains\",\n    \"unmanaged\"\n  ],\n  \"ignoreWords\": [\n    \"Akinshin\",\n    \"Andrey\",\n    \"Cassell\",\n    \"Expecto\",\n    \"Jint\",\n    \"JITted\",\n    \"LoongArch64\",\n    \"macrobenchmark\",\n    \"MediatR\",\n    \"Nagórski's\",\n    \"Newtonsoft\",\n    \"NodaTime\",\n    \"Npgsql\",\n    \"Sitnik's\",\n    \"Sitnik\",\n    \"Stepanov\",\n    \"Yegor\",\n    \"Wojciech\",\n    \"Avalonia\",\n    \"Gitter\"\n  ],\n  \"patterns\": [\n    {\n      \"name\": \"Markdown links\",\n      \"pattern\": \"\\\\((.*)\\\\)\",\n      \"description\": \"\"\n    },\n    {\n      \"name\": \"Markdown code blocks\",\n      \"pattern\": \"/^(\\\\s*`{3,}).*[\\\\s\\\\S]*?^\\\\1/gmx\",\n      \"description\": \"Taken from the cSpell example at https://cspell.org/configuration/patterns/#verbose-regular-expressions\"\n    },\n    {\n      \"name\": \"Inline code blocks\",\n      \"pattern\": \"\\\\`([^\\\\`\\\\r\\\\n]+?)\\\\`\",\n      \"description\": \"https://stackoverflow.com/questions/41274241/how-to-capture-inline-markdown-code-but-not-a-markdown-code-fence-with-regex\"\n    },\n    {\n      \"name\": \"Link contents\",\n      \"pattern\": \"\\\\<a(.*)\\\\>\",\n      \"description\": \"\"\n    },\n    {\n      \"name\": \"Snippet references\",\n      \"pattern\": \"-- snippet:(.*)\",\n      \"description\": \"\"\n    },\n    {\n      \"name\": \"Snippet references 2\",\n      \"pattern\": \"\\\\<\\\\[sample:(.*)\",\n      \"description\": \"another kind of snippet reference\"\n    },\n    {\n      \"name\": \"Multi-line code blocks\",\n      \"pattern\": \"/^\\\\s*```[\\\\s\\\\S]*?^\\\\s*```/gm\"\n    },\n    {\n      \"name\": \"HTML Tags\",\n      \"pattern\": \"<[^>]*>\",\n      \"description\": \"Reference: https://stackoverflow.com/questions/11229831/regular-expression-to-remove-html-tags-from-a-string\"\n    }\n  ],\n  \"ignoreRegExpList\": [\n    \"Markdown links\",\n    \"Markdown code blocks\",\n    \"Inline code blocks\",\n    \"Link contents\",\n    \"Snippet references\",\n    \"Snippet references 2\",\n    \"Multi-line code blocks\",\n    \"HTML Tags\"\n  ],\n  \"ignorePaths\": [\n    \"docs/_changelog/**/*.md\",\n    \"docs/articles/team.md\"\n  ]\n}\n"
  },
  {
    "path": "build/common.props",
    "content": "<Project>\n  <PropertyGroup>\n    <Product>BenchmarkDotNet</Product>\n    <Description>Powerful .NET library for benchmarking</Description>\n    <Copyright>.NET Foundation and contributors</Copyright>\n    <NeutralLanguage>en-US</NeutralLanguage>\n    <Authors>.NET Foundation and contributors</Authors>\n    <PackageTags>benchmark;benchmarking;performance</PackageTags>\n    <PackageIcon>package-icon.png</PackageIcon>\n    <PackageProjectUrl>https://github.com/dotnet/BenchmarkDotNet</PackageProjectUrl>\n    <PackageLicenseExpression>MIT</PackageLicenseExpression>\n    <RepositoryType>git</RepositoryType>\n    <RepositoryUrl>https://github.com/dotnet/BenchmarkDotNet</RepositoryUrl>\n    <ContinuousIntegrationBuild Condition=\"'$(GITHUB_ACTIONS)' == 'true'\">true</ContinuousIntegrationBuild>\n\n    <CLSCompliant>true</CLSCompliant>\n    <ComVisible>false</ComVisible>\n\n    <UseSharedCompilation>false</UseSharedCompilation>\n    <EnableNETAnalyzers>true</EnableNETAnalyzers>\n    <SuppressNETCoreSdkPreviewMessage>True</SuppressNETCoreSdkPreviewMessage>\n    <CheckEolTargetFramework>false</CheckEolTargetFramework>\n    <CodeAnalysisRuleSet>$(MSBuildThisFileDirectory)CodingStyle.ruleset</CodeAnalysisRuleSet>\n    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>\n    <WarningsNotAsErrors>NU1900</WarningsNotAsErrors>\n    <Nullable>enable</Nullable>\n    <!-- Suppress warning for nuget package used in old (unsupported) tfm. -->\n    <SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>\n  </PropertyGroup>\n\n  <PropertyGroup>\n    <AssemblyOriginatorKeyFile>$(MSBuildThisFileDirectory)strongNameKey.snk</AssemblyOriginatorKeyFile>\n    <SignAssembly>true</SignAssembly>\n  </PropertyGroup>\n\n  <PropertyGroup Condition=\"'$(GenerateDocumentationFile)' == '' AND '$(Configuration)' == 'Release' \">\n    <GenerateDocumentationFile>true</GenerateDocumentationFile>\n  </PropertyGroup>\n\n  <PropertyGroup Condition=\"'$(MSBuildProjectExtension)' == '.csproj' \">\n    <LangVersion>14.0</LangVersion>\n  </PropertyGroup>\n\n  <PropertyGroup Condition=\" '$(VersionPrefix)' == '' \">\n    <!-- When this is changed, optionally reset WeaverVersionSuffix, then run `build.cmd pack-weaver`. -->\n    <VersionPrefix>0.16.0</VersionPrefix>\n  </PropertyGroup>\n\n  <PropertyGroup Condition=\" '$(NoVersionSuffix)' == '' AND '$(VersionSuffix)' == '' \">\n    <VersionSuffix>develop</VersionSuffix>\n    <VersionSuffix Condition=\" '$(BDN_CI_BUILD)' != '' \">ci</VersionSuffix>\n  </PropertyGroup>\n\n  <PropertyGroup>\n    <AssemblyVersion>$(VersionPrefix)</AssemblyVersion>\n    <AssemblyFileVersion>$(VersionPrefix)</AssemblyFileVersion>\n    <InformationalVersion>$(Version)</InformationalVersion>\n    <PackageVersion>$(Version)</PackageVersion>\n  </PropertyGroup>\n\n  <PropertyGroup>\n    <!-- Increment this when the BenchmarkDotNet.Weaver package needs to be re-packed. -->\n    <WeaverVersionSuffix>-3</WeaverVersionSuffix>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <GlobalPackageReference Include=\"Microsoft.NETFramework.ReferenceAssemblies\" Version=\"1.0.3\" />\n    <GlobalPackageReference Include=\"StyleCop.Analyzers.Unstable\" Version=\"1.2.0.556\" />\n  </ItemGroup>\n\n  <UsingTask TaskName=\"ReplaceFileText\"\n             TaskFactory=\"RoslynCodeTaskFactory\"\n             AssemblyFile=\"$(MSBuildToolsPath)\\Microsoft.Build.Tasks.Core.dll\">\n    <ParameterGroup>\n      <InputFilename ParameterType=\"System.String\" Required=\"true\" />\n      <OutputFilename ParameterType=\"System.String\" Required=\"true\" />\n      <MatchExpression ParameterType=\"System.String\" Required=\"true\" />\n      <ReplacementText ParameterType=\"System.String\" Required=\"true\" />\n    </ParameterGroup>\n    <Task>\n      <Using Namespace=\"System\" />\n      <Using Namespace=\"System.IO\" />\n      <Using Namespace=\"System.Text.RegularExpressions\" />\n      <Code Type=\"Fragment\" Language=\"cs\">\n        <![CDATA[\n            File.WriteAllText(\n                OutputFilename,\n                Regex.Replace(File.ReadAllText(InputFilename), MatchExpression, ReplacementText)\n                );\n          ]]>\n      </Code>\n    </Task>\n  </UsingTask>\n</Project>\n"
  },
  {
    "path": "build/common.targets",
    "content": "<Project>\n\n  <ItemGroup Condition=\"'$(IsPackable)' == 'true'\">\n    <None Include=\"$(MSBuildThisFileDirectory)package-icon.png\" Pack=\"True\" PackagePath=\"\"/>\n  </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "build/sdk/global.json",
    "content": "{\n  \"sdk\": {\n    \"version\": \"10.0.103\",\n    \"rollForward\": \"disable\"\n  }\n}\n"
  },
  {
    "path": "build/versions.txt",
    "content": "6eda98ab1e83a0d185d09ff8b24c795711af8db1\n0.7.0\n0.7.1\n0.7.2\n0.7.3\n0.7.4\n0.7.5\n0.7.6\n0.7.7\n0.7.8\n0.8.0\n0.8.1\n0.8.2\n0.9.0\n0.9.1\n0.9.2\n0.9.3\n0.9.4\n0.9.5\n0.9.6\n0.9.7\n0.9.8\n0.9.9\n0.10.0\n0.10.1\n0.10.2\n0.10.3\n0.10.4\n0.10.5\n0.10.6\n0.10.7\n0.10.8\n0.10.9\n0.10.10\n0.10.11\n0.10.12\n0.10.13\n0.10.14\n0.11.0\n0.11.1\n0.11.2\n0.11.3\n0.11.4\n0.11.5\n0.12.0\n0.12.1\n0.13.0\n0.13.1\n0.13.2\n0.13.3\n0.13.4\n0.13.5\n0.13.6\n0.13.7\n0.13.8\n0.13.9\n0.13.10\n0.13.11\n0.13.12\n0.14.0\n0.15.0\n0.15.1\n0.15.2\n0.15.3\n0.15.4\n0.15.5\n0.15.6\n0.15.7\n0.15.8\n0.16.0\n"
  },
  {
    "path": "build.cmd",
    "content": ":<<\"::CMDLITERAL\"\n@CALL build\\build.bat %*\n@GOTO :EOF\n::CMDLITERAL\n\"$(cd \"$(dirname \"$0\")\"; pwd)/build/build.sh\" \"$@\""
  },
  {
    "path": "docs/.gitignore",
    "content": "###############\n#    folder   #\n###############\n/**/DROP/\n/**/TEMP/\n/**/packages/\n/**/bin/\n/**/obj/\n_site\n_exported_templates\ndocfx-bin\napi/*\n!api/index.md\n/index.md\n_changelog\nchangelog\n\n# Autogenerated by `build.cmd docs-generate`\narticles/analyzers.md\n"
  },
  {
    "path": "docs/_redirects/_redirects",
    "content": "/Advancedfeatures.htm /articles/overview.html\n/HowItWorks.htm /Internals/HowItWorks.htm\n/RulesOfBenchmarking.htm /Guides/GoodPractices.htm\n/Overview.htm /articles/overview.html\n/Configs.htm /articles/configs/configs.html\n/HowToRun.htm /Guides/HowToRun.htm\n/index.htm /index.html\n/Contributing.htm /articles/contributing/building.html\n/Team.htm /articles/team.html\n/Internals.htm /articles/guides/how-it-works.html\n/Guides.htm /articles/guides/getting-started.html\n/FAQ.htm /articles/faq.html\n/NuGet.htm /Guides/NuGet.htm\n/license.htm /articles/license.html\n/GettingStarted.htm /Guides/GettingStarted.htm\n/Advanced/Baseline.htm /articles/features/baselines.html\n/Advanced/STAThread.htm /articles/samples/IntroStaThread.html\n/Advanced/EnvironmentVariables.htm /articles/samples/IntroEnvVars.html\n/Advanced/Params.htm /articles/features/parameterization.html\n/Advanced/CustomizingMono.htm /articles/guides/customizing-runtime.html\n/Advanced/CustomMonoPath.htm /articles/guides/customizing-runtime.html\n/Advanced/Arguments.htm /articles/features/parameterization.html\n/Advanced/Percentiles.htm /articles/features/statistics.html\n/Advanced/SetupAndCleanup.htm /articles/features/setup-and-cleanup.html\n/Contributing/Debugging.htm /articles/contributing/debugging.html\n/Contributing/Disassembler.htm /articles/contributing/disassembler.html\n/Contributing/RunningTests.htm /articles/contributing/running-tests.html\n/Contributing/Miscellaneous.htm /articles/contributing/miscellaneous.html\n/Contributing/Development.htm /articles/contributing/development.html\n/Contributing/Building.htm /articles/contributing/building.html\n/Internals/HowItWorks.htm /articles/guides/how-it-works.html\n/Guides/GoodPractices.htm /articles/guides/good-practices.html\n/Guides/HowToRun.htm /articles/guides/how-to-run.html\n/Guides/NuGet.htm /articles/guides/nuget.html\n/Guides/ChoosingRunStrategy.htm /articles/guides/choosing-run-strategy.html\n/Guides/GettingStarted.htm /articles/guides/getting-started.html\n/Configs/Columns.htm /articles/configs/columns.html\n/Configs/Configs.htm /articles/configs/configs.html\n/Configs/Diagnosers.htm /articles/configs/diagnosers.html\n/Configs/Exporters.htm /articles/configs/exporters.html\n/Configs/Filters.htm /articles/configs/filters.html\n/Configs/OrderProvider.htm /articles/configs/orderers.html\n/Configs/Analyzers.htm /articles/configs/analysers.html\n/Configs/Toolchains.htm /articles/configs/toolchains.html\n/Configs/Loggers.htm /articles/configs/loggers.html\n/Configs/Validators.htm /articles/configs/validators.html\n/Configs/Jobs.htm /articles/configs/jobs.html\n/articles/samples/IntroXamarin.html /articles/samples/IntroMaui.html\n"
  },
  {
    "path": "docs/api/index.md",
    "content": "﻿# BenchmarkDotNet API Reference"
  },
  {
    "path": "docs/articles/configs/analysers.md",
    "content": "---\nuid: docs.analysers\nname: Analysers\n---\n\n# Analysers\n\nAn **analyser** can analyse summary of your benchmarks and produce some useful warnings.\nFor example, `EnvironmentAnalyser` warns you, \nif you build your application in the DEBUG mode or run it with an attached debugger.\n"
  },
  {
    "path": "docs/articles/configs/columns.md",
    "content": "---\nuid: docs.columns\nname: Columns\n---\n\n# Columns\n\nA *column* is a column in the summary table.\n\n## Default columns\n\nIn this section, default columns (which be added to the Summary table by default) are presented.\nSome of columns are optional, i.e. they can be omitted (it depends on the measurements from the summary).\n\n### Target\n\nThere are 3 default columns which describes the target benchmark:\n  `Namespace`, `Type`, `Method`. `Namespace` and `Type` will be omitted\n  when all the benchmarks have the same namespace or type name.\n`Method` column always be a part of the summary table.\n\n### Job\n\nThere are many different job characteristics,\n  but the summary includes only characteristics which has at least one non-default value.\n\n### Statistics\n\nThere are also a lot of different statistics which can be considered.\nIt will be really hard to analyse the summary table, if all of the available statistics will be shown.\nFortunately, BenchmarkDotNet has some heuristics for statistics columns and shows only important columns.\nFor example, if all of the standard deviations are zero (we run our benchmarks against Dry job),\n  this column will be omitted.\nThe standard error will be shown only for cases when we are failed to achieve required accuracy level.\n\nOnly `Mean` will be always shown.\nIf the distribution looks strange,\n  BenchmarkDotNet could also print additional columns like `Median` or `P95` (95th percentile).\n\nIf you need specific statistics, you always could add them manually.\n\n### Params\n\nIf you have `params`, the corresponded columns will be automatically added.\n\n### Diagnosers\n\nIf you turned on diagnosers which providers additional columns, they will be also included in the summary page.\n\n## Custom columns\n\nOf course, you can define own custom columns and use it everywhere. Here is the definition of `TagColumn`:\n\n[!code-csharp[IntroTagColumn.cs](../../../src/BenchmarkDotNet/Columns/TagColumn.cs)]\n\n---\n\n[!include[IntroTagColumn](../samples/IntroTagColumn.md)]"
  },
  {
    "path": "docs/articles/configs/configoptions.md",
    "content": "---\n#cspell:ignore configoptions\nuid: docs.configoptions\nname: Configoptions\n---\n\n# Config Options\n\nThe config options let you customize some behavior of BenchmarkDotNet - mainly regarding the output.\nAvailable config options are:\n\n* `ConfigOptions.Default` - No configuration option is set - this is the default.\n* `ConfigOptions.KeepBenchmarkFiles` - All auto-generated files should be kept after running the benchmarks (by default they are removed).\n* `ConfigOptions.JoinSummary` - All benchmarks results should be joined into a single summary (by default we have a summary per type).\n* `ConfigOptions.StopOnFirstError` - Benchmarking should be stopped after the first error (by default it's not).\n* `ConfigOptions.DisableOptimizationsValidator` - Mandatory optimizations validator should be entirely turned off.\n* `ConfigOptions.DontOverwriteResults` - The exported result files should not be overwritten (by default they are overwritten).\n* `ConfigOptions.DisableLogFile` - Disables the log file written on disk.\n\nAll of these options could be combined and are available as CLI (Comand Line Interface) option (except `DisableOptimizationsValidator`), see [Console Arguments](xref:docs.console-args) for further information how to use the CLI.\n\nAny of these options could be used either in `object style config` or `fluent style config`:\n\n### Object style config\n\n```cs\npublic class Config : ManualConfig\n{\n    public Config()\n    {\n        // Using the WithOptions() factory method:\n        this.WithOptions(ConfigOptions.JoinSummary)\n            .WithOptions(ConfigOptions.DisableLogFile);\n        \n        // Or (The ConfigOptions Enum is defined as a BitField)\n        this.WithOptions(ConfigOptions.JoinSummary | ConfigOptions.DisableLogFile);\n\n    }\n}\n```\n\n### Fluent style config\n\n```cs\n    public static void Run()\n    {\n        BenchmarkRunner\n            .Run<Benchmarks>(\n                ManualConfig\n                    .Create(DefaultConfig.Instance)\n                    .WithOptions(ConfigOptions.JoinSummary)\n                    .WithOptions(ConfigOptions.DisableLogFile)\n                    // or\n                    .WithOptions(ConfigOptions.JoinSummary | ConfigOptions.DisableLogFile));\n    }\n```\n"
  },
  {
    "path": "docs/articles/configs/configs.md",
    "content": "---\nuid: docs.configs\nname: Configs\n---\n\n# Configs\n\nConfig is a set of so called `jobs`, `columns`, `exporters`, `loggers`, `diagnosers`, `analysers`, `validators`\n  that help you to build your benchmark. \n\n## Built-in configuration\n\nThere are two built-in ways to set your config:\n\n### Object style\n\n```cs\n[Config(typeof(Config))]\npublic class MyClassWithBenchmarks\n{\n    private class Config : ManualConfig\n    {\n        public Config()\n        {\n            AddJob(new Job1(), new Job2());\n            AddColumn(new Column1(), new Column2());\n            AddColumnProvider(new ColumnProvider1(), new ColumnProvider2());\n            AddExporter(new Exporter1(), new Exporter2());\n            AddLogger(new Logger1(), new Logger2());\n            AddDiagnoser(new Diagnoser1(), new Diagnoser2());\n            AddAnalyser(new Analyser1(), new Analyser2());\n            AddValidator(new Validator2(),new Validator2());\n            AddHardwareCounters(HardwareCounter enum1, HardwareCounter enum2);\n            AddFilter(new Filter1(), new Filter2());\n            AddLogicalGroupRules(BenchmarkLogicalGroupRule enum1, BenchmarkLogicalGroupRule enum2);\n        }\n    }\n    \n    [Benchmark]\n    public void Benchmark1()\n    {\n    }\n    \n    [Benchmark]\n    public void Benchmark2()\n    {\n    }\n}\n```\n\n\n---\n\n[!include[IntroConfigSource](../samples/IntroConfigSource.md)]\n\n[!include[IntroConfigUnion](../samples/IntroConfigUnion.md)]\n\n[!include[IntroFluentConfigBuilder](../samples/IntroFluentConfigBuilder.md)]"
  },
  {
    "path": "docs/articles/configs/diagnosers.md",
    "content": "---\nuid: docs.diagnosers\nname: Diagnosers\n---\n\n# Diagnosers\n\nA **diagnoser** can attach to your benchmark and get some useful info.\n\nThe current Diagnosers are:\n\n- GC and Memory Allocation (`MemoryDiagnoser`) which is cross platform, built-in and **is not enabled by default anymore**.\n  Please see Adam Sitnik's [blog post](https://adamsitnik.com/the-new-Memory-Diagnoser/) for all the details.\n- JIT Stats Diagnoser.\n  You can find this diagnoser in a separate package with diagnosers for Windows (`BenchmarkDotNet.Diagnostics.Windows`):\n  [![NuGet](https://img.shields.io/nuget/v/BenchmarkDotNet.svg)](https://www.nuget.org/packages/BenchmarkDotNet.Diagnostics.Windows/)\n- JIT Inlining Events (`InliningDiagnoser`).\n  You can find this diagnoser in a separate package with diagnosers for Windows (`BenchmarkDotNet.Diagnostics.Windows`):\n  [![NuGet](https://img.shields.io/nuget/v/BenchmarkDotNet.svg)](https://www.nuget.org/packages/BenchmarkDotNet.Diagnostics.Windows/)\n- JIT Tail Call Events (`TailCallDiagnoser`).\n  You can find this diagnoser as well as the (`InliningDiagnoser`) in a separate package with diagnosers for Windows (`BenchmarkDotNet.Diagnostics.Windows`):\n  [![NuGet](https://img.shields.io/nuget/v/BenchmarkDotNet.svg)](https://www.nuget.org/packages/BenchmarkDotNet.Diagnostics.Windows/) Please see [this post](https://georgeplotnikov.github.io/articles/tale-tail-call-dotnet) for all the details.\n- Hardware Counter Diagnoser.\n  You can find this diagnoser in a separate package with diagnosers for Windows (`BenchmarkDotNet.Diagnostics.Windows`):\n  [![NuGet](https://img.shields.io/nuget/v/BenchmarkDotNet.svg)](https://www.nuget.org/packages/BenchmarkDotNet.Diagnostics.Windows/).\n  Please see Adam Sitnik's [blog post](https://adamsitnik.com/Hardware-Counters-Diagnoser/) for all the details.\n- Disassembly Diagnoser.\n  It allows you to disassemble the benchmarked code to asm, IL and C#/F#.\n  Please see Adam Sitnik's [blog post](https://adamsitnik.com/Disassembly-Diagnoser/) for all the details.\n- ETW Profiler (`EtwProfiler`).\n  It allows you to not only benchmark, but also profile the code. It's using TraceEvent, which internally uses ETW and exports all the information to a trace file. The trace file contains all of the stack traces captured by the profiler, PDBs to resolve symbols for both native and managed code and captured GC, JIT and CLR events. Please use one of the free tools: PerfView or Windows Performance Analyzer to analyze and visualize the data from trace file. You can find this diagnoser in a separate package with diagnosers for Windows (`BenchmarkDotNet.Diagnostics.Windows`): [![NuGet](https://img.shields.io/nuget/v/BenchmarkDotNet.svg)](https://www.nuget.org/packages/BenchmarkDotNet.Diagnostics.Windows/)\n  Please see Adam Sitnik's [blog post](https://adamsitnik.com/ETW-Profiler/) for all the details.\n- Concurrency Visualizer Profiler (`ConcurrencyVisualizerProfiler`)\n  It uses `EtwProfiler` to profile the code using ETW and create not only `.etl` file but also a CVTrace file which can be opened by Concurrency Visualizer plugin from Visual Studio.\n  Please see Adam Sitnik's [blog post](https://adamsitnik.com/ConcurrencyVisualizer-Profiler/) for all the details.\n- Native Memory Profiler (`NativeMemoryProfiler`)\n  It uses `EtwProfiler` to profile the code using ETW and adds the extra columns `Allocated native memory` and `Native memory leak`.\n  Please see Wojciech Nagórski's [blog post](https://wojciechnagorski.github.io/2019/08/analyzing-native-memory-allocation-with-benchmarkdotnet/) for all the details.\n- Event Pipe Profiler (`EventPipeProfiler`).\n  It is a cross-platform profiler that allows profile .NET code on every platform - Windows, Linux, macOS.\n  Please see Wojciech Nagórski's [blog post](https://wojciechnagorski.github.io/2020/04/cross-platform-profiling-.net-code-with-benchmarkdotnet/) for all the details.\n- Threading Diagnoser (`ThreadingDiagnoser`) - .NET Core 3.0+ diagnoser that reports some Threading statistics.\n- Exception Diagnoser (`ExceptionDiagnoser`) - a diagnoser that reports the frequency of exceptions thrown during the operation.\n\n## Usage\n\nBelow is a sample output from the `GC and Memory Allocation` diagnoser, note the extra columns on the right-hand side (\"Gen 0\", \"Gen 1\", \"Gen 2\" and \"Allocated\"):\n\n```\n           Method |        Mean |     StdErr |      Median |  Gen 0 | Allocated |\n----------------- |------------ |----------- |------------ |------- |---------- |\n 'new byte[10kB]' | 884.4896 ns | 46.3528 ns | 776.4237 ns | 0.1183 |     10 kB |\n```\n\nA config example:\n\n```cs\nprivate class Config : ManualConfig\n{\n    public Config()\n    {\n        AddDiagnoser(MemoryDiagnoser.Default);\n        AddDiagnoser(new InliningDiagnoser());\n        AddDiagnoser(new EtwProfiler());\n        AddDiagnoser(ThreadingDiagnoser.Default);\n        AddDiagnoser(ExceptionDiagnoser.Default);\n    }\n}\n```\n\nYou can also use one of the following attributes (apply it on a class that contains Benchmarks):\n```cs\n[MemoryDiagnoser]\n[InliningDiagnoser]\n[TailCallDiagnoser]\n[EtwProfiler]\n[ConcurrencyVisualizerProfiler]\n[NativeMemoryProfiler]\n[ThreadingDiagnoser]\n[ExceptionDiagnoser]\n```\n\nIn BenchmarkDotNet, 1kB = 1024B, 1MB = 1024kB, and so on. The column Gen X means number of GC collections per 1000 operations for that generation.\n\n## Restrictions\n\n* In order to not affect main results we perform a separate run if any diagnoser is used. That's why it might take more time to execute benchmarks.\n* MemoryDiagnoser:\n\t* In order to get the number of allocated bytes in cross platform way we are using `GC.GetAllocatedBytesForCurrentThread` which recently got [exposed](https://github.com/dotnet/corefx/pull/12489) for netcoreapp1.1. That's why BenchmarkDotNet does not support netcoreapp1.0 from version 0.10.1.\n\t* MemoryDiagnoser is `99.5%` accurate about allocated memory when using default settings or Job.ShortRun (or any longer job than it).\n* Threading Diagnoser:\n    * Works only for .NET Core 3.0+\n* HardwareCounters:\n\t* Windows 8+ only (we plan to add Unix support in the future)\n    * No Hyper-V (Virtualization) support\n    * Requires running as Admin (ETW Kernel Session)\n    * No `InProcessToolchain` support ([#394](https://github.com/dotnet/BenchmarkDotNet/issues/394))\n* EtwProfiler, ConcurrencyVisualizerProfiler and NativeMemoryProfiler:\n    * Windows only\n    * Requires running as Admin (ETW Kernel Session)\n    * No `InProcessToolchain` support ([#394](https://github.com/dotnet/BenchmarkDotNet/issues/394))\n* Disassembly Diagnoser:\n    * .NET Core disassembler works only on Windows\n    * Mono disassembler does not support recursive disassembling and produces output without IL and C#.\n    * Indirect calls are not tracked.\n    * To be able to compare different platforms, you need to target AnyCPU `<PlatformTarget>AnyCPU</PlatformTarget>`\n    * To get the corresponding C#/F# code from disassembler you need to configure your project in following way:\n\n```xml\n<DebugType>pdbonly</DebugType>\n<DebugSymbols>true</DebugSymbols>\n```\n\n---\n\n[!include[IntroHardwareCounters](../samples/IntroHardwareCounters.md)]\n\n[!include[IntroDisassemblyRyuJit](../samples/IntroDisassemblyRyuJit.md)]\n\n[!include[IntroDisassembly](../samples/IntroDisassembly.md)]\n\n[!include[IntroDisassemblyAllJits](../samples/IntroDisassemblyAllJits.md)]\n\n[!include[IntroDisassemblyDry](../samples/IntroDisassemblyDry.md)]\n\n[!include[IntroTailcall](../samples/IntroTailcall.md)]\n\n[!include[IntroJitStatsDiagnoser](../samples/IntroJitStatsDiagnoser.md)]\n\n[!include[IntroNativeMemory](../samples/IntroNativeMemory.md)]\n\n[!include[IntroThreadingDiagnoser](../samples/IntroThreadingDiagnoser.md)]\n\n[!include[IntroExceptionDiagnoser](../samples/IntroExceptionDiagnoser.md)]\n"
  },
  {
    "path": "docs/articles/configs/exporters.md",
    "content": "---\nuid: docs.exporters\nname: Exporters\n---\n\n# Exporters\n\nAn *exporter* allows you to export results of your benchmark in different formats.\nBy default, files with results will be located in \n`.\\BenchmarkDotNet.Artifacts\\results` directory, but this can be changed via the `ArtifactsPath` property in the `IConfig`. \nDefault exporters are: csv, html and markdown.\n\n---\n\n[!include[IntroExport](../samples/IntroExport.md)]\n\n[!include[IntroExportJson](../samples/IntroExportJson.md)]\n\n[!include[IntroExportXml](../samples/IntroExportXml.md)]\n\n\n## Plots\n\n[You can install R](https://www.r-project.org/) to automatically get nice plots of your benchmark results.\nFirst, make sure `Rscript.exe` or `Rscript` is in your path,\n  or define an R_HOME environment variable pointing to the R installation directory.  \n_eg: If `Rscript` is located in `/path/to/R/R-1.2.3/bin/Rscript`, then `R_HOME` must point to `/path/to/R/R-1.2.3/`, it **should not** point to `/path/to/R/R-1.2.3/bin`_  \nUse `RPlotExporter.Default` and `CsvMeasurementsExporter.Default` in your config,\n  and the `BuildPlots.R` script in your bin directory will take care of the rest.\n\nExamples:\n\n```\n<BenchmarkName>-barplot.png\n<BenchmarkName>-boxplot.png\n<BenchmarkName>-<MethodName>-density.png\n<BenchmarkName>-<MethodName>-facetTimeline.png\n<BenchmarkName>-<MethodName>-facetTimelineSmooth.png\n<BenchmarkName>-<MethodName>-<JobName>-timelineSmooth.png\n<BenchmarkName>-<MethodName>-<JobName>-timelineSmooth.png\n```\n\nA config example in C#:\n\n```cs\npublic class Config : ManualConfig\n{\n    public Config()\n    {\n        Add(CsvMeasurementsExporter.Default);\n        Add(RPlotExporter.Default);\n    }\n}\n```\n\nA config example in F#:\n\n```fs\nmodule MyBenchmark\n\nopen BenchmarkDotNet.Attributes\nopen BenchmarkDotNet.Configs\nopen BenchmarkDotNet.Exporters\nopen BenchmarkDotNet.Exporters.Csv\nopen MyProjectUnderTest\n\ntype MyConfig() as this =\n    inherit ManualConfig()\n    do\n        this.Add(CsvMeasurementsExporter.Default)\n        this.Add(RPlotExporter.Default)\n\n[<\n  MemoryDiagnoser; \n  Config(typeof<MyConfig>);\n  RPlotExporter\n>]\ntype MyPerformanceTests() =\n\n    let someTestData = getTestDataAsList ()\n\n    [<Benchmark>]\n    member __.SomeTestCase() = \n        someTestData |> myFunctionUnderTest\n```\n\n## CSV\n\nThe CSV file format is often used to graph the output or to analyze the results programmatically. The CSV exporter may be configured to produce sanitized output, where cell values are numerals and their units are predefined.\n\nThe CSV exporter and other compatible exporters may consume an instance of `ISummaryStyle` that defines how the output should look like:\n\n| Property            | Remarks                                            | Default |\n| ------------------- | -------------------------------------------------- | ------- |\n| PrintUnitsInHeader  | If true, units will be displayed in the header row | false   |\n| PrintUnitsInContent | If true, units will be appended to the value       | true    |\n| TimeUnit            | If null, unit will be automatically selected       | null    |\n| SizeUnit            | If null, unit will be automatically selected       | null    |\n\nExample of CSV exporter configured to always use microseconds, kilobytes, and to render units only in column headers:\n\n```cs\nvar exporter = new CsvExporter(\n    CsvSeparator.CurrentCulture,\n    new SummaryStyle(\n        cultureInfo: System.Globalization.CultureInfo.CurrentCulture,\n        printUnitsInHeader: true,\n        printUnitsInContent: false,\n        timeUnit: Perfolizer.Horology.TimeUnit.Microsecond,\n        sizeUnit: SizeUnit.KB\n    ));\n\nvar config = ManualConfig.CreateMinimumViable().AddExporter(exporter);\n```\n\nExcerpt from the resulting CSV file:\n\n```\nMethod,...,Mean [us],Error [us],StdDev [us],Min [us],Max [us],Allocated [KB]\nBenchmark,...,\"37,647.6\",\"32,717.9\",\"21,640.9\",\"11,209.2\",\"59,492.6\",1.58\n```\n"
  },
  {
    "path": "docs/articles/configs/filters.md",
    "content": "---\nuid: docs.filters\nname: Filters\n---\n\n# Filters\n\nSometimes you don't want to run all of your benchmarks.\nIn this case, you can *filter* some of them with the help of *filters*.\n\nPredefined filters:\n\n| Filter Type         | Filters benchmarks by       | Console argument   | Console example                  |\n|---------------------|-----------------------------|--------------------|----------------------------------|\n| GlobFilter          | Provided glob pattern       | `filter`           | --filter *Serializer*.ToStream   |\n| AttributesFilter    | Provided attribute names    | `attribute`        | --attribute STAThread            |\n| AllCategoriesFilter | All Provided category names | `categories`       | --allCategories Priority1 CoreFX |\n| AnyCategoriesFilter | Any provided category names | `anycategories`    | --anyCategories Json Xml         |\n| SimpleFilter        | Provided lambda predicate   | -                  |                                  |\n| NameFilter          | Provided lambda predicate   | -                  |                                  |\n| UnionFilter         | Logical AND                 | -                  |                                  |\n| DisjunctionFilter   | Logical OR                  | -                  |                                  |\n\n---\n\n[!include[IntroFilters](../samples/IntroFilters.md)]\n\n[!include[IntroCategories](../samples/IntroCategories.md)]\n\n[!include[IntroJoin](../samples/IntroJoin.md)]\n"
  },
  {
    "path": "docs/articles/configs/jobs.md",
    "content": "---\nuid: docs.jobs\nname: Jobs\n---\n\n# Jobs\n\nBasically, a *job* describes how to run your benchmark. Practically, it's a set of characteristics which can be specified. You can specify one or several jobs for your benchmarks.\n\n## Characteristics\n\nThere are several categories of characteristics which you can specify. Let's consider each category in detail.\n\n### Id\n\nIt's a single string characteristic. It allows to name your job. This name will be used in logs and a part of a folder name with generated files for this job. `Id` doesn't affect benchmark results, but it can be useful for diagnostics. If you don't specify `Id`, random value will be chosen based on other characteristics\n\n### Environment\n\n`Environment` specifies an environment of the job. You can specify the following characteristics:\n\n* `Platform`: `x86` or `x64`\n* `Runtime`:\n  * `Clr`: Full .NET Framework (available only on Windows)\n  * `Core`: CoreCLR (x-plat)\n  * `Mono`: Mono (x-plat)\n* `Jit`:\n  * `LegacyJit` (available only for `Runtime.Clr`)\n  * `RyuJit` (available only for `Runtime.Clr` and `Runtime.Core`)\n  * `Llvm` (available only for `Runtime.Mono`)\n* `Affinity`: [Affinity](https://msdn.microsoft.com/library/system.diagnostics.process.processoraffinity.aspx) of a benchmark process\n* `GcMode`: settings of Garbage Collector\n  * `Server`: `true` (Server mode) or `false` (Workstation mode)\n  * `Concurrent`:  `true` (Concurrent mode) or `false` (NonConcurrent mode)\n  * `CpuGroups`:  Specifies whether garbage collection supports multiple CPU groups\n  * `Force`: Specifies whether the BenchmarkDotNet's benchmark runner forces full garbage collection after each benchmark invocation\n  * `AllowVeryLargeObjects`:  On 64-bit platforms, enables arrays that are greater than 2 gigabytes (GB) in total size\n* `LargeAddressAware`: Specifies that benchmark can handle addresses larger than 2 gigabytes. See also: @BenchmarkDotNet.Samples.IntroLargeAddressAware and [`LARGEADDRESSAWARE`](https://learn.microsoft.com/cpp/build/reference/largeaddressaware-handle-large-addresses)\n  * `false`: Benchmark uses the defaults (64-bit: enabled; 32-bit: disabled).\n  * `true`: Explicitly specify that benchmark can handle addresses larger than 2 gigabytes.\n* `EnvironmentVariables`: customized environment variables for target benchmark. See also: @BenchmarkDotNet.Samples.IntroEnvVars\n\nBenchmarkDotNet will use host process environment characteristics for non specified values.\n\n### Run\n\nIn this category, you can specify how to benchmark each method.\n\n* `RunStrategy`:\n  * `Throughput`: default strategy which allows to get good precision level\n  * `ColdStart`: should be used only for measuring cold start of the application or testing purpose\n  * `Monitoring`: A mode without overhead evaluating, with several target iterations\n* `LaunchCount`: how many times we should launch process with target benchmark\n* `WarmupCount`: how many warmup iterations should be performed\n* `IterationCount`: how many target iterations should be performed (if specified, `BenchmarkDotNet.Jobs.RunMode.MinIterationCount` and `BenchmarkDotNet.Jobs.RunMode.MaxIterationCount` will be ignored)\n* `IterationTime`: desired time of a single iteration\n* `UnrollFactor`: how many times the benchmark method will be invoked per one iteration of a generated loop\n* `InvocationCount`: count of invocation in a single iteration (if specified, `IterationTime` will be ignored), must be a multiple of `UnrollFactor`\n* `MinIterationCount`: Minimum count of target iterations that should be performed, the default value is 15\n* `MaxIterationCount`: Maximum count of target iterations that should be performed, the default value is 100\n* `MinWarmupIterationCount`: Minimum count of warmup iterations that should be performed, the default value is 6\n* `MaxWarmupIterationCount`: Maximum count of warmup iterations that should be performed, the default value is 50\n\nUsually, you shouldn't specify such characteristics like `LaunchCount`, `WarmupCount`, `IterationCount`, or `IterationTime` because BenchmarkDotNet has a smart algorithm to choose these values automatically based on received measurements. You can specify it for testing purposes or when you are damn sure that you know the right characteristics for your benchmark (when you set `IterationCount` = `20` you should understand why `20` is a good value for your case).\n\n### Accuracy\n\nIf you want to change the accuracy level, you should use the following characteristics instead of manually adjusting values of `WarmupCount`, `IterationCount`, and so on.\n\n* `MaxRelativeError`, `MaxAbsoluteError`: Maximum acceptable error for a benchmark (by default, BenchmarkDotNet continue iterations until the actual error is less than the specified error). *In these two characteristics*, the error means half of 99.9% confidence interval. `MaxAbsoluteError` is an absolute `TimeInterval`; doesn't have a default value. `MaxRelativeError` defines max acceptable (`(<half of CI 99.9%>) / Mean`).\n* `MinIterationTime`: Minimum time of a single iteration. Unlike `Run.IterationTime`, this characteristic specifies only the lower limit. In case of need, BenchmarkDotNet can increase this value.\n* `MinInvokeCount`:  Minimum about of target method invocation. Default value if `4` but you can decrease this value for cases when single invocations takes a lot of time.\n* `EvaluateOverhead`: if your benchmark method takes nanoseconds, BenchmarkDotNet overhead can significantly affect measurements. If this characteristic is enabled, the overhead will be evaluated and subtracted from the result measurements. Default value is `true`.\n* `WithOutlierMode`: sometimes you could have outliers in your measurements. Usually these are unexpected outliers which arose because of other processes activities. By default (`OutlierMode.RemoveUpper`), all upper outliers (which is larger than Q3) will be removed from the result measurements. However, some of benchmarks have *expected* outliers. In these situation, you expect that some of invocation can produce outliers measurements (e.g. in case of network activities, cache operations, and so on). If you want to see result statistics with these outliers, you should use `OutlierMode.DontRemove`. If you can also choose `OutlierMode.RemoveLower` (outliers which are smaller than Q1 will be removed) or `OutlierMode.RemoveAll` (all outliers will be removed). See also: @BenchmarkDotNet.Mathematics.OutlierMode\n* `AnalyzeLaunchVariance`: this characteristic makes sense only if `Run.LaunchCount` is default. If this mode is enabled and, BenchmarkDotNet will try to perform several launches and detect if there is a variance between launches. If this mode is disable, only one launch will be performed.\n\n### Infrastructure\n\nUsually, you shouldn't specify any characteristics from this section, it can be used for advanced cases only.\n\n* `Toolchain`: a toolchain which generates source code for target benchmark methods, builds it, and executes it. BenchmarkDotNet has own toolchains for .NET, .NET Core, Mono and CoreRT projects. If you want, you can define own toolchain.\n* `Clock`: a clock which will be used for measurements. BenchmarkDotNet automatically choose the best available clock source, but you can specify own clock source.\n* `EngineFactory`: a provider for measurement engine which performs all the measurement magic. If you don't trust BenchmarkDotNet, you can define own engine and implement all the measurement stages manually.\n\n## Usage\n\nThere are several ways to specify a job.\n\n### Object style\n\nYou can create own jobs directly from the source code via a custom config:\n\n```cs\n[Config(typeof(Config))]\npublic class MyBenchmarks\n{\n    private class Config : ManualConfig\n    {\n        public Config()\n        {\n            AddJob(\n                new Job(\"MySuperJob\", RunMode.Dry, EnvironmentMode.RyuJitX64)\n                {\n                    Environment = { Runtime = CoreRuntime.Core90 },\n                    Run = { LaunchCount = 5, IterationTime = TimeInterval.Millisecond * 200 },\n                    Accuracy = { MaxRelativeError = 0.01 }\n                });\n\n            // The same, using the .With() factory methods:\n            AddJob(\n                Job.Dry\n                .WithPlatform(Platform.X64)\n                .WithJit(Jit.RyuJit)\n                .WithRuntime(CoreRuntime.Core90)\n                .WithLaunchCount(5)\n                .WithIterationTime(TimeInterval.Millisecond * 200)\n                .WithMaxRelativeError(0.01)\n                .WithId(\"MySuperJob\"));\n        }\n    }\n    // Benchmarks\n}\n```\n\nBasically, it's a good idea to start with predefined values (e.g. `EnvironmentMode.RyuJitX64` and `RunMode.Dry` passed as constructor args) and modify rest of the properties using property setters or with help of object initializer syntax.\n\nNote that the job cannot be modified after it's added into config. Trying to set a value on property of the frozen job will throw an `InvalidOperationException`. Use the `Job.Frozen` property to determine if the code properties can be altered.\n\nIf you do want to create a new job based on frozen one (all predefined job values are frozen) you can use the `.With()` extension method\n\n```cs\n            var newJob = Job.Dry.WithPlatform(Platform.X64);\n```\n\nor pass the frozen value as a constructor argument\n\n```c#\n            var newJob = new Job(Job.Dry) { Environment = { Platform = Platform.X64 } };\n```\n\nor use the `.Apply()` method on unfrozen job\n\n```c#\n            var newJob = new Job() { Environment = { Platform = Platform.X64 } }.Apply(Job.Dry);\n```\n\nin any case the Id property will not be transfered and you must pass it explicitly (using the .ctor id argument or the `.WithId()` extension method).\n\n### Attribute style\n\nYou can also add new jobs via attributes. Examples:\n\n```cs\n[DryJob]\n[MonoJob]\n[SimpleJob(RuntimeMoniker.Net90)]\n[SimpleJob(RuntimeMoniker.NetCoreApp31)]\n[LegacyJitX86Job, LegacyJitX64Job, RyuJitX64Job]\n[SimpleJob(RunStrategy.ColdStart, launchCount: 1, warmupCount: 5, iterationCount: 5, id: \"FastAndDirtyJob\")]\npublic class MyBenchmarkClass\n```\n\nNote that each of the attributes identifies a separate job, the sample above will result in 8 different jobs, not a single merged job.\n\n### Attribute style for merging jobs\n\nSometimes you want to apply some changes to other jobs, without adding a new job to a config (which results in one extra benchmark run).\n\nTo do that you can use following predefined job mutator attributes:\n\n* `[EvaluateOverhead]`\n* `[GcConcurrent]`\n* `[GcForce]`\n* `[GcServer]`\n* `[InnerIterationCount]`\n* `[InvocationCount]`\n* `[IterationCount]`\n* `[IterationTime]`\n* `[MaxAbsoluteError]`\n* `[MaxIterationCount]`\n* `[MaxRelativeError]`\n* `[MinInvokeCount]`\n* `[MinIterationCount]`\n* `[MinIterationTime]`\n* `[Outliers]`\n* `[ProcessCount]`\n* `[RunOncePerIteration]`\n* `[WarmupCount]`\n* `[MinWarmupCount]`\n* `[MaxWarmupCount]`\n\nSo following example:\n\n```cs\n[ClrJob, CoreJob]\n[GcServer(true)]\npublic class MyBenchmarkClass\n```\n\nIs going to be merged to a config with two jobs:\n\n* CoreJob with `GcServer=true`\n* ClrJob with `GcServer=true`\n\n#### Custom attributes\n\nYou can also create your own custom attributes with your favourite set of jobs. Example:\n\n```cs\n[AttributeUsage(AttributeTargets.Class | AttributeTargets.Assembly)]\npublic class MySuperJobAttribute : Attribute, IConfigSource\n{\n    protected MySuperJobAttribute()\n    {\n        var job = new Job(\"MySuperJob\", RunMode.Core);\n        job.Env.Platform = Platform.X64;\n        Config = ManualConfig.CreateEmpty().AddJob(job);\n    }\n\n    public IConfig Config { get; }\n}\n\n[MySuperJob]\npublic class MyBenchmarks\n```\n\n---\n\n[!include[IntroGcMode](../samples/IntroGcMode.md)]\n"
  },
  {
    "path": "docs/articles/configs/loggers.md",
    "content": "---\nuid: docs.loggers\nname: Loggers\n---\n\n# Loggers\n\nA **logger** allows you to log results of your benchmark. By default, you can see log on console and in a file (`<BenchmarkName>.log`).\n\n"
  },
  {
    "path": "docs/articles/configs/orderers.md",
    "content": "---\nuid: docs.orderers\nname: Orderers\n---\n\n# Orderers\n\nOrderers allows customizing the order of benchmark results in the summary table.\n\nThe following built-in order policies are available.\n- <xref:BenchmarkDotNet.Order.SummaryOrderPolicy>\n- <xref:BenchmarkDotNet.Order.MethodOrderPolicy>\n- <xref:BenchmarkDotNet.Order.JobOrderPolicy>\n\nYou can also use a custom orderer by implementing the <xref:BenchmarkDotNet.Order.IOrderer> interface.\n\n---\n\n[!include[IntroOrderAttr](../samples/IntroOrderAttr.md)]\n\n[!include[IntroOrderManual](../samples/IntroOrderManual.md)]"
  },
  {
    "path": "docs/articles/configs/powerplans.md",
    "content": "---\nuid: docs.powerplans\nname: Power Plans\n---\n\n# Power Plans\n\nBenchmarkDotNet forces Windows OS to execute on the High-Performance power plan. You can disable this feature by modify PowerPlanMode property. You can see it in the @BenchmarkDotNet.Samples.IntroPowerPlan.\n\nPlease note. During an execution, BenchmarkDotNet saves the current power plan and applies it according to the PowerPlanMode property. When all of the benchmarks finish, a previous power plan comes back. However, if someone killed process or energy was plugged off, we could stay with the High-Performance power plan. In this situation, we should return it manually in Windows Control Panel or by powercfg command. \n\n### Links\n\n* Power policy settings: https://learn.microsoft.com/windows/win32/power/power-policy-settings\n* Powercfg command: https://learn.microsoft.com/windows-hardware/design/device-experiences/powercfg-command-line-options\n* @BenchmarkDotNet.Samples.IntroPowerPlan\n\n---"
  },
  {
    "path": "docs/articles/configs/toc.yml",
    "content": "- name: Configs\n  href: configs.md\n- name: Jobs\n  href: jobs.md\n- name: Columns\n  href: columns.md\n- name: Exporters\n  href: exporters.md\n- name: Loggers\n  href: loggers.md\n- name: Diagnosers\n  href: diagnosers.md\n- name: Toolchains\n  href: toolchains.md\n- name: Analysers\n  href: analysers.md\n- name: Validators\n  href: validators.md\n- name: Filters\n  href: filters.md\n- name: Orderers\n  href: orderers.md\n- name: ConfigOptions\n  href: configoptions.md"
  },
  {
    "path": "docs/articles/configs/toolchains.md",
    "content": "---\nuid: docs.toolchains\nname: Toolchains\n---\n\n# Toolchains\n\nTo achieve process-level isolation, BenchmarkDotNet generates, builds and executes a new console app per every benchmark. A **toolchain** contains generator, builder, and executor.\n\nWhen you run your benchmarks without specifying the toolchain in an explicit way, the default one is used:\n\n* Roslyn for Full .NET Framework and Mono\n* dotnet cli for .NET Core and NativeAOT\n\n## Multiple frameworks support\n\n\nIf you want to test multiple frameworks, your project file **MUST target all of them** and you **MUST install the corresponding SDKs**:\n\n```xml\n<TargetFrameworks>netcoreapp3.1;net8.0;net48</TargetFrameworks>\n```\n\nIf you run your benchmarks without specifying any custom settings, BenchmarkDotNet is going to run the benchmarks **using the same framework as the host process**:\n\n```cmd\ndotnet run -c Release -f netcoreapp3.1 # is going to run the benchmarks using .NET Core 3.1\ndotnet run -c Release -f net8.0 # is going to run the benchmarks using .NET 8.0\ndotnet run -c Release -f net48         # is going to run the benchmarks using .NET 4.8\nmono $pathToExe                        # is going to run the benchmarks using Mono from your PATH\n```\n\nTo run the benchmarks for multiple runtimes with a single command, you need to specify the target framework moniker names via `--runtimes|-r` console argument:\n\n```cmd\ndotnet run -c Release -f net8.0 --runtimes net8.0 netcoreapp3.1 # is going to run the benchmarks using .NET 8.0 and .NET Core 3.1\ndotnet run -c Release -f net8.0 --runtimes net8.0 net48         # is going to run the benchmarks using .NET 8.0 and .NET 4.8\n```\n\nWhat is going to happen if you provide multiple Full .NET Framework monikers? Let's say:\n\n```cmd\ndotnet run -c Release -f net461 net472 net48\n```\n\nFull .NET Framework always runs every .NET executable using the latest .NET Framework available on a given machine. If you try to run the benchmarks for a few .NET TFMs, they are all going to be executed using the latest .NET Framework from your machine. The only difference is that they are all going to have different features enabled depending on target version they were compiled for. You can read more about this [here](https://docs.microsoft.com/en-us/dotnet/framework/migration-guide/version-compatibility) and [here](https://docs.microsoft.com/en-us/dotnet/framework/migration-guide/application-compatibility). This is **.NET Framework behavior which can not be controlled by BenchmarkDotNet or any other tool**.\n\n**Note:** Console arguments support works only if you pass the `args` to `BenchmarkSwitcher`:\n\n```cs\nclass Program\n{\n    static void Main(string[] args) \n        => BenchmarkSwitcher\n            .FromAssembly(typeof(Program).Assembly)\n            .Run(args); // crucial to make it work\n}\n```\n\nYou can achieve the same thing using `[SimpleJobAttribute]`:\n\n```cs\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Jobs;\n\nnamespace BenchmarkDotNet.Samples\n{\n    [SimpleJob(RuntimeMoniker.Net48)]\n    [SimpleJob(RuntimeMoniker.Mono)]\n    [SimpleJob(RuntimeMoniker.NetCoreApp31)]\n    [SimpleJob(RuntimeMoniker.Net80)]\n    public class TheClassWithBenchmarks\n```\n\nOr using a custom config:\n\n```cs\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Running;\n\nnamespace BenchmarkDotNet.Samples\n{\n    class Program\n    {\n        static void Main(string[] args)\n        {\n            var config = DefaultConfig.Instance\n                .AddJob(Job.Default.WithRuntime(CoreRuntime.Core80))\n                .AddJob(Job.Default.WithRuntime(ClrRuntime.Net48))\n                .AddJob(Job.Default.WithRuntime(MonoRuntime.Default));\n\n            BenchmarkSwitcher\n                .FromAssembly(typeof(Program).Assembly)\n                .Run(args, config);\n        }\n    }\n}\n```\n\nThe recommended way of running the benchmarks for multiple runtimes is to use the `--runtimes` console line argument. By using the console line argument you don't need to edit the source code anytime you want to change the list of runtimes. Moreover, if you share the source code of the benchmark other people can run it even if they don't have the exact same framework version installed.\n\n\n## Custom .NET Core Runtime\n\nWe can run your benchmarks for custom `<RuntimeFrameworkVersion>` if you want. All you need to do is to create custom toolchain by calling `CsProjCoreToolchain.From` method, which accepts `NetCoreAppSettings`.\n\n```cs\npublic class MyConfig : ManualConfig\n{\n    public MyConfig()\n    {\n        Add(Job.Default.With(\n            CsProjCoreToolchain.From(\n                new NetCoreAppSettings(\n                    targetFrameworkMoniker: \"net8.0-windows\",\n                    runtimeFrameworkVersion: \"8.0.101\",\n                    name: \".NET 8.0 Windows\"))));\n    }\n}\n```\n\n## Custom .NET Runtime\n\nIt's possible to benchmark a private build of .NET Runtime. All you need to do is to define a job with the right version of `ClrRuntime`.\n\n```cs\nBenchmarkSwitcher\n    .FromAssembly(typeof(Program).Assembly)\n    .Run(args, \n        DefaultConfig.Instance.AddJob(\n            Job.ShortRun.WithRuntime(ClrRuntime.CreateForLocalFullNetFrameworkBuild(version: \"4.0\"))));\n```\n\nThis sends the provided version as a `COMPLUS_Version` env var to the benchmarked process.\n\n## Custom dotnet cli path\n\nWe internally use dotnet cli to build and run .NET Core executables. Sometimes it might be mandatory to use non-default dotnet cli path. An example scenario could be a comparison of RyuJit 32bit vs 64 bit. It required due this [limitation](https://github.com/dotnet/cli/issues/7532) of dotnet cli\n\n```cs\npublic class CustomPathsConfig : ManualConfig\n{\n    public CustomPathsConfig() \n    {\n        var dotnetCli32bit = NetCoreAppSettings\n            .NetCoreApp31\n            .WithCustomDotNetCliPath(@\"C:\\Program Files (x86)\\dotnet\\dotnet.exe\", \"32 bit cli\");\n\n        var dotnetCli64bit = NetCoreAppSettings\n            .NetCoreApp31\n            .WithCustomDotNetCliPath(@\"C:\\Program Files\\dotnet\\dotnet.exe\", \"64 bit cli\");\n\n        AddJob(Job.RyuJitX86.WithToolchain(CsProjCoreToolchain.From(dotnetCli32bit)).WithId(\"32 bit cli\"));\n        AddJob(Job.RyuJitX64.WithToolchain(CsProjCoreToolchain.From(dotnetCli64bit)).WithId(\"64 bit cli\"));\n    }\n}\n```\n\n``` ini\nBenchmarkDotNet=v0.10.9.20170910-develop, OS=Windows 10 Redstone 1 (10.0.14393)\nProcessor=Intel Core i7-6600U CPU 2.60GHz (Skylake), ProcessorCount=4\nFrequency=2742185 Hz, Resolution=364.6727 ns, Timer=TSC\n.NET Core SDK=2.1.0-preview1-007074\n  [Host]     : .NET Core 2.0.0 (Framework 4.6.00001.0), 64bit RyuJIT\n  32 bit cli : .NET Core 2.0.0 (Framework 4.6.00001.0), 32bit RyuJIT\n  64 bit cli : .NET Core 2.0.0 (Framework 4.6.00001.0), 64bit RyuJIT\n\nJit=RyuJit  \n```\n\nThis feature is now also exposed with the `--cli` console argument.\n\nExample: `dotnet run -c Release -- --cli \"C:\\Projects\\machinelearning\\Tools\\dotnetcli\\dotnet.exe\"`\n\n## CoreRun\n\nTo use CoreRun for running the benchmarks you need to use `--coreRun `command line argument. You can combine it with `--cli` described above. This is most probably the easiest and most reliable way of running benchmarks against local CoreFX/CoreCLR builds.\n\nExample: `dotnet run -c Release -- --coreRun \"C:\\Projects\\corefx\\bin\\testhost\\netcoreapp-Windows_NT-Release-x64\\shared\\Microsoft.NETCore.App\\9.9.9\\CoreRun.exe\"`\n\n---\n\n[!include[IntroInProcess](../samples/IntroInProcess.md)]\n\n[!include[IntroInProcessWrongEnv](../samples/IntroInProcessWrongEnv.md)]\n\n\n## NativeAOT\n\nBenchmarkDotNet supports [NativeAOT](https://github.com/dotnet/runtime/tree/main/src/coreclr/nativeaot)! However, you might want to know how it works to get a better understanding of the results that you get.\n\nAs every AOT solution, NativeAOT has some [limitations](https://github.com/dotnet/runtime/blob/main/src/coreclr/nativeaot/docs/limitations.md) like limited reflection support or lack of dynamic assembly loading. Because of that, the host process (what you run from command line) is never an AOT process, but just a regular .NET process. This process (called Host process) uses reflection to read benchmarks metadata (find all `[Benchmark]` methods etc), generates a new project that references the benchmarks and compiles it using ILCompiler. Such compilation produces a native executable, which is later started by the Host process. This process (called Benchmark or Child process) performs the actual benchmarking and reports the results back to the Host process. By default BenchmarkDotNet uses the latest version of `Microsoft.DotNet.ILCompiler` to build the NativeAOT benchmark according to [this instructions](https://github.com/dotnet/runtime/blob/main/src/coreclr/nativeaot/docs/compiling.md).\n\nThis is why you need to:\n- install [pre-requisites](https://docs.microsoft.com/en-us/dotnet/core/deploying/native-aot/#prerequisites) required by NativeAOT compiler\n- target .NET to be able to run NativeAOT benchmarks (example: `<TargetFramework>net7.0</TargetFramework>` in the .csproj file)\n- run the app as a .NET process (example: `dotnet run -c Release -f net7.0`).\n- specify the NativeAOT runtime in an explicit way, either by using console line arguments `--runtimes nativeaot7.0` (the recommended approach), or by using`[SimpleJob]` attribute or by using the fluent Job config API `Job.ShortRun.With(NativeAotRuntime.Net70)`:\n\n```cmd\ndotnet run -c Release -f net7.0 --runtimes nativeaot7.0\n```\n\nor:\n\n```cs\nvar config = DefaultConfig.Instance\n    .AddJob(Job.Default.WithRuntime(NativeAotRuntime.Net70)); // compiles the benchmarks as net7.0 and uses the latest NativeAOT to build a native app\n\nBenchmarkSwitcher\n    .FromAssembly(typeof(Program).Assembly)\n    .Run(args, config);\n```\n\nor:\n\n```cs\n[SimpleJob(RuntimeMoniker.NativeAot70)] // compiles the benchmarks as net7.0 and uses the latest NativeAOT to build a native app\npublic class TheTypeWithBenchmarks\n{\n   [Benchmark] // the benchmarks go here\n}\n```\n\n### Customization\n\nIf you want to benchmark some particular version of NativeAOT (or from a different NuGet feed) you have to specify it in an explicit way:\n\n```cs\nvar config = DefaultConfig.Instance\n    .AddJob(Job.ShortRun\n        .WithToolchain(NativeAotToolchain.CreateBuilder()\n            .UseNuGet(\n                microsoftDotNetILCompilerVersion: \"7.0.0-*\", // the version goes here\n                nuGetFeedUrl: \"https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet7/nuget/v3/index.json\") // this address might change over time\n            .DisplayName(\"NativeAOT NuGet\")\n            .TargetFrameworkMoniker(\"net7.0\")\n            .ToToolchain()));\n```\n\nThe builder allows to configure more settings:\n- specify packages restore path by using `PackagesRestorePath($path)`\n- rooting all application assemblies by using `RootAllApplicationAssemblies($bool)`. This is disabled by default.\n- generating stack trace metadata by using `IlcGenerateStackTraceData($bool)`. This option is enabled by default.\n- set optimization preference by using `IlcOptimizationPreference($value)`. The default is `Speed`, you can configure it to `Size` or nothing\n- set instruction set for the target OS, architecture and hardware by using `IlcInstructionSet($value)`. By default BDN recognizes most of the instruction sets on your machine and enables them.\n\nBenchmarkDotNet supports [rd.xml](https://github.com/dotnet/runtime/blob/main/src/coreclr/nativeaot/docs/rd-xml-format.md) files. To get given file respected by BenchmarkDotNet you need to place it in the same folder as the project that defines benchmarks and name it `rd.xml` or in case of multiple files give them `.rd.xml` extension. The alternative to `rd.xml` files is annotating types with [DynamicallyAccessedMembers](https://devblogs.microsoft.com/dotnet/app-trimming-in-net-5/) attribute.\n\nIf given benchmark is not supported by NativeAOT, you need to apply `[AotFilter]` attribute for it. Example:\n\n```cs\n[Benchmark]\n[AotFilter(\"Not supported by design.\")]\npublic object CreateInstanceNames() => System.Activator.CreateInstance(_assemblyName, _typeName);\n```\n\n### Generated files\n\nBy default BenchmarkDotNet removes the generates files after finishing the run. To keep them on the disk  you need to pass `--keepFiles true` command line argument or apply `[KeepBenchmarkFiles]` attribute to the class which defines benchmark(s). Then, read the folder from the tool output. In the example below it's `D:\\projects\\performance\\artifacts\\bin\\MicroBenchmarks\\Release\\net7.0\\Job-KRLVKQ`:\n\n```log\n// ***** Building 1 exe(s) in Parallel: Start   *****\n// start dotnet  restore -r win-x64 /p:UseSharedCompilation=false /p:BuildInParallel=false /m:1 /p:Deterministic=true /p:Optimize=true in D:\\projects\\performance\\artifacts\\bin\\MicroBenchmarks\\Release\\net7.0\\Job-KRLVKQ\n// command took 2.74s and exited with 0\n// start dotnet  build -c Release -r win-x64 --no-restore /p:UseSharedCompilation=false /p:BuildInParallel=false /m:1 /p:Deterministic=true /p:Optimize=true in D:\\projects\\performance\\artifacts\\bin\\MicroBenchmarks\\Release\\net7.0\\Job-KRLVKQ\n// command took 3.82s and exited with 0\n```\n\nIf you go to `D:\\projects\\performance\\artifacts\\bin\\MicroBenchmarks\\Release\\net7.0\\Job-KRLVKQ`, you can see the generated project file (named `BenchmarkDotNet.Autogenerated.csproj`), code (file name ends with `.notcs`) and find the native executable (in the `bin\\**\\native` subfolder). Example:\n\n```cmd\ncd D:\\projects\\performance\\artifacts\\bin\\MicroBenchmarks\\Release\\net7.0\\Job-KRLVKQ\ncat .\\BenchmarkDotNet.Autogenerated.csproj\n```\n\n```log\n<Project Sdk=\"Microsoft.NET.Sdk\">\n  <PropertyGroup>\n    <ImportDirectoryBuildProps>false</ImportDirectoryBuildProps>\n    <ImportDirectoryBuildTargets>false</ImportDirectoryBuildTargets>\n    <OutputType>Exe</OutputType>\n    <TargetFramework>net7.0</TargetFramework>\n    <RuntimeIdentifier>win-x64</RuntimeIdentifier>\n    <RuntimeFrameworkVersion></RuntimeFrameworkVersion>\n    <AssemblyName>Job-KRLVKQ</AssemblyName>\n    <AssemblyTitle>Job-KRLVKQ</AssemblyTitle>\n    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>\n    <PlatformTarget>x64</PlatformTarget>\n    <TreatWarningsAsErrors>False</TreatWarningsAsErrors>\n    <DebugSymbols>false</DebugSymbols>\n    <UseSharedCompilation>false</UseSharedCompilation>\n    <Deterministic>true</Deterministic>\n    <RunAnalyzers>false</RunAnalyzers>\n    <IlcOptimizationPreference>Speed</IlcOptimizationPreference>\n    <TrimMode>link</TrimMode><TrimmerDefaultAction>link</TrimmerDefaultAction>\n    <IlcGenerateCompleteTypeMetadata>True</IlcGenerateCompleteTypeMetadata>\n    <IlcGenerateStackTraceData>True</IlcGenerateStackTraceData>\n    <EnsureNETCoreAppRuntime>false</EnsureNETCoreAppRuntime>\n    <ValidateExecutableReferencesMatchSelfContained>false</ValidateExecutableReferencesMatchSelfContained>\n  </PropertyGroup>\n  <PropertyGroup>\n    <ServerGarbageCollection>false</ServerGarbageCollection>\n    <ConcurrentGarbageCollection>true</ConcurrentGarbageCollection>\n  </PropertyGroup>\n  <ItemGroup>\n    <Compile Include=\"Job-KRLVKQ.notcs\" Exclude=\"bin\\**;obj\\**;**\\*.xproj;packages\\**\" />\n  </ItemGroup>\n  <ItemGroup>\n    <PackageReference Include=\"Microsoft.DotNet.ILCompiler\" Version=\"7.0.0-*\" />\n    <ProjectReference Include=\"D:\\projects\\performance\\src\\benchmarks\\micro\\MicroBenchmarks.csproj\" />\n  </ItemGroup>\n  <ItemGroup>\n    <RdXmlFile Include=\"bdn_generated.rd.xml\" />\n  </ItemGroup>\n  <ItemGroup>\n    <IlcArg Include=\"--instructionset:base,sse,sse2,sse3,sse4.1,sse4.2,avx,avx2,aes,bmi,bmi2,fma,lzcnt,pclmul,popcnt\" />\n  </ItemGroup>\n</Project>\n```\n\n### Compiling source to native code using the ILCompiler you built\n\nIf you are a NativeAOT contributor and you want to benchmark your local build of NativeAOT you have to provide necessary info (path to shipping packages).\n\nYou can do that from command line:\n\n```cmd\ndotnet run -c Release -f net7.0 --runtimes nativeaot7.0 --ilcPackages D:\\projects\\runtime\\artifacts\\packages\\Release\\Shipping\\\n```\n\nor explicitly in the code:\n\n\n```cs\nvar config = DefaultConfig.Instance\n    .AddJob(Job.ShortRun\n        .WithToolchain(NativeAotToolchain.CreateBuilder()\n            .UseLocalBuild(@\"C:\\Projects\\runtime\\artifacts\\packages\\Release\\Shipping\\\")\n            .DisplayName(\"NativeAOT local build\")\n            .TargetFrameworkMoniker(\"net7.0\")\n            .ToToolchain()));\n```\n\nBenchmarkDotNet is going to follow [these instructrions](https://github.com/dotnet/runtime/blob/main/docs/workflow/building/coreclr/nativeaot.md#building) to get it working for you.\n\n**Note**: BenchmarkDotNet is going to run `dotnet restore` on the auto-generated project and restore the packages to a temporary folder. It might take some time, but the next time you rebuild dotnet/runtime repo and run the same command BenchmarkDotNet is going to use the new ILCompiler package.\n\n\n## Wasm\n\nBenchmarkDotNet supports Web Assembly on Unix! However, currently you need to build the **dotnet runtime** yourself to be able to run the benchmarks.\n\nFor up-to-date docs, you should visit [dotnet/runtime repository](https://github.com/dotnet/runtime/blob/main/docs/workflow/testing/libraries/testing-wasm.md).\n\nThe docs below are specific to Ubuntu 18.04 at the moment of writing this document (16/07/2020).\n\nFirs of all, you need to install.... **npm** 10+:\n\n```cmd\ncurl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -\nsudo apt install nodejs\n```\n\nAfter this, you need to install [jsvu](https://github.com/GoogleChromeLabs/jsvu):\n\n```cmd\nnpm install jsvu -g\n```\n\nAdd it to PATH:\n\n```cmd\nexport PATH=\"${HOME}/.jsvu:${PATH}\"\n```\n\nAnd use it to install V8, JavaScriptCore and SpiderMonkey:\n\n```cmd\njsvu --os=linux64 --engines=javascriptcore,spidermonkey,v8\n```\n\nNow you need to install [Emscripten](https://emscripten.org/docs/getting_started/downloads.html#installation-instructions):\n\n```cmd\ngit clone https://github.com/emscripten-core/emsdk.git\ncd emsdk\n./emsdk install latest\n./emsdk activate latest\nsource ./emsdk_env.sh\n```\n\nThe last thing before cloning dotnet/runtime repository is creation of `EMSDK_PATH` env var used by Mono build scripts:\n\n```cmd\nexport EMSDK_PATH=$EMSDK\n```\n\nNow you need to clone dotnet/runtime repository:\n\n```cmd\ngit clone https://github.com/dotnet/runtime\ncd runtime\n```\n\nInstall [all Mono prerequisites](https://github.com/dotnet/runtime/blob/main/docs/workflow/testing/libraries/testing-wasm.md):\n\n```cmd\nsudo apt-get install cmake llvm-9 clang-9 autoconf automake libtool build-essential python curl git lldb-6.0 liblldb-6.0-dev libunwind8 libunwind8-dev gettext libicu-dev liblttng-ust-dev libssl-dev libnuma-dev libkrb5-dev zlib1g-dev\n```\n\nAnd FINALLY build Mono Runtime with Web Assembly support:\n\n```cmd\n./build.sh --arch wasm --os Browser -c release\n```\n\nAnd that you have .NET 5 feed added to your `nuget.config` file:\n\n```xml\n<add key=\"dotnet5\" value=\"https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet5/nuget/v3/index.json\" />\n```\n\nNow you should be able to run the Wasm benchmarks!\n\n[!include[IntroWasm](../samples/IntroWasm.md)]\n\n## MonoAotLLVM\n\nBenchmarkDotNet supports doing Mono AOT runs with both the Mono-Mini compiler and the Mono-LLVM compiler (which uses llvm on the back end).\n\nUsing this tool chain requires the following flags:\n\n```\n--runtimes monoaotllvm\n--aotcompilerpath <path to mono aot compiler>\n--customruntimepack <path to runtime pack>\n```\n\nand optionally (defaults to mini)\n\n```\n--aotcompilermode <mini|llvm>  \n```\n\nAs of this writing, the mono aot compiler is not available as a seperate download or nuget package. Therefore, it is required to build the compiler in the [dotnet/runtime repository].\n\nThe compiler binary (mono-sgen) is built as part of the `mono` subset, so it can be built (along with the runtime pack) like so (in the root of [dotnet/runtime]).\n\n`./build.sh -subset mono+libs -c Release`\n\nThe compiler binary should be generated here (modify for your platform):\n\n```\n<runtime root>/artifacts/obj/mono/OSX.x64.Release/mono/mini/mono-sgen\n```\n\nAnd the runtime pack should be generated here:\n\n```\n<runtimeroot>artifacts/bin/microsoft.netcore.app.runtime.osx-x64/Release/\n```\n"
  },
  {
    "path": "docs/articles/configs/validators.md",
    "content": "---\nuid: docs.validators\nname: Validators\n---\n\n# Validators\n\nA **validator** can validate your benchmarks before they are executed and produce validation errors.\nIf any of the validation errors is critical, then none of the benchmarks will get executed.\n\nAvailable validators are:\n\n* `BaselineValidator.FailOnError` - it checks if more than 1 Benchmark per class has `Baseline = true` applied. This validator is mandatory.\n* `JitOptimizationsValidator.(Dont)FailOnError` - it checks whether any of the referenced assemblies is non-optimized. `DontFailOnError` version is enabled by default.\n* `ExecutionValidator.(Dont)FailOnError` - it checks if it is possible to run your benchmarks by executing each of them once. Optional.\n* `ReturnValueValidator.(Dont)FailOnError` - it checks if non-void benchmarks return equal values. Optional.\n"
  },
  {
    "path": "docs/articles/contributing/building.md",
    "content": "# Building\n\nThere are two recommended options to build BenchmarkDotNet from source:\n\n## Visual Studio\n\n- [Visual Studio](https://www.visualstudio.com/downloads/) (Community, Professional, Enterprise) with .NET 4.6.2 SDK and F# support.\n\n- [.NET 10 SDK](https://dotnet.microsoft.com/download).\n\nOnce all the necessary tools are in place, building is trivial. Simply open solution file **BenchmarkDotNet.slnx** that lives at the base of the repository and run Build action.\n\n## Command-line\n\n[Cake (C# Make)](https://cakebuild.net/) is a cross platform build automation system with a C# DSL to do things like compiling code, copy files/folders, running unit tests, compress files and build NuGet packages.\n\nThe build currently depends on the following prerequisites:\n\n- Windows:\n  - PowerShell version 5 or higher\n  - MSBuild version 15.1 or higher\n  - .NET Framework 4.6 or higher\n\n- Linux:\n  - Install [Mono version 5 or higher](https://www.mono-project.com/download/stable/#download-lin)\n  - Install [fsharp package](https://fsharp.org/use/linux/)\n  - Install packages required to .NET Core SDK\n    - `gettext`\n    - `libcurl4-openssl-dev`\n    - `libicu-dev`\n    - `libssl-dev`\n    - `libunwind8`\n\n- macOS\n  - Install [Mono version 5 or higher](https://www.mono-project.com/download/stable/#download-mac)\n  - Install [fsharp package](https://fsharp.org/use/mac/)\n  - Install the latest version of [OpenSSL](https://www.openssl.org/source/).\n\nIn order to run various build tasks from terminal, use `build.cmd` file in the repository root.\n`build.cmd` is a cross-platform script that can be used the same way on Windows, Linux, and macOS.\nWhen executed without arguments, it prints help information with list of all available build tasks."
  },
  {
    "path": "docs/articles/contributing/debugging.md",
    "content": "# Debugging\n\nThere should be two debug profiles available in VS drop down\n\n![](https://cloud.githubusercontent.com/assets/6011991/15627671/89f2405a-24eb-11e6-8bd1-c9d45613e0f6.png \"Debug profiles\")\n"
  },
  {
    "path": "docs/articles/contributing/disassembler.md",
    "content": "# Contributing to Disassembler\n\nThe disassembler might looks scarry, but once you know how it works and how to debug it, it's very easy to develop it.\n\n### How it works\n\nWe have 3 disassemblers:\n\n- Mono\n- x64 for Windows and Linux\n- x86 for Windows\n\nThe MonoDisassembler is very simple: it spawns Mono with the right arguments to get the asm, Mono prints the output to the console and we just parse it. Single class does the job: `MonoDisassembler`.\n\nWhen it comes to Windows disassemblers it's not so easy. To obtain the disassm we are using ClrMD. ClrMD can attach only to the process of same bitness (architecture).\nThis is why we have two disassemblers: x64 and x86. The code is the same (single class, linked in two projects) but compiled for two different architectures. We keep both disassemblers in the resources of the BenchmarkDotNet.dll. When we need the disassembler, we search for it in the resources, copy it to the disk and run (it's an exe).\n\nOn Linux it's simpler (only x64 is supported) and we don't spawn a new process (everything is done in-proc).\n\n### How to debug the disassembler\n\nYou need to create a new console app project which executes the code that you would like to disassemble. In this app, you need to run the desired code (to get it jitted) and just don't exit before attaching the disassembler and getting the disassembly.\n\nDisassembler requires some arguments to run: id of the process to attach, full type name of the type which contains desired method, name of desired method and few other (see the example below).\n\nPersonally I use following code to run the console app and print arguments that are required to attach to it:\n\n```cs\nnamespace Sample\n{\n    class Program\n    {\n        static void Main(string[] args)\n        {\n            var result = Benchmark(); // execute the benchmark do method gets jitted\n\n            Console.WriteLine(\n            $\"{Process.GetCurrentProcess().Id} \" +   // process Id\n                $\"\\\"{typeof(Program).FullName}\\\" \" + // full type name\n                $\"{nameof(Benchmark)} \" +            // benchmarked method name\n                $\"{bool.FalseString} \" +             // print Source\n                \"2 \" +                               // recursive depth\n                $\"{Path.GetTempFileName()}.xml\");    // result xml file path\n\n            while(true)\n            {\n                Console.WriteLine(\"Press Ctrl+C to kill the process\");\n                Console.ReadLine(); // block the exe, attach with Disassembler now\n            }\n\n            GC.KeepAlive(result);\n        }\n\n        public static IntPtr Benchmark()\n        {\n            return new IntPtr(42).Multiply(4);\n        }\n    }\n\n    public static class IntPtrHelper\n    {\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public unsafe static IntPtr Multiply(this IntPtr a, int factor)\n        {\n            return (sizeof(IntPtr) == sizeof(int))\n                ? new IntPtr((int)a * factor)\n                : new IntPtr((long)a * factor);\n        }\n    }\n}\n```\n\n**Important**: Please remember that every new classic .NET project in VS compiles as 32 bit. If you want to check the asm produced for x64 you need to go to the properties of the console app (Alt+Enter) and uncheck \"Prefer 32 bit\" in the \"Build\" tab.\n\nOnce you configure your app, you should run it. It will give you an output similar to this:\n\n`13672 Sample.Program Benchmark True 7 C:\\Users\\adsitnik\\AppData\\Local\\Temp\\tmpDCB9.tmp.xml`\n\nNow you go to BenchmarkDotNet solution, select desired Disassembler project in the Solution Explorer and Set it as Startup project. After this you go to the project's properties and in the Debug tab copy-paste the arguments for the disassembler. Now when you start debugging, your IDE will spawn new process of the disassembler with the right arguments to attach to the desired exe. You should be able to debug it like any other app.\n\nPlease keep in mind that you should always use the disassembler for the correct processor architecture. If you fail to debug it, you are most probably using the wrong one.\n"
  },
  {
    "path": "docs/articles/contributing/documentation.md",
    "content": "# Documentation\n\nBenchmarkDotNet uses [DocFX](https://dotnet.github.io/docfx/) as a documentation generation tool.\n\n## Hints\n\n* If you want to provide a link to API, you can use\n    [cross references](https://dotnet.github.io/docfx/tutorial/links_and_cross_references.html#different-syntax-of-cross-reference) by\n    [UID](https://dotnet.github.io/docfx/tutorial/links_and_cross_references.html#define-uid).\n  For example,\n    `[SimpleJobAttribute](xref:BenchmarkDotNet.Attributes.SimpleJobAttribute)` and\n    `@BenchmarkDotNet.Attributes.SimpleJobAttribute`\n    will be transformed to\n    [SimpleJobAttribute](xref:BenchmarkDotNet.Attributes.SimpleJobAttribute).\n    \n## Notes\n\nDocFX uses the [following syntax](https://dotnet.github.io/docfx/spec/docfx_flavored_markdown.html?tabs=tabid-1%2Ctabid-a#note-warningtipimportant) inside block quote for different types of notes:\n\n```markdown\n> [!NOTE]\n> note content\n> [!TIP]\n> tip content\n> [!WARNING]\n> warning content\n> [!IMPORTANT]\n> important content\n> [!Caution]\n> caution content\n```\n\nIt will be transformed to:\n\n> [!NOTE]\n> note content\n\n> [!TIP]\n> tip content\n\n> [!WARNING]\n> warning content\n\n> [!IMPORTANT]\n> important content\n\n> [!Caution]\n> caution content\n\n## Building documentation locally\n\nYou can build documentation locally with the help of the `docs-build` build task:\n\n```\nbuild.cmd docs-build\n```\n\n## See also\n\n* [DocFX User Manual](https://dotnet.github.io/docfx/tutorial/docfx.exe_user_manual.html)\n* [DocFX Tutorials: Links and Cross References](https://dotnet.github.io/docfx/tutorial/links_and_cross_references.html)\n* [DocFX Flavored Markdown](https://dotnet.github.io/docfx/spec/docfx_flavored_markdown.html?tabs=tabid-1%2Ctabid-a#file-inclusion)\n"
  },
  {
    "path": "docs/articles/contributing/miscellaneous.md",
    "content": "#Miscellaneous topics\n \n## F# #\n\nWe have full F# support, all you have to do is to run `dotnet restore` to download the compilers etc.\n\n## Chat room\n[![Join the chat at https://gitter.im/dotnet/BenchmarkDotNet](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/dotnet/BenchmarkDotNet?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)\n\n## How can I help?\n\n[Here is a list of up-for-grabs issues](https://github.com/dotnet/BenchmarkDotNet/issues?q=is%3Aissue+is%3Aopen+label%3Aup-for-grabs)"
  },
  {
    "path": "docs/articles/contributing/running-tests.md",
    "content": "# Running Tests\n\nTo run all tests just run the following command in the repo root:\n\n```cmd\ndotnet test -c Release BenchmarkDotNet.slnx\n```\n\nMost of the tests projects target `net462` and `net8.0`. If the change that you want to test is not specific to any particular runtime, you can run the tests for one of them.\n\n```cmd\ndotnet test -c Release -f net8.0 BenchmarkDotNet.slnx\n```\n\nYou should be able to run all of tests from your IDE as well.\n\n## Verify Tests\n\nFor some unit tests (e.g. for exporter tests) BenchmarkDotNet uses [Verify](https://github.com/VerifyTests/Verify).\n* The expected value for each test is stored in a `*.verified.txt` file located near the test source file in the repository. Verify generates verified file's names automatically according test name and its parameters. This files must be added under the source control.\n* It also creates a `*.received` file for each failed test. You can use diff tools for convenient file comparison. By default you can find test run results on the test runner console as usual. You can comment out the line ```result.DisableDiff()``` in ```VerifySettingsFactory.Create``` method and then Verify will open KDiff for each failed test. This way you can easily understand what's the difference between verified and received values and choose the correct one.\n"
  },
  {
    "path": "docs/articles/contributing/toc.yml",
    "content": "- name: Building\n  href: building.md\n- name: Debugging\n  href: debugging.md\n- name: Running tests\n  href: running-tests.md\n- name: Miscellaneous topics\n  href: miscellaneous.md\n- name: Disassembler\n  href: disassembler.md\n- name: Documentation\n  href: documentation.md"
  },
  {
    "path": "docs/articles/faq.md",
    "content": "---\nuid: docs.faq\nname: FAQ\n---\n\n# FAQ (Frequently asked questions)\n\n* **Q** Why can't I install BenchmarkDotNet in Visual Studio 2010/2012/2013?\n\n    **A** BenchmarkDotNet requires NuGet 3.x+ and can't be installed in old versions of Visual Studio which use NuGet 2.x.\nConsider to use Visual Studio 2015/2017 or [Rider](https://www.jetbrains.com/rider/).\nSee also: [BenchmarkDotNet#237](https://github.com/dotnet/BenchmarkDotNet/issues/237), [roslyn#12780](https://github.com/dotnet/roslyn/issues/12780).\n\n* **Q** Why can't I install BenchmarkDotNet in a new .NET Core Console App in Visual Studio 2017?\n\n    **A** BenchmarkDotNet supports only netcoreapp2.0+.\nSome old Visual Studio 2017 can create a new application which targets netcoreapp1.0.\nYou should upgrade it up to 2.0.\nIf you want to target netcoreapp1.0 in your main assembly, it's recommended to create a separated project for benchmarks.\n\n* **Q** I created a new .NET Core Console App in Visual Studio 2017. Now I want to run my code on CoreCLR, full .NET Framework, and Mono. How can I do it?\n\n    **A** Use the following lines in your `.csproj` file:\n\n    ```xml\n    <TargetFrameworks>netcoreapp2.0;net46</TargetFrameworks>\n    <PlatformTarget>AnyCPU</PlatformTarget>\n    ```\n\n    And mark your benchmark class with the following attributes:\n\n    ```cs\n    [CoreJob, ClrJob, MonoJob]\n    ```\n\n* **Q** My source code targets old versions of .NET Framework or .NET Core, but BenchmarkDotNet requires `net461` and `netcoreapp2.0`. How can I run benchmarks in this case?\n\n    **A** It's a good practice to introduce an additional console application (e.g. `MyAwesomeLibrary.Benchmarks`) which will depend on your code and BenchmarkDotNet.\nDue to the fact that users usually run benchmarks in a develop environment and don't distribute benchmarks for users, it shouldn't be a problem.\n\n* **Q** I wrote a small benchmark, but BenchmarkDotNet requires a lot of time for time measurements. How can I reduce this time?\n\n    **A** By default, BenchmarkDotNet automatically chooses a number of iterations which allows achieving the best precision.\nIf you don't need such level of precision and just want to have a quick way to get approximated results, you can specify all parameters manually.\nFor example, you can use the `SimpleJob` or `ShortRunJob` attributes:\n\n    ```cs\n    [SimpleJob(launchCount: 1, warmupCount: 3, iterationCount: 5, invocationCount:100, id: \"QuickJob\")]\n    [ShortRunJob]\n    ```\n\n* **Q** My benchmark unexpectedly stopped and I saw the information about error code. What can I do?\n\n    **A** BenchmarkDotNet generates, builds and runs new process for every benchmark. This behavior is sometimes interpreted by anti-virus as dangerous, and the process is killed. Use `EnvironmentAnalyser` to detect antivirus software and configure your benchmark to use [`InProcessToolchain`](xref:BenchmarkDotNet.Samples.IntroInProcess).\n\n* **Q** Can I run benchmark on the virtual machine?\n \n    **A** Yes, of course. However, it can affect results because of the shared, physical machine, virtualization process and incorrect `Stopwatch.Frequency`. If you are unsure whether an application is running on virtual environment, use `EnvironmentAnalyser` to detect VM hypervisor.\n\n* **Q** I have failed to run my benchmarks, I am getting following errors about non-optimized dll. What can I do?  \n\n    ```\n    Assembly BenchmarkDotNet.Samples which defines benchmarks references non-optimized BenchmarkDotNet\n            If you own this dependency, please, build it in RELEASE.\n            If you don't, you can create custom config with DontFailOnError to disable our custom policy and allow this b\n    Assembly BenchmarkDotNet.Samples which defines benchmarks is non-optimized\n    Benchmark was built without optimization enabled (most probably a DEBUG configuration). Please, build it in RELEASE.\n    ```\n\n    **A** You should always run your benchmarks in RELEASE mode with optimizations enabled (default setting for RELEASE). However if you have to use non-optimized 3rd party assembly you have to create custom config to disable our default policy.\n\n    ```cs\n    public class AllowNonOptimized : ManualConfig\n    {\n        public AllowNonOptimized()\n        {\n            Add(JitOptimizationsValidator.DontFailOnError); // ALLOW NON-OPTIMIZED DLLS\n\n            Add(DefaultConfig.Instance.GetLoggers().ToArray()); // manual config has no loggers by default\n            Add(DefaultConfig.Instance.GetExporters().ToArray()); // manual config has no exporters by default\n            Add(DefaultConfig.Instance.GetColumnProviders().ToArray()); // manual config has no columns by default\n        }\n    }\n    ```\n\n* **Q** I'm running benchmarks on Linux and I see: `// ! Failed to set up priority Highest for thread ... Make sure you have the right permissions.` What can I do?\n\n    **A** This message can appear when using in-process toolchains (for example via `[InProcess]`) because BenchmarkDotNet tries to set `ThreadPriority.Highest`. On Linux, raising scheduling priority requires additional permissions. Instead of running the whole benchmark as root (which can create root-owned build artifacts), you can grant the benchmark executable the `CAP_SYS_NICE` capability:\n\n    ```bash\n    sudo setcap cap_sys_nice=eip /path/to/YourBenchmarksExecutable\n    ```\n\n    If you don't need high thread priority, you can ignore the message or avoid in-process toolchains.\n\n* **Q** I have failed to run my benchmarks from LINQPad. How can I fix this problem?  \n\n    ```\n    Assembly LINQPadQuery which defines benchmarks references non-optimized LINQPad\n    Assembly LINQPadQuery which defines benchmarks is non-optimized\n    Benchmark was built without optimization enabled (most probably a DEBUG configuration). Please, build it in RELEASE.\n    ```\n\n    **A** You need to make sure that you are using **AnyCPU** 5.22.05+ build of LINQPad with optimizations enabled. To enable the optimizations you need to go to Preferences -> Query and select `compile with /optimize+`\n\n* **Q** I'm trying to use `RPlotExporter` but there are no any images in the `results` folder\n\n    **A** Try to specify `R_LIBS_USER` (e.g. `R_LIBS_USER=/usr/local/lib/R/` on Linux/macOS, see also: [#692](https://github.com/dotnet/BenchmarkDotNet/issues/692))\n\n* **Q** My benchmark failed with OutOfMemoryException. How can I fix this problem? \n\n    **A** BenchmarkDotNet continues to run additional iterations until desired accuracy level is achieved. It's possible only if the benchmark method doesn't have any side-effects. \n    If your benchmark allocates memory and keeps it alive, you are creating a memory leak. \n    \n    You should redesign your benchmark and remove the side-effects. You can use `OperationsPerInvoke`, `IterationSetup` and `IterationCleanup` to do that.\n    \n    An example:\n    \n    ```cs\n    public class OOM\n    {\n        private StringBuilder buffer = new StringBuilder();\n        \n        [Benchmark]\n        public void HasSideEffects()\n        {\n            // This method is growing the buffer to infinity\n            // because it's executed millions of times\n            buffer.Append('a');\n        }\n        \n        [Benchmark(OperationsPerInvoke = 16)]\n        public void HasNoSideEffects()\n        {\n            buffer.Clear();\n    \n            for (int i = 0; i < 1024; i++)\n                buffer.Append('a');\n        }\n    }\n    ```    \n"
  },
  {
    "path": "docs/articles/features/baselines.md",
    "content": "---\nuid: docs.baselines\nname: Benchmark and Job Baselines\n---\n\n# Benchmark and Job Baselines\n\nIn order to scale your results, you can mark a benchmark method or a job as a baseline.\nLet's learn this feature by examples.\n\n---\n\n[!include[IntroBenchmarkBaseline](../samples/IntroBenchmarkBaseline.md)]\n\n[!include[IntroRatioSD](../samples/IntroRatioSD.md)]\n\n[!include[IntroCategoryBaseline](../samples/IntroCategoryBaseline.md)]\n\n[!include[IntroJobBaseline](../samples/IntroJobBaseline.md)]"
  },
  {
    "path": "docs/articles/features/disassembler.md",
    "content": "---\nuid: docs.disassembler\nname: Disassembler\n---\n\n# Disassembler\n\nCan be enabled by using `[DisassemblyDiagnoser]` or command line args: `-d` or `--disasm`.\n\nThe configuration options available from code level are:\n\n* `maxDepth`: Includes called methods to given level. 1 by default, indexed from 1. To print just the benchmark set it to 0. This option is also available from the console arguments level `--disasmDepth`.\n* `printSource`: C#|F#|VB source code will be printed. False by default.\n* `printInstructionAddresses`: Print instruction addresses. False by default.\n* `exportGithubMarkdown`: Exports to GitHub markdown. True by default.\n* `exportHtml`: Exports to HTML with clickable links. False by default.\n* `exportCombinedDisassemblyReport`: Exports all benchmarks to a single HTML report. Makes it easy to compare different runtimes or methods (each becomes a column in HTML table).\n* `exportDiff`: Exports a diff of the assembly code to the Github markdown format. False by default.\n\n### Requirements\n\nDisassembly Diagnoser requires following settings in your `.csproj` file:\n\n```xml\n<PropertyGroup>\n  <PlatformTarget>AnyCPU</PlatformTarget>\n  <DebugType>pdbonly</DebugType>\n  <DebugSymbols>true</DebugSymbols>\n</PropertyGroup>\n```\n\nTo get the source code we need to locate and read the `.pdb` files.\nThis is why we need `DebugType` and `DebugSymbols` settings.\nTo compare different platforms the project which defines benchmarks has to target `AnyCPU`.\n\n> [!NOTE]\n> By default, BenchmarkDotNet excludes disassembler's native dependencies that aren't used on current target platform.  \n> Use the following settings when running the benchmark binary on a different platform than it was built on, or multiple platforms.\n>\n> ```xml\n> <BenchmarkDotNetTargetPlatform>all</BenchmarkDotNetTargetPlatform>\n> ```\n\nOr specify `<RuntimeIdentifier>` for the platform that it will be run on. \n\n### Disassembly Diagnoser for Mono on Windows\n\nIf you want to get a disassembly listing for Mono on Windows, you need `as` and `x86_64-w64-mingw32-objdump.exe` tools.\nIf you don't have it, you will get a warning like follows:\n\n```\nIt's impossible to get Mono disasm because you don't have some required tools:\n'as' is not recognized as an internal or external command\n'x86_64-w64-mingw32-objdump.exe' is not recognized as an internal or external command\n```\n\nThe easiest way to get these tools:\n\n1. Download and install [Cygwin](https://www.cygwin.com/)\n2. On the \"Select Packages\" screen, search for `binutils`\n3. Install `binutils` and `mingw64-x86_64-binutils`\n4. Add `cygwin64\\bin\\` (or `cygwin\\bin\\`) in `%PATH%`\n\n![](../../images/cygwin-binutils.png)\n\n---\n\n[!include[IntroDisassembly](../samples/IntroDisassembly.md)]\n\n[!include[IntroDisassemblyRyuJit](../samples/IntroDisassemblyRyuJit.md)]\n\n[!include[IntroDisassemblyAllJits](../samples/IntroDisassemblyAllJits.md)]\n\n[!include[IntroDisassemblyDry](../samples/IntroDisassemblyDry.md)]"
  },
  {
    "path": "docs/articles/features/etwprofiler.md",
    "content": "---\n#cspell:ignore etwprofiler\nuid: docs.etwprofiler\nname: EtwProfiler\n---\n\n# EtwProfiler\n\n`EtwProfiler` allows to profile the benchmarked .NET code on Windows and exports the data to a trace file which can be opened with [PerfView](https://github.com/Microsoft/perfview) or [Windows Performance Analyzer](https://learn.microsoft.com/windows-hardware/test/wpt/windows-performance-analyzer).\n\n![](https://adamsitnik.com/images/etwprofiler/flamegraph.png)\n\n## How it works\n\n`EtwProfiler` uses `TraceEvent` library which internally uses Event Tracing for Windows (ETW) to capture stack traces and important .NET Runtime events.\n\nBefore the process with benchmarked code is started, EtwProfiler starts User and Kernel ETW sessions. Every session writes data to it's own file and captures different data. User session listens for the .NET Runtime events (GC, JIT etc) while the Kernel session gets CPU stacks and Hardware Counter events. After this, the process with benchmarked code is started. During the benchmark execution all the data is captured and written to a trace file. Moreover, BenchmarkDotNet Engine emits it's own events to be able to differentiate jitting, warmup, pilot and actual workload when analyzing the trace file. When the benchmarking is over, both sessions are closed and the two trace files are merged into one.\n\n## Limitations\n\nWhat we have today comes with following limitations:\n\n* EtwProfiler works only on Windows (one day we might implement similar thing for Unix using EventPipe)\n* Requires to run as Admin (to create ETW Kernel Session)\n* No `InProcessToolchain` support\n* To get the best possible managed code symbols you should configure your project in following way:\n\n```xml\n<DebugType>pdbonly</DebugType>\n<DebugSymbols>true</DebugSymbols>\n```\n\n> [!NOTE]\n> On certain machines [Intel TDT and Windows Defender](https://www.microsoft.com/en-us/security/blog/2021/04/26/defending-against-cryptojacking-with-microsoft-defender-for-endpoint-and-intel-tdt/) can cause CPU samples to be captured with no value.\n> You can correct this problem by disabling the feature using `powershell.exe Set-MpPreference -DisableTDTFeature $true`.\n> *WARNING:* Disabling security features will make your machine less secure; do so at your own risk.\n\n## How to use it?\n\nYou need to install `BenchmarkDotNet.Diagnostics.Windows` package.\n\nIt can be enabled in few ways, some of them:\n\n* Use the new attribute (apply it on a class that contains Benchmarks):\n\n```cs\nusing BenchmarkDotNet.Diagnostics.Windows.Configs;\n\n[EtwProfiler]\npublic class TheClassThatContainsBenchmarks { /* benchmarks go here */ }\n```\n\n* Extend the `DefaultConfig.Instance` with new instance of `EtwProfiler`:\n\n```cs\nclass Program\n{\n    static void Main(string[] args)\n        => BenchmarkSwitcher\n            .FromAssembly(typeof(Program).Assembly)\n            .Run(args,\n                DefaultConfig.Instance\n                    .AddDiagnoser(new EtwProfiler())); // HERE\n}\n```\n\n* Passing `-p ETW` or `--profiler ETW` command line argument to `BenchmarkSwitcher`\n\n## Configuration\n\nTo configure the new diagnoser you need to create an instance of `EtwProfilerConfig` class and pass it to the `EtwProfiler` constructor. The parameters that `EtwProfilerConfig` ctor takes are:\n\n* `performExtraBenchmarksRun` - if set to true, benchmarks will be executed one more time with the profiler attached. If set to false, there will be no extra run but the results will contain overhead. True by default.\n* `bufferSizeInMb` - ETW session buffer size, in MB. 256 by default.\n* `intervalSelectors` - interval per hardware counter, if not provided then default values will be used.\n* `kernelKeywords` - kernel session keywords, ImageLoad (for native stack frames) and Profile (for CPU Stacks) are the defaults.\n* `providers` - providers that should be enabled, if not provided then default values will be used.\n\n## Using PerfView to work with trace files\n\nPerfView is a free .NET profiler from Microsoft. If you don't know how to use it you should watch [these instructional videos](https://channel9.msdn.com/Series/PerfView-Tutorial) first.\n\nIf you are familiar with PerfView, then the only thing you need to know is that BenchmarkDotNet performs Jitting by running the code once, Pilot Experiment to determine how many times benchmark should be executed per iteration, non-trivial Warmup and Actual Workload. This is why when you open your trace file in PerfView you will see your benchmark in a few different places of the StackTrace.\n\n![](https://adamsitnik.com/images/etwprofiler/flamegraph_not_filtered.png)\n\nThe simplest way to filter the data to the actual benchmarks runs is to open the `CallTree` tab, put \"EngineActualStage\" in the Find box, press enter and when PerfView selects `EngineActualStage` in the `CallTree` press `Alt+R` to Set Time Range.\n\n![](https://adamsitnik.com/images/etwprofiler/perfview.gif)\n\nIf you want to filter the trace to single iteration, then you must go to the Events panel and search for the `WorkloadActual/Start` and `WorkloadActual/Stop` events.\n\n1. Open Events window\n2. Put \"WorkloadActual\" in the Filter box and hit enter.\n3. Press control or shift and choose the Start and Stop events from the left panel. Hit enter.\n4. Choose iteration that you want to investigate (events are sorted by time).\n5. Select two or more cells from the \"Time MSec\" column.\n6. Right click, choose \"Open Cpu Stacks\".\n7. Choose the process with benchmarks, right-click, choose \"Drill Into\"\n\n![](https://adamsitnik.com/images/etwprofiler/perfview_events.gif)\n"
  },
  {
    "path": "docs/articles/features/event-pipe-profiler.md",
    "content": "﻿---\nuid: docs.event-pipe-profiler\nname: EventPipeProfiler\n---\n\n# EventPipeProfiler\n\n`EventPipeProfiler` is a cross-platform profiler that allows profile .NET code on every platform - Windows, Linux, macOS. Collected data are exported to trace files (`.speedscope.json` and `.nettrace`) which can be analyzed using [SpeedScope](https://www.speedscope.app/), [PerfView](https://github.com/Microsoft/perfview), and [Visual Studio Profiler](https://learn.microsoft.com/visualstudio/profiling/profiling-feature-tour). This new profiler is available from the 0.12.1 version.\n\n![](https://wojciechnagorski.github.io/images/EventPipeProfiler/SpeedScopeAdvance.png)\n\n# Configuration\n\n`EventPipeProfiler` can be enabled in three ways:\n\n1. Using parameter `-p EP` or `--profiler EP` from the console line.\n2. Marking the benchmarked class with `[EventPipeProfiler(...)]` attribute. You can find an example below.\n3. Using a custom configuration. You can find an example below.\n\n[!include[IntroEventPipeProfiler](../samples/IntroEventPipeProfiler.md)]\n[!include[IntroEventPipeProfilerAdvanced](../samples/IntroEventPipeProfilerAdvanced.md)]"
  },
  {
    "path": "docs/articles/features/parameterization.md",
    "content": "---\nuid: docs.parameterization\nname: Benchmark Parameterization\n---\n\n# Parameterization\n\n---\n\n[!include[IntroParams](../samples/IntroParams.md)]\n\n[!include[IntroParamsSource](../samples/IntroParamsSource.md)]\n\n[!include[IntroParamsAllValues](../samples/IntroParamsAllValues.md)]\n\n[!include[IntroParamsPriority](../samples/IntroParamsPriority.md)]\n\n[!include[IntroArguments](../samples/IntroArguments.md)]\n\n[!include[IntroArgumentsSource](../samples/IntroArgumentsSource.md)]\n\n[!include[IntroArrayParam](../samples/IntroArrayParam.md)]\n\n[!include[IntroArguments](../samples/IntroArgumentsPriority.md)]\n"
  },
  {
    "path": "docs/articles/features/setup-and-cleanup.md",
    "content": "---\nuid: docs.setup-and-cleanup\nname: Setup And Cleanup\n---\n\n# Setup And Cleanup\n\nSometimes we want to write some logic which should be executed *before* or *after* a benchmark, but we don't want to measure it.\nFor this purpose, BenchmarkDotNet provides a set of attributes:\n  [`[GlobalSetup]`](xref:BenchmarkDotNet.Attributes.GlobalSetupAttribute),\n  [`[GlobalCleanup]`](xref:BenchmarkDotNet.Attributes.GlobalCleanupAttribute),\n  [`[IterationSetup]`](xref:BenchmarkDotNet.Attributes.IterationSetupAttribute),\n  [`[IterationCleanup]`](xref:BenchmarkDotNet.Attributes.IterationCleanupAttribute).\n\n---\n\n[!include[IntroSetupCleanupGlobal](../samples/IntroSetupCleanupGlobal.md)]\n\n[!include[IntroSetupCleanupIteration](../samples/IntroSetupCleanupIteration.md)]\n\n[!include[IntroSetupCleanupTarget](../samples/IntroSetupCleanupTarget.md)]"
  },
  {
    "path": "docs/articles/features/statistics.md",
    "content": "---\nuid: docs.statistics\nname: Statistics\n---\n\n# Statistics\n\n---\n\n[!include[IntroStatisticsColumns](../samples/IntroStatisticsColumns.md)]\n\n[!include[IntroPercentiles](../samples/IntroPercentiles.md)]\n\n[!include[IntroRankColumn](../samples/IntroRankColumn.md)]\n\n[!include[IntroMultimodal](../samples/IntroMultimodal.md)]\n\n[!include[IntroOutliers](../samples/IntroOutliers.md)]"
  },
  {
    "path": "docs/articles/features/toc.yml",
    "content": "- name: Parameterization\n  href: parameterization.md\n- name: Baselines\n  href: baselines.md\n- name: Setup And Cleanup\n  href: setup-and-cleanup.md\n- name: Statistics\n  href: statistics.md\n- name: Disassembler\n  href: disassembler.md\n- name: EtwProfiler\n  href: etwprofiler.md\n- name: EventPipeProfiler\n  href: event-pipe-profiler.md\n- name: VSProfiler\n  href: vsprofiler.md\n- name: VSTest\n  href: vstest.md"
  },
  {
    "path": "docs/articles/features/vsprofiler.md",
    "content": "---\nuid: docs.vsprofiler\nname: VS Profiler\n---\n\n# Running with Visual Studio profiler\nVisual Studio supports [profiler integration with BenchmarkDotNet](https://learn.microsoft.com/visualstudio/profiling/profiling-with-benchmark-dotnet) on Windows through its [Microsoft.VisualStudio.BenchmarkDotNetDiagnosers](https://www.nuget.org/packages/Microsoft.VisualStudio.DiagnosticsHub.BenchmarkDotNetDiagnosers) NuGet package. Once installed, Visual Studio specific diagnosers will capture performance data in runs and automatically open traces if launched through Visual Studio\n\n![](../../images/vs-profiler-demo.png)\n\n## How it works\n\nFirst, install the [Microsoft.VisualStudio.BenchmarkDotNetDiagnosers](https://www.nuget.org/packages/Microsoft.VisualStudio.DiagnosticsHub.BenchmarkDotNetDiagnosers) NuGet package in your benchmarking project. Next add one or more of the Visual Studio diagnosers to your benchmark to capture the relevant profiling information while benchmarking. Lastly, run your benchmarks and a diagsession will be generated. If run from Visual Studio the diagsession will automatically be opened.\n\n## Available Diagnosers\n\n* `[CPUUsageDiagnoser]` - Enables the [CPU Usage tool](https://learn.microsoft.com/visualstudio/profiling/cpu-usage).\n* `[DatabaseDiagnoser]` - Enables the [Database tool](https://learn.microsoft.com/visualstudio/profiling/analyze-database)\n* `[DotNetCountersDiagnoser]` - Enables the [.NET Counters tool](https://learn.microsoft.com/visualstudio/profiling/dotnet-counters-tool)\n* `[DotNetObjectAllocDiagnoser]` - Enables the [.NET Object Allocation tool](https://learn.microsoft.com/visualstudio/profiling/dotnet-alloc-tool). When using this tool, you must also specify `[DotNetObjectAllocJobConfiguration]` on the benchmark. If this is missing the run will fail and you will receive an error indicating you need to add it.\n* `[EventsDiagnoser]` - Enables the [Events tool](https://learn.microsoft.com/visualstudio/profiling/events-viewer)\n* `[FileIODiagnoser]` - Enables the [File IO tool](https://learn.microsoft.com/visualstudio/profiling/use-file-io)\n\n## How to use it?\n\nAfter installing the [Microsoft.VisualStudio.BenchmarkDotNetDiagnosers](https://www.nuget.org/packages/Microsoft.VisualStudio.DiagnosticsHub.BenchmarkDotNetDiagnosers) NuGet package add the following code as a benchmark:\n\n```cs\nusing System;\nusing System.Security.Cryptography;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Running;\nusing Microsoft.VSDiagnostics;\n\nnamespace MyBenchmarks\n{\n    [CPUUsageDiagnoser]\n    public class Md5VsSha256\n    {\n        private const int N = 10000;\n        private readonly byte[] data;\n\n        private readonly SHA256 sha256 = SHA256.Create();\n        private readonly MD5 md5 = MD5.Create();\n\n        public Md5VsSha256()\n        {\n            data = new byte[N];\n            new Random(42).NextBytes(data);\n        }\n\n        [Benchmark]\n        public byte[] Sha256() => sha256.ComputeHash(data);\n\n        [Benchmark]\n        public byte[] Md5() => md5.ComputeHash(data);\n    }\n\n    public class Program\n    {\n        public static void Main(string[] args)\n        {\n            var summary = BenchmarkRunner.Run(typeof(Program).Assembly);\n        }\n    }\n}\n```\n\nIn this case we have added the `[CpuUsageDiagnoser]` to capture a CPU sampling trace. From here run the benchmark in Visual Studio (Ctrl+F5), and after the benchmark run the resulting diagsession will be displayed. Double clicking on one of the benchmark rows shown under the Benchmarks tab will filter the time selection to the specific benchmark allowing you to better isolate and investigate.\n\n![](../../images/vs-profiler-demo.png)"
  },
  {
    "path": "docs/articles/features/vstest.md",
    "content": "---\nuid: docs.vstest\nname: Running with VSTest\n---\n\n# Running with VSTest\n\nBenchmarkDotNet supports discovering and executing benchmarks through VSTest.\nThis provides an alternative user experience to running benchmarks with the CLI\n  and may be preferable for those who like their IDE's VSTest integrations that they may have used when running unit tests.\n\nBelow is an example of running some benchmarks from the BenchmarkDotNet samples project in Visual Studio's Test Explorer.\n\n![](../../images/vs-testexplorer-demo.png)\n\n## About VSTest\n\nVSTest is one of the most popular test platforms in use in the .NET ecosystem,\n  with test frameworks such as MSTest, xUnit, and NUnit providing support for it.\nMany IDEs, including Visual Studio and Rider, provide UIs for running tests through VSTest\n  which some users may find more accessible than running them through the command line.\n\nIt may seem counterintuitive to run performance tests on a platform\n  that is designed for unit tests that expect a boolean outcome of \"Passed\" or \"Failed\".\nHowever, VSTest provides good value as a protocol for discovering and executing tests.\nIn addition, we can still make use of this boolean output to indicate\n  if the benchmark had validation errors that caused it to fail to run.\n\n## Caveats and things to know\n\n* **The benchmark measurements may be affected by the VSTest host and your IDE!**  \n  If you want to have accurate measurements,\n    it is recommended to run benchmarks through the CLI without other processes on the machine impacting performance.\n  This does not mean that the measurements are useless though,\n    it will still be able to provide useful measurements during development when comparing different approaches.\n* **The test adapter will not display or execute benchmarks if optimizations are disabled.**  \n  Please ensure you are compiling in Release mode or with `Optimize` set to true.\n  Using an `InProcess` toolchain will let you run your benchmarks with optimizations disabled\n    and will let you attach the debugger as well.\n* **The VSTest adapter will not call your application's entry point.**  \n  If you use the entry point to customize how your benchmarks are run,\n    you will need to do this through other means such as an assembly-level `IConfigSource`,\n    as shown [here](#setting-a-default-configuration).\n* **The test adapter will generate an entry point for you automatically.**  \n  The generated entry point will pass the command line arguments\n    and the current assembly into `BenchmarkSwitcher`,\n    so you can still use it in your CLI as well as in VSTest.\n  This means you can delete your entry point and only need to define your benchmarks.\n  If you want to use a custom entry point, you can still do so by setting `GenerateProgramFile` to `false` in your project file.\n\n## Getting started\n\n* **Step 1.** Install the NuGet packages.  \n  You need to install two packages into your benchmark project:\n  * `BenchmarkDotNet.TestAdapter`: Implements the VSTest protocol for BenchmarkDotNet\n  * `Microsoft.NET.Test.Sdk`: Includes all the pieces needed for the VSTest host to run and load the VSTest adapter.\n* **Step 2.** Make sure that the entry point is configured correctly.  \n  As mentioned in the caveats section, `BenchmarkDotNet.TestAdapter` will generate an entry point for you automatically.\n  So, if you have an entry point already,\n    you will either need to delete it or set `GenerateProgramFile` to `false` in your project file to continue using your existing one.\n  Here is an example of a `.csproj` file based on the default Console Application template:\n\n```xml\n<Project Sdk=\"Microsoft.NET.Sdk\">\n\n  <PropertyGroup>\n    <OutputType>Exe</OutputType>\n    <TargetFramework>net8.0</TargetFramework>\n    <ImplicitUsings>enable</ImplicitUsings>\n    <Nullable>enable</Nullable>\n    <!-- Disable entry point generation as this project has it's own entry point -->\n    <GenerateProgramFile>false</GenerateProgramFile>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <PackageReference Include=\"BenchmarkDotNet.TestAdapter\" Version=\"0.16.0\" />\n    <PackageReference Include=\"Microsoft.NET.Test.Sdk\" Version=\"18.0.1\" />\n  </ItemGroup>\n\n</Project>\n```\n\n* **Step 3.** Make sure that your IDE supports VSTest integration.  \n  In Visual Studio, everything works out of the box.\n  In Rider/R#, the VSTest integration might need to be activated:\n  * Go to the \"Unit Testing\" settings page.\n    * Rider: Settings -> Build, Execution, Deployment -> Unit Testing -> VSTest\n    * R#: Extensions -> ReSharper -> Options -> Tools -> Unit Testing -> Test Frameworks -> VSTest\n  * Make sure that the \"Enable VSTest adapter support\" checkbox is checked.\n  In recent versions of Rider, this may be enabled by default.\n* **Step 4.** Switch to the `Release` configuration.  \n  As mentioned above, the TestAdapter is not able to discover and run benchmarks with optimizations disabled (by design).\n* **Step 5.** Build the project.  \n  In order to discover the benchmarks, the VSTest adapter needs to be able to find the assembly.\n  Once you build the project, you should observe the discovered benchmarks in your IDE's Unit Test Explorer.\n\nIf you correctly performed all the steps above, you should be able to run your benchmarks in your IDE using embedded unit testing features.\nIf this doesn't work for you, don't hesitate to file [a new GitHub issue](https://github.com/dotnet/BenchmarkDotNet/issues/new).\n\n## Setting a default configuration\n\nPreviously, it was common for the default configuration to be defined inside the entry point.\nSince the entry point is not used when running benchmarks through VSTest,\n  the default configuration must be specified using a `Config` attribute that is set on the assembly instead.\n\nFirst, create a class that extends `ManualConfig` or `IConfig` which sets the default configuration you want:\n\n```csharp\nclass MyDefaultConfig : ManualConfig\n{\n    public MyDefaultConfig()\n    {\n        AddJob(Job.Dry);\n        AddLogger(Loggers.ConsoleLogger.Default);\n        AddValidator(JitOptimizationsValidator.DontFailOnError);\n    }\n}\n```\n\nThen, set an assembly attribute with the following.\n\n```csharp\n[assembly: Config(typeof(MyDefaultConfig))]\n```\n\nBy convention, assembly attributes are usually defined inside `AssemblyInfo.cs` in a directory called `Properties`.\n\n## Viewing the results\n\nThe full output from BenchmarkDotNet that you would have been used to seeing in the past will be sent to the \"Tests\" output of your IDE.\nUse this view if you want to see the tabular view that compares multiple benchmarks with each other or\n  if you want to see the results for each individual iteration.\n\nOne more place where you can view the results is in each individual test's output messages.\nIn Visual Studio, this can be viewed by clicking on the test in the Test Explorer after running it and looking at the Test Detail Summary.\nSince this only displays statistics for a single benchmark case,\n  it does not show the tabulated view that compares multiple benchmark cases.\nInstead, it displays a histogram and various other useful statistics.\nNot all IDEs support displaying these output messages, so you may only be able to view the results using the \"Tests\" output.\n"
  },
  {
    "path": "docs/articles/guides/choosing-run-strategy.md",
    "content": "---\n#cspell:ignore runstrategy\nuid: docs.runstrategy\nname: Choosing RunStrategy\n---\n\n# Choosing RunStrategy\n\nIf you run a benchmark, you always (explicitly or implicitly) use a [job](xref:docs.jobs).\nEach `Job` has the `RunStrategy` parameter which allows switching between different benchmark modes.\nThe default `RunStrategy` is `Throughput`, and it works fine for most cases.\nHowever, other strategies are also useful in some specific cases.\n\n## Throughput\n\n`Throughput` is the default `RunStrategy`, works perfectly for microbenchmarking.\nIt's automatically choosing the amount of operation in main iterations based on a set of pilot iterations.\nThe amount of iterations will also be chosen automatically based on accuracy job settings.\nA benchmark method should have a steady state.\n\nOf course, you can manually set all the characteristics. An example:\n\n```cs\n[SimpleJob(launchCount: 3, warmupCount: 10, iterationCount: 30)]\npublic class MyBenchmarkClass\n```\n\n---\n\n[!include[IntroColdStart](../samples/IntroColdStart.md)]\n\n[!include[IntroMonitoring](../samples/IntroMonitoring.md)]\n"
  },
  {
    "path": "docs/articles/guides/console-args.md",
    "content": "---\nuid: docs.console-args\nname: Console Arguments\n---\n\n# How to use console arguments\n\n`BenchmarkSwitcher` supports various console arguments, to make it work you need to pass the `args` to switcher:\n\n```cs\nclass Program\n{\n    static void Main(string[] args) \n        => BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args);\n}\n```\n\n**Note:** the docs that you are currently reading might get outdated, to get the most up-to-date info about supported console arguments run the benchmarks with `--help`.\n\n## Filter\n\nThe `--filter` or just `-f` allows you to filter the benchmarks by their full name (`namespace.typeName.methodName`) using glob patterns.\n\nExamples:\n\n1. Run all benchmarks from System.Memory namespace: `-f 'System.Memory*'`\n2. Run all benchmarks: `-f '*'`\n3. Run all benchmarks from ClassA and ClassB `-f '*ClassA*' '*ClassB*'`\n\n**Note**: If you would like to **join** all the results into a **single summary**, you need to put `--join`. For example: `-f '*ClassA*' '*ClassB*' --join`\n\n## List of benchmarks\n\nThe `--list` allows you to print all of the available benchmark names. Available options are:\n\n* `flat` - prints list of the available benchmarks: `--list flat`\n\n```ini\nBenchmarkDotNet.Samples.Algo_Md5VsSha256.Md5\nBenchmarkDotNet.Samples.Algo_Md5VsSha256.Sha256\nBenchmarkDotNet.Samples.IntroArguments.Benchmark\nBenchmarkDotNet.Samples.IntroArgumentsSource.SingleArgument\nBenchmarkDotNet.Samples.IntroArgumentsSource.ManyArguments\nBenchmarkDotNet.Samples.IntroArrayParam.ArrayIndexOf\nBenchmarkDotNet.Samples.IntroArrayParam.ManualIndexOf\nBenchmarkDotNet.Samples.IntroBasic.Sleep\n[...]\n```\n\n* `tree` - prints tree of the available benchmarks: `--list tree`\n\n```ini\nBenchmarkDotNet\n └─Samples\n    ├─Algo_Md5VsSha256\n    │  ├─Md5\n    │  └─Sha256\n    ├─IntroArguments\n    │  └─Benchmark\n    ├─IntroArgumentsSource\n    │  ├─SingleArgument\n    │  └─ManyArguments\n    ├─IntroArrayParam\n    │  ├─ArrayIndexOf\n    │  └─ManualIndexOf\n    ├─IntroBasic\n    │  ├─Sleep\n[...]\n```\n\nThe `--list` option works with the `--filter` option. Examples:\n\n* `--list flat --filter *IntroSetupCleanup*` prints:\n\n```ini\nBenchmarkDotNet.Samples.IntroSetupCleanupGlobal.Logic\nBenchmarkDotNet.Samples.IntroSetupCleanupIteration.Benchmark\nBenchmarkDotNet.Samples.IntroSetupCleanupTarget.BenchmarkA\nBenchmarkDotNet.Samples.IntroSetupCleanupTarget.BenchmarkB\nBenchmarkDotNet.Samples.IntroSetupCleanupTarget.BenchmarkC\nBenchmarkDotNet.Samples.IntroSetupCleanupTarget.BenchmarkD\n```\n\n* `--list tree --filter *IntroSetupCleanup*` prints:\n\n```ini\nBenchmarkDotNet\n └─Samples\n    ├─IntroSetupCleanupGlobal\n    │  └─Logic\n    ├─IntroSetupCleanupIteration\n    │  └─Benchmark\n    └─IntroSetupCleanupTarget\n       ├─BenchmarkA\n       ├─BenchmarkB\n       ├─BenchmarkC\n       └─BenchmarkD\n```\n\n## Categories\n\nYou can also filter the benchmarks by categories:\n\n* `--anyCategories` - runs all benchmarks that belong to **any** of the provided categories\n* `--allCategories`- runs all benchmarks that belong to **all** provided categories\n\n## Diagnosers\n\n* `-m`, `--memory` - enables MemoryDiagnoser and prints memory statistics\n* `-t`, `--threading` - enables `ThreadingDiagnoser` and prints threading statistics\n* `-d`, `--disasm`- enables DisassemblyDiagnoser and exports diassembly of benchmarked code. When you enable this option, you can use:\n  * `--disasmDepth` - Sets the recursive depth for the disassembler.\n  * `--disasmDiff` - Generates diff reports for the disassembler.\n\n## Runtimes\n\nThe `--runtimes` or just `-r` allows you to run the benchmarks for selected Runtimes. Available options are:\n\n* Clr - BDN will either use Roslyn (if you run it as .NET app) or latest installed .NET SDK to build the benchmarks (if you run it as .NET Core app).\n* Core - if you run it as .NET Core app, BDN will use the same target framework moniker, if you run it as .NET app it's going to use net8.0.\n* Mono - it's going to use the Mono from `$Path`, you can override  it with `--monoPath`.\n* net46, net461, net462, net47, net471, net472, net48, net481 - to build and run benchmarks against specific .NET Framework version.\n* netcoreapp3.1, net5.0, net6.0, net7.0, net8.0 - to build and run benchmarks against specific .NET (Core) version.\n* nativeaot5.0, nativeaot6.0, nativeaot7.0, nativeaot8.0 - to build and run benchmarks using NativeAOT. Can be customized with additional options: `--ilcPackages`, `--ilCompilerVersion`.\n* mono6.0, mono7.0, mono8.0 - to build and run benchmarks with .Net 6+ using MonoVM.\n\nExample: run the benchmarks for .NET 4.7.2 and .NET 8.0:\n\n```log\ndotnet run -c Release -- --runtimes net472 net8.0\n```\n\nExample: run the benchmarks for .NET Core 3.1 and latest .NET SDK installed on your PC:\n\n```log\ndotnet run -c Release -f netcoreapp3.1 -- --runtimes clr core\n```\n\nBut same command executed with `-f net6.0` is going to run the benchmarks for .NET 6.0:\n\n```log\ndotnet run -c Release -f net6.0 -- --runtimes clr core\n```\n\n## Number of invocations and iterations\n\n* `--launchCount` - how many times we should launch process with target benchmark. The default is 1.\n* `--warmupCount` - how many warmup iterations should be performed. If you set it, the minWarmupCount and maxWarmupCount are ignored. By default calculated by the heuristic.\n* `--minWarmupCount` - minimum count of warmup iterations that should be performed. The default is 6.\n* `--maxWarmupCount` - maximum count of warmup iterations that should be performed. The default is 50.\n* `--iterationTime` - desired time of execution of an iteration. Used by Pilot stage to estimate the number of invocations per iteration. 500ms by default.\n* `--iterationCount` - how many target iterations should be performed. By default calculated by the heuristic.\n* `--minIterationCount` - minimum number of iterations to run. The default is 15.\n* `--maxIterationCount` - maximum number of iterations to run. The default is 100.\n* `--invocationCount` - invocation count in a single iteration. By default calculated by the heuristic.\n* `--unrollFactor` - how many times the benchmark method will be invoked per one iteration of a generated loop. 16 by default\n* `--runOncePerIteration` - run the benchmark exactly once per iteration. False by default.\n\nExample: run single warmup iteration, from 9 to 12 actual workload iterations.\n\n```log\ndotnet run -c Release -- --warmupCount 1 --minIterationCount 9 --maxIterationCount 12\n```\n\n## Specifying custom default settings for console argument parser\n\nIf you want to have a possibility to specify custom default Job settings programmatically and optionally overwrite it with console line arguments, then you should create a global config with single job marked as `.AsDefault` and pass it to `BenchmarkSwitcher` together with the console line arguments.\n\nExample: run single warmup iteration by default.\n\n```cs\nstatic void Main(string[] args)\n    => BenchmarkSwitcher\n        .FromAssembly(typeof(Program).Assembly)\n        .Run(args, GetGlobalConfig());\n\nstatic IConfig GetGlobalConfig()\n    => DefaultConfig.Instance\n        .With(Job.Default\n            .WithWarmupCount(1)\n            .AsDefault()); // the KEY to get it working\n```\n\nNow, the default settings are: `WarmupCount=1` but you might still overwrite it from console args like in the example below:\n\n```log\ndotnet run -c Release -- --warmupCount 2\n```\n\n## Response files support\n\nBenchmark.NET supports parsing parameters via response files. for example you can create file `run.rsp` with following content\n```\n--warmupCount 1\n--minIterationCount 9\n--maxIterationCount 12\n```\n\nand run it using `dotnet run -c Release -- @run.rsp`. It would be equivalent to running following command line\n\n```log\ndotnet run -c Release -- --warmupCount 1 --minIterationCount 9 --maxIterationCount 12\n```\n\n## Statistical Test\n\nTo perform a Mann–Whitney U Test and display the results in a dedicated column you need to provide the Threshold:\n\n* `--statisticalTest`- Threshold for Mann–Whitney U Test. Examples: 5%, 10ms, 100ns, 1s\n\nExample: run Mann–Whitney U test with relative ratio of 5% for all benchmarks for .NET 6.0 (base) vs .NET 8.0 (diff). .NET 6.0 will be baseline because it was first.\n\n```log\ndotnet run -c Release -- --filter * --runtimes net6.0 net8.0 --statisticalTest 5%\n```\n\n## Example Usages\n\n* Use Job.ShortRun for running the benchmarks:  \n    `-j short`\n* Run benchmarks in process:  \n    `-i`\n* Run benchmarks for .NET 4.7.2, .NET 8.0 and Mono. .NET 4.7.2 will be baseline because it was first.:\n    `--runtimes net472 net8.0 Mono`\n* Run benchmarks for .NET 8.0 and .NET 10.0. .NET 8.0 will be baseline because it was first.:\n    `--runtimes net8.0 net10.0`\n* Use MemoryDiagnoser to get GC stats:\n    `-m`\n* Use DisassemblyDiagnoser to get disassembly:\n    `-d`\n* Use HardwareCountersDiagnoser to get hardware counter info:\n    `--counters CacheMisses+InstructionRetired`\n* Run all benchmarks exactly once:\n    `-f * -j Dry`\n* Run all benchmarks from System.Memory namespace:\n    `-f System.Memory*`\n* Run all benchmarks from ClassA and ClassB using type names:\n    `-f ClassA ClassB`\n* Run all benchmarks from ClassA and ClassB using patterns:\n    `-f *.ClassA.* *.ClassB.*`\n* Run all benchmarks called `BenchmarkName` and show the results in single summary:\n    `--filter *.BenchmarkName --join`\n* Run selected benchmarks once per iteration:\n    `--runOncePerIteration`\n* Run selected benchmarks 100 times per iteration. Perform single warmup iteration and 5 actual workload iterations:\n    `--invocationCount 100 --iterationCount 5 --warmupCount 1`\n* Run selected benchmarks 250ms per iteration. Perform from 9 to 15 iterations:\n    `--iterationTime 250 --maxIterationCount 15 --minIterationCount 9`\n* Run MannWhitney test with relative ratio of 5% for all benchmarks for .NET 6.0 (base) vs .NET 8.0 (diff). .NET Core 6.0 will be baseline because it was provided as first.:\n    `--filter * --runtimes net6.0 net8.0 --statisticalTest 5%`\n* Run benchmarks using environment variables 'ENV_VAR_KEY_1' with value 'value_1' and 'ENV_VAR_KEY_2' with value 'value_2':\n    `--envVars ENV_VAR_KEY_1:value_1 ENV_VAR_KEY_2:value_2`\n* Hide Mean and Ratio columns (use double quotes for multi-word columns: \"Alloc Ratio\"):\n    `-h Mean Ratio`\n\n## More\n\n* `-j`, `--job`               (Default: Default) Dry/Short/Medium/Long or Default\n* `-r`, `--runtimes`          Full target framework moniker for .NET Core and .NET. For Mono just 'Mono'. For NativeAOT please append target runtime version (example: 'nativeaot7.0'). First one will be marked as baseline!\n* `-e`, `--exporters`         GitHub/StackOverflow/RPlot/CSV/JSON/HTML/XML\n* `-m`, `--memory`            (Default: false) Prints memory statistics\n* `-t`, `--threading`         (Default: false) Prints threading statistics\n* `--exceptions`              (Default: false) Prints exception statistics\n* `-d, --disasm`              (Default: false) Gets disassembly of benchmarked code\n* `-p, --profiler`            Profiles benchmarked code using selected profiler. Available options: EP/ETW/CV/NativeMemory\n* `-f, --filter`              Glob patterns\n* `-h, --hide`                Hides columns by name\n* `-i, --inProcess`           (Default: false) Run benchmarks in Process\n* `-a, --artifacts`           Valid path to accessible directory\n* `--outliers`                (Default: RemoveUpper) `DontRemove`/`RemoveUpper`/`RemoveLower`/`RemoveAll`\n* `--affinity`                Affinity mask to set for the benchmark process\n* `--allStats`                (Default: false) Displays all statistics (min, max & more)\n* `--allCategories`           Categories to run. If few are provided, only the benchmarks which belong to all of them are going to be executed\n* `--anyCategories`           Any Categories to run\n* `--attribute`               Run all methods with given attribute (applied to class or method)\n* `--join`                    (Default: false) Prints single table with results for all benchmarks\n* `--keepFiles`               (Default: false) Determines if all auto-generated files should be kept or removed after running the benchmarks.\n* `--noOverwrite`             (Default: false) Determines if the exported result files should not be overwritten (be default they are overwritten).\n* `--counters`                Hardware Counters\n* `--cli`                     Path to dotnet cli (optional).\n* `--packages`                The directory to restore packages to (optional).\n* `--coreRun`                 Path(s) to CoreRun (optional).\n* `--monoPath`                Optional path to Mono which should be used for running benchmarks.\n* `--clrVersion`              Optional version of private CLR build used as the value of `COMPLUS_Version` env var.\n* `--ilCompilerVersion`       Optional version of Microsoft.DotNet.ILCompiler which should be used to run with NativeAOT. Example: \"7.0.0-preview.3.22123.2\"\n* `--ilcPackages`             Optional path to shipping packages produced by local dotnet/runtime build. Example: 'D:\\projects\\runtime\\artifacts\\packages\\Release\\Shipping\\'\n* `--launchCount`             How many times we should launch process with target benchmark. The default is 1.\n* `--warmupCount`             How many warmup iterations should be performed. If you set it, the minWarmupCount and maxWarmupCount are ignored. By default calculated by the heuristic.\n* `--minWarmupCount`          Minimum count of warmup iterations that should be performed. The default is 6.\n* `--maxWarmupCount`          Maximum count of warmup iterations that should be performed. The default is 50.\n* `--iterationTime`           Desired time of execution of an iteration in milliseconds. Used by Pilot stage to estimate the number of invocations per iteration. 500ms by default\n* `--iterationCount`          How many target iterations should be performed. By default calculated by the heuristic.\n* `--minIterationCount`       Minimum number of iterations to run. The default is 15.\n* `--maxIterationCount`       Maximum number of iterations to run. The default is 100.\n* `--invocationCount`         Invocation count in a single iteration. By default calculated by the heuristic.\n* `--unrollFactor`            How many times the benchmark method will be invoked per one iteration of a generated loop. 16 by default\n* `--strategy`                The RunStrategy that should be used. Throughput/ColdStart/Monitoring.\n* `--platform`                The Platform that should be used. If not specified, the host process platform is used (default). AnyCpu/X86/X64/Arm/Arm64/LoongArch64.\n* `--runOncePerIteration`     (Default: false) Run the benchmark exactly once per iteration.\n* `--info`                    (Default: false) Print environment information.\n* `--apples`                  (Default: false) Runs apples-to-apples comparison for specified Jobs.\n* `--list`                    (Default: Disabled) Prints all of the available benchmark names. Flat/Tree\n* `--disasmDepth`             (Default: 1) Sets the recursive depth for the disassembler.\n* `--disasmFilter`            Glob patterns applied to full method signatures by the the disassembler.\n* `--disasmDiff`              (Default: false) Generates diff reports for the disassembler.\n* `--logBuildOutput`          Log Build output.\n* `--generateBinLog`          Generate msbuild `binlog` for builds\n* `--buildTimeout`            Build timeout in seconds.\n* `--wakeLock`                Prevents the system from entering sleep or turning off the display. None/System/Display.\n* `--stopOnFirstError`        (Default: false) Stop on first error.\n* `--statisticalTest`         Threshold for Mann–Whitney U Test. Examples: 5%, 10ms, 100ns, 1s\n* `--disableLogFile`          Disables the `logfile`.\n* `--maxWidth`                Max parameter column width, the default is 20.\n* `--envVars`                 Colon separated environment variables (key:value)\n* `--memoryRandomization`     Specifies whether Engine should allocate some random-sized memory between iterations. It makes [GlobalCleanup] and [GlobalSetup] methods to be executed after every iteration.\n* `--wasmEngine`              Full path to a java script engine used to run the benchmarks, used by Wasm toolchain.\n* `--wasmArgs`                (Default: --expose_wasm) Arguments for the javascript engine used by Wasm toolchain.\n* `--customRuntimePack`       Path to a custom runtime pack. Only used for wasm/MonoAotLLVM currently.\n* `--AOTCompilerPath`         Path to Mono AOT compiler, used for MonoAotLLVM.\n* `--AOTCompilerMode`         (Default: mini) Mono AOT compiler mode, either 'mini' or 'llvm'\n* `--wasmDataDir`             Wasm data directory\n* `--wasmCoreCLR`             (Default: false) Use CoreCLR runtime pack (Microsoft.NETCore.App.Runtime.browser-wasm) instead of the Mono runtime pack for WASM benchmarks.\n* `--noForcedGCs`             Specifying would not forcefully induce any GCs.\n* `--noOverheadEvaluation`    Specifying would not run the evaluation overhead iterations.\n* `--resume`                  (Default: false) Continue the execution if the last run was stopped.\n* `--help`                    Display this help screen.\n* `--version`                 Display version information.\n"
  },
  {
    "path": "docs/articles/guides/customizing-runtime.md",
    "content": "---\nuid: docs.customizing-runtime\nname: Customizing Runtime\n---\n\n# Customizing Runtime\n\nCurrently, we have only information about customizing Mono in this section.\nIf you want to customize .NET Core, read an article about @docs.toolchains.\n\n---\n\n[!include[IntroCustomMono](../samples/IntroCustomMono.md)]\n\n[!include[IntroCustomMonoArguments](../samples/IntroCustomMonoArguments.md)]\n\n[!include[IntroEnvVars](../samples/IntroEnvVars.md)]\n\n[!include[IntroStaThread](../samples/IntroStaThread.md)]"
  },
  {
    "path": "docs/articles/guides/dotnet-new-templates.md",
    "content": "---\nuid: docs.dotnet-new-templates\nname: BenchmarkDotNet templates \n---\n\n# BenchmarkDotNet templates\n\nBenchmarkDotNet provides project templates to setup your benchmarks easily.  \nThe template exists for each major .NET language ([C#](https://learn.microsoft.com/dotnet/csharp/), [F#](https://learn.microsoft.com/dotnet/fsharp/) and [VB](https://learn.microsoft.com/dotnet/visual-basic/)) with equivalent features and structure.\n\n## How to install the templates\n\nThe templates requires the [.NET Core SDK](https://www.microsoft.com/net/download). Once installed, run the following command to install the templates:\n\n```log\ndotnet new install BenchmarkDotNet.Templates\n```\n\nIf you want to uninstall all BenchmarkDotNet templates:\n\n```log\ndotnet new uninstall BenchmarkDotNet.Templates\n```\n\nThe template is a nuget package distributed over nuget: [BenchmarkDotNet.Templates](https://www.nuget.org/packages/BenchmarkDotNet.Templates/).\n\n## Basic usage\n\nTo create a new C# benchmark library project from the template, run:\n\n```log\ndotnet new benchmark\n```\n\n If you'd like to create F# or VB project, you can specify project language with `-lang` option:\n\n```log\ndotnet new benchmark -lang F#\ndotnet new benchmark -lang VB\n```\n\n## Project template specific options\n\nThe template projects has five additional options - all of them are optional.\n\nBy default a console app project targeting `net6.0` is created.\nThis lets you run the benchmarks from console (`dotnet run`) or from your favorite IDE.  \n\nThe option `-f` or `--framework` changes the target framework:\n\n```log\ndotnet new benchmark -f net472\n```\n\nYou can specify `--console-app=false` to create a class library project targeting `netstandard2.0` by default:\n\n```log\ndotnet new benchmark --console-app=false\n```\n\nThe option `-b` or `--benchmarkName` sets the name of the benchmark class:\n\n```log\ndotnet new benchmark -b Md5VsSha256\n```\n\nBenchmarkDotNet lets you create a dedicated configuration class (see [Configs](xref:docs.configs)) to customize the execution of your benchmarks.\nTo create a benchmark project with a configuration class, use the option `-c` or `--config`:\n\n```log\ndotnet new benchmark -c\n```\n\nThe option `--no-restore` if specified, skips the automatic nuget restore after the project is created:\n\n```log\ndotnet new benchmark --no-restore\n```\n\nUse the `-h` or `--help` option to display all possible arguments with a description and the default values:\n\n```log\ndotnet new benchmark --help\n```\n\n## How to run the benchmarks\n\nPlease read [how to run your benchmarks](xref:docs.how-to-run).\n\n## The relationship of BenchmarkDotNet and BenchmarkDotNet.Templates\n\nThe version of the template nuget package is synced with the [BenchmarkDotNet](https://www.nuget.org/packages/BenchmarkDotNet/) package.\nFor instance, the template version `0.11.5` is referencing [BenchmarkDotnet 0.11.15](https://www.nuget.org/packages/BenchmarkDotNet/0.11.5) - there is no floating version behavior.\n\n**Note**: This will maybe change when BenchmarkDotNet reaches `1.x`.\n\n## References\n\nFor more info about the `dotnet new` CLI, please read [the documentation](https://learn.microsoft.com/dotnet/core/tools/dotnet).\n\n"
  },
  {
    "path": "docs/articles/guides/getting-started.md",
    "content": "# Getting started\nTo get started with BenchmarkDotNet, please follow these steps. \n\n## Step 1. Create a project\nCreate a new console application.\n\n## Step 2. Installation\nInstall BenchmarkDotNet via the NuGet package: [BenchmarkDotNet](https://www.nuget.org/packages/BenchmarkDotNet/)\n\n```cmd\n> dotnet add package BenchmarkDotNet\n```\n\nRead more about BenchmarkDotNet NuGet packages: @docs.nuget\n\n## Step 3. Design a benchmark\nWrite a class with methods that you want to measure and mark them with the `Benchmark` attribute. In the following example, we \ncompare [MD5](https://en.wikipedia.org/wiki/MD5) and [SHA256](https://en.wikipedia.org/wiki/SHA-2) cryptographic hash functions:\n\n```cs\nusing System;\nusing System.Security.Cryptography;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Running;\n\nnamespace MyBenchmarks\n{\n    public class Md5VsSha256\n    {\n        private const int N = 10000;\n        private readonly byte[] data;\n\n        private readonly SHA256 sha256 = SHA256.Create();\n        private readonly MD5 md5 = MD5.Create();\n\n        public Md5VsSha256()\n        {\n            data = new byte[N];\n            new Random(42).NextBytes(data);\n        }\n\n        [Benchmark]\n        public byte[] Sha256() => sha256.ComputeHash(data);\n\n        [Benchmark]\n        public byte[] Md5() => md5.ComputeHash(data);\n    }\n\n    public class Program\n    {\n        public static void Main(string[] args)\n        {\n            var summary = BenchmarkRunner.Run<Md5VsSha256>();\n        }\n    }\n}\n```\n\nThe `BenchmarkRunner.Run<Md5VsSha256>()` call runs your benchmarks and prints results to the console.\n\n## Step 4. Run benchmarks\nStart your console application to run the benchmarks. The application must be built in the Release configuration.\n\n```cmd\n> dotnet run -c Release\n```\n\n## Step 5. View results\nView the results. Here is an example of output from the above benchmark:\n\n```\nBenchmarkDotNet=v0.13.2, OS=Windows 10 (10.0.19045.2251)\nIntel Core i7-4770HQ CPU 2.20GHz (Haswell), 1 CPU, 8 logical and 4 physical cores\n.NET SDK=7.0.100\n  [Host]     : .NET 7.0.0 (7.0.22.51805), X64 RyuJIT AVX2\n  DefaultJob : .NET 7.0.0 (7.0.22.51805), X64 RyuJIT AVX2\n\n\n| Method |     Mean |    Error |   StdDev |\n|------- |---------:|---------:|---------:|\n| Sha256 | 51.57 us | 0.311 us | 0.291 us |\n|    Md5 | 21.91 us | 0.138 us | 0.129 us |\n```\n\n## Step 6. Analyze results\nBenchmarkDotNet will automatically create basic reports in the `.\\BenchmarkDotNet.Artifacts\\results` folder that can be shared and analyzed. \n\nTo help analyze performance in further depth, you can configure your benchmark to collect and output more detailed information. Benchmark configuration can be conveniently changed by adding attributes to the class containing your benchmarks. For example:\n\n* [Diagnosers](../configs/diagnosers.md)\n  * GC allocations: `[MemoryDiagnoser]`\n  * Code size and disassembly: `[DisassemblyDiagnoser]`\n  * Threading statistics: `[ThreadingDiagnoser]`\n* [Exporters](../configs/exporters.md)\n  * CSV reports with raw data: `[CsvMeasurementsExporter]`\n  * JSON reports with raw data: `[JsonExporter]`\n  * Plots (if you have installed R): `[RPlotExporter]`\n\nFor more information, see [Configs](../configs/configs.md).\n\n## Next steps\nBenchmarkDotNet provides features which aid high-quality performance research.\nIf you want to know more about BenchmarkDotNet features, check out the [Overview](../overview.md) page.\nIf you have any questions, check out the [FAQ](../faq.md) page.\nIf you didn't find an answer for your question on this page, [ask it on Gitter](https://gitter.im/dotnet/BenchmarkDotNet) or [create an issue on GitHub](https://github.com/dotnet/BenchmarkDotNet/issues).\n"
  },
  {
    "path": "docs/articles/guides/good-practices.md",
    "content": "# Good Practices\n\n## Use the Release build without an attached debugger\n\nNever use the Debug build for benchmarking. *Never*. The debug version of the target method can run 10–100 times slower. \nThe release mode means that you should have `<Optimize>true</Optimize>` in your csproj file \nor use [/optimize](https://learn.microsoft.com/dotnet/csharp/language-reference/compiler-options/) for `csc`. Also, never \nuse an attached debugger (e.g. Visual Studio or WinDbg) during the benchmarking. The best way is \nbuild our benchmark in the Release mode and run it from the command line.\n\n## Try different environments\n\nPlease, don't extrapolate your results. Or do it very carefully.\nI remind you again: the results in different environments may vary significantly. If a `Foo1` method is faster than \na `Foo2` method for CLR4, .NET Framework 4.5, x64, RyuJIT, Windows, it means that the `Foo1` method is faster than \nthe `Foo2` method for CLR4, .NET Framework 4.5, x64, RyuJIT, Windows and nothing else. And you can not say anything \nabout methods performance for CLR 2 or .NET Framework 4.6 or LegacyJIT-x64 or x86 or Linux+Mono until you try it. \n\n## Avoid dead code elimination\n\nYou should also use the result of calculation. For example, if you run the following code:\n\n```cs\nvoid Foo()\n{\n    Math.Exp(1);\n}\n```\n\nthen JIT can eliminate this code because the result of `Math.Exp` is not used. The better way is use it like this:\n\n```cs\ndouble Foo()\n{\n    return Math.Exp(1);\n}\n```\n\n## Power settings and other applications\n\n* Turn off all of the applications except the benchmark process and the standard OS processes. If you run benchmark and work in the Visual Studio at the same time, it can negatively affect to benchmark results.\n* If you use laptop for benchmarking, keep it plugged in and use the maximum performance mode.\n\n"
  },
  {
    "path": "docs/articles/guides/how-it-works.md",
    "content": "# How it works\n\nBenchmarkDotNet follows the following steps to run your benchmarks:\n\n1. `BenchmarkRunner` generates an isolated project per each runtime settings and builds it in Release mode.\n2. Next, we take each method/job/params combination and try to measure its performance by launching benchmark process several times (`LaunchCount`).\n3. An invocation of the workload method is an *operation*. A bunch of operation is an *iteration*. If you have an `IterationSetup` method, it will be invoked before each iteration, \nbut not between operations. We have the following type of iterations:\n    * `Jitting`: The overhead/workload methods are invoked to ensure they are JIT-compiled (and on tiered runtimes, to promote them when possible). These iterations are not used for measurements.\n    * `Pilot`: The best operation count will be chosen.\n    * `OverheadWarmup`, `OverheadWorkload`: BenchmarkDotNet overhead will be evaluated.\n    * `ActualWarmup`: Warmup of the workload method.\n    * `ActualWorkload`: Actual measurements.\n    * `Result` = `ActualWorkload` - `<MedianOverhead>`\n4. After all of the measurements, BenchmarkDotNet creates:\n    * An instance of the `Summary` class that contains all information about benchmark runs.\n    * A set of files that contains summary in human-readable and machine-readable formats.\n    * A set of plots.\n\n## Pseudocode\n\nIf you don't understand our \"count terminology\", then you might find following pseudocode useful:\n\n```cs\nIEnumerable<Results> Run(Benchmark benchmark)\n{\n    var toolchain = benchmark.GetToolchain();\n\n    var autoGeneratedProject = toolchain.Generate(benchmark);\n    var exe = toolchain.Build(autoGeneratedProject);\n\n    foreach (var runIndex in LaunchCount) // LaunchCount = 1 by default\n        yield return ParseResults(Process.Start(exe).Output); // calls ActualRun in a separate process\n}\n\nResult ActualRun(Method method, Job job)\n{\n    GlobalSetup();\n    JittingStage(method); // triggers JIT compilation (and tiering if enabled) before Pilot/Warmup\n\n    int unrollFactor = job.Run.UnrollFactor; // 16 by default\n\n    long perfectInvocationCount = Pilot(method, unrollFactor);\n\n    WarmupStage(EMPTY_METHOD, perfectInvocationCount, unrollFactor); // EMPTY_METHOD has same return type and arguments as benchmark\n    var overhead = ActualStage(EMPTY_METHOD, perfectInvocationCount, unrollFactor);\n\n    WarmupStage(method, perfectInvocationCount, unrollFactor);\n    var result = ActualStage(method, perfectInvocationCount);\n\n    if (MemoryDiagnoser.IsEnabled)\n        var gcStats = MeasureGcStats(method, perfectInvocationCount, unrollFactor);\n\n    GlobalCleanup(); \n\n    return (result - Median(overhead), gcStats);\n}\n\nvoid JittingStage(Method method)\n{\n    RunIteration(method, invokeCount: 1, unrollFactor: 1);\n    if (JitInfo.IsTiered)\n    {\n        for (int i = 0; i < JitInfo.MaxTierPromotions; i++)\n        {\n            RunIteration(method, invokeCount: JitInfo.TieredCallCountThreshold, unrollFactor: 1);\n            Thread.Sleep(250);\n        }\n    }\n}\n\nlong Pilot(Method method, int unrollFactor)\n{\n    // invokeCount is the equivalent of InnerIterationCount from xunit-performance\n    long invokeCount = minInvokeCount;\n\n    while (true)\n    {\n        var measurement = RunIteration(method, invokeCount, unrollFactor);\n\n        if (heuristic.IsPilotRequirementMet(measurement))\n            break;\n\n        invokeCount *= 2;\n    }\n\n    return invokeCount;\n}\n\nvoid Warmup(Method method, long invokeCount, int unrollFactor)\n{\n    while (true)\n    {\n        var measurement = RunIteration(method, invokeCount, unrollFactor);\n\n        if (heuristic.IsWarmupRequirementMet(measurement))\n            break;\n    }\n}\n\nIEnuberable<Measurement> Workload(Method method, long invokeCount, int unrollFactor)\n{\n    while (true)\n    {\n        var measurement = RunIteration(method, invokeCount, unrollFactor);\n\n        if (measurement.IsNotOutlier)\n            yield return measurement;\n\n        if (heuristic.IsWorkloadRequirementMet(measurement))\n            yield break;\n    }\n}\n\n// every iteration invokes the method (invokeCount / unrollFactor) times\nMeasurement RunIteration(Method method, long invokeCount, long unrollFactor)\n{\n    IterationSetup();\n    MemoryCleanup();\n\n    var clock = Clock.Start();\n\n    for (long i = 0; i < invokeCount / unrollFactor; i++)\n    {\n        // we perform manual loop unrolling!!\n        method(); // 1st call\n        method(); // 2nd call\n\n        method(); // (unrollFactor - 1)'th call\n        method(); // unrollFactor'th call\n    }\n\n    var clockSpan = clock.GetElapsed();\n\n    IterationCleanup();\n    MemoryCleanup();\n\n    return Measurement(clockSpan);\n}\n\nGcStats MeasureGcStats(Method method, long invokeCount, long unrollFacto)\n{\n    // we enable monitoring after workload actual run, for this single iteration which is executed at the end\n    // so even if we enable AppDomain monitoring in separate process\n    // it does not matter, because we have already obtained the results!\n    EnableMonitoring(); \n\n    IterationSetup();\n\n    var initialGcStats = GcStats.ReadInitial();\n\n    // we do NOT start any clock here, because the enabled monitoring might have some overhead\n    // so we just get the gc stats and ignore the timing\n    // it's last thing the process does before it dies, so also enabled monitoring is not an issue for next benchmarks\n    // because each of them is going to be executed in a new process\n\n    for (long i = 0; i < invokeCount / unrollFactor; i++)\n    {\n        // we perform manual loop unrolling!!\n        method(); // 1st call\n        method(); // 2nd call\n\n        method(); // (unrollFactor - 1)'th call\n        method(); // unrollFactor'th call\n    }\n\n    var finalGcStats = GcStats.ReadFinal();\n\n    IterationCleanup();\n\n    return finalGcStats - initialGcStats; // the result is the difference between the stats collected after and before running the extra iteration\n}\n```\n"
  },
  {
    "path": "docs/articles/guides/how-to-run.md",
    "content": "---\nuid: docs.how-to-run\n---\n\n# How to run your benchmarks\n\nThere are several ways to run your benchmarks. What is important is that **BenchmarkDotNet works only with Console Apps**. It does not support any other kind of application like ASP.NET, Azure WebJobs, etc.\n\n## Types\n\nIf you have just a few types with benchmarks, you can use `BenchmarkRunner`:\n\n```cs\nvar summary = BenchmarkRunner.Run<MyBenchmarkClass>();\nvar summary = BenchmarkRunner.Run(typeof(MyBenchmarkClass));\n```\n\nThe disadvantage of `BenchmarkRunner` is that it always runs all benchmarks in a given type (or assembly) and to change the type you need to modify the source code. But it's great for a quick start.\n\n## BenchmarkSwitcher\n\nIf you have more types and you want to choose which benchmark to run (either by using console line arguments or console input) you should use `BenchmarkSwitcher`:\n\n```cs\nstatic void Main(string[] args) => BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args);\n```\n\nAlso you can use the config command style to specify some config from command line (more [](xref:docs.console-args)):\n\n```log\ndotnet run -c Release -- --job short --runtimes net472 net7.0 --filter *BenchmarkClass1*\n```\n\nThe most important thing about `BenchmarkSwitcher` is that you need to pass the `args` from `Main` to the `Run` method. If you don't, it won't parse the arguments."
  },
  {
    "path": "docs/articles/guides/nuget.md",
    "content": "---\nuid: docs.nuget\nname: Installing NuGet packages\n---\n\n# Installing NuGet packages\n\n## Packages\n\nWe have the following set of NuGet packages (you can install it directly from `nuget.org`):\n\n* `BenchmarkDotNet`: BenchmarkDotNet infrastructure and logic. This is all you need to run benchmarks.\n* `BenchmarkDotNet.Annotations`: Basic BenchmarkDotNet annotations for your benchmarks.\n* `BenchmarkDotNet.Diagnostics.Windows`: an additional optional package that provides a set of Windows diagnosers.\n* `BenchmarkDotNet.Diagnostics.dotTrace`: an additional optional package that provides DotTraceDiagnoser.\n* `BenchmarkDotNet.Diagnostics.dotMemory`: an additional optional package that provides DotMemoryDiagnoser.\n* `BenchmarkDotNet.Templates`: Templates for BenchmarkDotNet.\n\nYou might find other NuGet packages that start with `BenchmarkDotNet` name, but they are internal BDN packages that should not be installed manually. All that matters are the three packages mentioned above.\n\n## Versioning system and feeds\n\nWe have 3 kinds of versions: *stable*, *nightly*, and *develop*.\nYou can get the current version from the source code via `BenchmarkDotNetInfo.FullVersion` and the full title via `BenchmarkDotNetInfo.FullTitle`.\n\n### Stable\n\nThese versions are available from the official NuGet feed.\n\n```xml\n<packageSources>\n  <add key=\"api.nuget.org\" value=\"https://api.nuget.org/v3/index.json\" protocolVersion=\"3\" />\n</packageSources>\n```\n\n### Nightly\n\nIf you want to use a nightly version of the BenchmarkDotNet, add the `https://www.myget.org/F/benchmarkdotnet/api/v3/index.json` feed in the `<packageSources>` section of your `NuGet.config`:\n\n```xml\n<packageSources>\n  <add key=\"bdn-nightly\" value=\"https://www.myget.org/F/benchmarkdotnet/api/v3/index.json\" />\n</packageSources>\n```\n\nNow you can install the packages from the `bdn-nightly` feed.\n\n### Develop\n\nYou also can build BenchmarkDotNet from source code:\n\n```sh\nbuild.cmd pack\n```"
  },
  {
    "path": "docs/articles/guides/toc.yml",
    "content": "- name: Getting Started\n  href: getting-started.md\n- name: How to run your benchmarks\n  href: how-to-run.md\n- name: Good Practices\n  href: good-practices.md\n- name: Installing NuGet packages\n  href: nuget.md\n- name: Choosing RunStrategy\n  href: choosing-run-strategy.md\n- name: Customizing runtime\n  href: customizing-runtime.md\n- name: How it works\n  href: how-it-works.md\n- name: Console Arguments\n  href: console-args.md\n- name: Troubleshooting\n  href: troubleshooting.md\n- name: BenchmarkDotNet templates\n  href: dotnet-new-templates.md"
  },
  {
    "path": "docs/articles/guides/troubleshooting.md",
    "content": "# Troubleshooting\n\n## BenchmarkDotNet\n\nYou need to be aware of the fact that to ensure process-level isolation BenchmarkDotNet generates, builds and executes every benchmark in a dedicated process. For .NET and Mono we generate a C# file and compile it using Roslyn. For .NET Core and NativeAOT we generate not only C# file but also a project file which later is restored and build with dotnet cli. If your project has some non-trivial build settings like a `.props` and `.target` files or native dependencies things might not work well out of the box.\n\nHow do you know that BenchmarkDotNet has failed to build the project? BDN is going to tell you about it. An example:\n\n```log\n// Validating benchmarks:\n// ***** BenchmarkRunner: Start   *****\n// ***** Found 1 benchmark(s) in total *****\n// ***** Building 1 exe(s) in Parallel: Start   *****\n// start dotnet restore  /p:UseSharedCompilation=false /p:BuildInParallel=false /m:1 /p:Deterministic=true /p:Optimize=true in C:\\Projects\\BenchmarkDotNet\\samples\\BenchmarkDotNet.Samples\\bin\\Release\\netcoreapp2.1\\c6045772-d3c7-4dbe-ab37-4aca6dcb6ec4\n// command took 0.51s and exited with 1\n// ***** Done, took 00:00:00 (0.66 sec)   *****\n// Found 1 benchmarks:\n//   IntroBasic.Sleep: DefaultJob\n\n// Build Error: Standard output:\n\n Standard error:\n C:\\Projects\\BenchmarkDotNet\\samples\\BenchmarkDotNet.Samples\\bin\\Release\\netcoreapp2.1\\c6045772-d3c7-4dbe-ab37-4aca6dcb6ec4\\BenchmarkDotNet.Autogenerated.csproj(36,1): error MSB4025: The project file could not be loaded. Unexpected end of file while parsing Comment has occurred. Line 36, position 1.\n\n// BenchmarkDotNet has failed to build the auto-generated boilerplate code.\n// It can be found in C:\\Projects\\BenchmarkDotNet\\samples\\BenchmarkDotNet.Samples\\bin\\Release\\netcoreapp2.1\\c6045772-d3c7-4dbe-ab37-4aca6dcb6ec4\n// Please follow the troubleshooting guide: https://benchmarkdotnet.org/articles/guides/troubleshooting.html\n```\n\nIf the error message is not clear enough, you need to investigate it further.\n\nHow to troubleshoot the build process:\n\n1. Run the benchmarks with `--logBuildOutput` command line argument.\n2. Read the error message. If it does not contain the answer to your problem, please continue to the next step.\n3. Go to the build artifacts folder (path printed by BDN).\n4. The folder should contain: \n   * a file with source code (ends with `.notcs` to make sure IDE don't include it in other projects by default)\n   * a project file (`.csproj`)\n   * a script file (`.bat` on Windows, `.sh` for other OSes) which should be doing exactly the same thing as BDN does:\n     * dotnet restore\n     * dotnet build (with some parameters like `-c Release`)\n5. Run the script, read the error message. From here you continue with the troubleshooting like it was a project in your solution.\n\nThe recommended order of solving build issues:\n\n1. Change the right settings in your project file which defines benchmarks to get it working.\n2. Customize the `Job` settings using available options like `job.WithCustomBuildConfiguration($name)`or `job.With(new Argument[] { new MsBuildArgument(\"/p:SomeProperty=Value\")})`.\n3. Implement your own `IToolchain` and generate and build all the right things in your way (you can use existing Builders and Generators and just override some methods to change specific behaviour).\n4. Report a bug in BenchmarkDotNet repository.\n\n## Debugging Benchmarks\n\n## In the same process\n\nIf your benchmark builds but fails to run, you can simply debug it. The first thing you should try is to do it in a single process (host process === runner process).\n\n1. Use `DebugInProcessConfig`\n\n```cs\nstatic void Main(string[] args) => BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args, new DebugInProcessConfig());\n```\n\n2. Set the breakpoints in your favorite IDE\n3. Start debugging the project with benchmarks\n\n## In a different process\n\nSometimes you won't be able to reproduce the problem in the same process. In this case, you have 3 options:\n\n### Launch a debugger from the benchmark process using Debugger API\n\n```cs\n[GlobalSetup]\npublic void Setup()\n{\n    System.Diagnostics.Debugger.Launch();\n}\n```\n\n### Attach a debugger from IDE\n\nModify your benchmark to sleep until the Debugger is not attached and use your favorite IDE to attach the debugger to benchmark process. **Do attach to the process which is running the benchmark** (the arguments of the process are going to be `--benchmarkId $someNumber --benchmarkName $theName`), not the host process.\n\n```cs\n[GlobalSetup]\npublic void Setup()\n{\n    while(!System.Diagnostics.Debugger.IsAttached)\n        Thread.Sleep(TimeSpan.FromMilliseconds(100));\n}\n```\n\n### One of the above, but with a Debug build\n\nBy default, BDN builds everything in Release. But debugging Release builds even with full symbols might be non-trivial. To enforce BDN to build the benchmark in Debug please use `DebugBuildConfig` and then attach the debugger.\n\n"
  },
  {
    "path": "docs/articles/license.md",
    "content": "### The MIT License\n\nCopyright (c) 2013–2025 .NET Foundation and contributors\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "docs/articles/overview.md",
    "content": "---\nuid: docs.overview\nname: Overview\n---\n\n# Overview\n\n## Install\n\nCreate new console application and install the [BenchmarkDotNet](https://www.nuget.org/packages/BenchmarkDotNet/) NuGet package. We support:\n\n* *Projects:* classic and modern with PackageReferences\n* *Runtimes:* Full .NET Framework (4.6+), .NET Core (2.0+), Mono, NativeAOT\n* *OS:* Windows, Linux, MacOS\n* *Languages:* C#, F#, VB\n\n## Design a benchmark\nCreate a new console application, write a class with methods that you want to measure, and mark them with the `Benchmark` attribute. In the following example, we \ncompare the [MD5](https://en.wikipedia.org/wiki/MD5) and [SHA256](https://en.wikipedia.org/wiki/SHA-2) cryptographic hash functions:\n\n```cs\nusing System;\nusing System.Security.Cryptography;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Running;\n\nnamespace MyBenchmarks\n{\n    public class Md5VsSha256\n    {\n        private const int N = 10000;\n        private readonly byte[] data;\n\n        private readonly SHA256 sha256 = SHA256.Create();\n        private readonly MD5 md5 = MD5.Create();\n\n        public Md5VsSha256()\n        {\n            data = new byte[N];\n            new Random(42).NextBytes(data);\n        }\n\n        [Benchmark]\n        public byte[] Sha256() => sha256.ComputeHash(data);\n\n        [Benchmark]\n        public byte[] Md5() => md5.ComputeHash(data);\n    }\n\n    public class Program\n    {\n        public static void Main(string[] args)\n        {\n            var summary = BenchmarkRunner.Run(typeof(Program).Assembly);\n        }\n    }\n}\n```\n\nThe `BenchmarkRunner.Run(typeof(Program).Assembly)` call runs all benchmarks in the current assembly and prints results to the console. If you'd like to run a single benchmark type, you can use `BenchmarkRunner.Run<Md5VsSha256>()`.\n\nBenchmarkDotNet discovers benchmark types via reflection, so benchmarks can be placed in different files as long as they are in the same project/assembly and the benchmark classes are `public`.\n\nNote that BenchmarkDotNet will only run benchmarks if the application is built in the Release configuration.\nThis is to prevent unoptimized code from being benchmarked.\nBenchmarkDotNet will issue an error if you forget to change the configuration.\n\n## Benchmark results\n\n```\nBenchmarkDotNet=v0.13.2, OS=Windows 10 (10.0.19045.2251)\nIntel Core i7-4770HQ CPU 2.20GHz (Haswell), 1 CPU, 8 logical and 4 physical cores\n.NET SDK=7.0.100\n  [Host]     : .NET 7.0.0 (7.0.22.51805), X64 RyuJIT AVX2\n  DefaultJob : .NET 7.0.0 (7.0.22.51805), X64 RyuJIT AVX2\n\n\n| Method |     Mean |    Error |   StdDev |\n|------- |---------:|---------:|---------:|\n| Sha256 | 51.57 us | 0.311 us | 0.291 us |\n|    Md5 | 21.91 us | 0.138 us | 0.129 us |\n```\n\n## Jobs\n\nBenchmarkDotNet can benchmark your code in several environments at once. For example, to compare your benchmark's performance in .NET Framework, .NET Core, Mono and NativeAOT, you can add `SimpleJob` attributes to the benchmark class:\n\n```cs\n[SimpleJob(RuntimeMoniker.Net481)]\n[SimpleJob(RuntimeMoniker.Net70)]\n[SimpleJob(RuntimeMoniker.NativeAot70)]\n[SimpleJob(RuntimeMoniker.Mono)]\npublic class Md5VsSha256\n```\n\nExample of the result:\n\n```\nBenchmarkDotNet=v0.13.2, OS=Windows 10 (10.0.19045.2251)\nIntel Core i7-4770HQ CPU 2.20GHz (Haswell), 1 CPU, 8 logical and 4 physical cores\n.NET SDK=7.0.100\n  [Host]               : .NET 7.0.0 (7.0.22.51805), X64 RyuJIT AVX2\n  .NET 7.0             : .NET 7.0.0 (7.0.22.51805), X64 RyuJIT AVX2\n  .NET Framework 4.8.1 : .NET Framework 4.8.1 (4.8.9037.0), X64 RyuJIT VectorSize=256\n  Mono                 : Mono 6.12.0 (Visual Studio), X64 VectorSize=128\n  NativeAOT 7.0        : .NET 7.0.0 (7.0.22.51805), X64 RyuJIT AVX2\n\n| Method |                  Job |              Runtime |      Mean |    Error |   StdDev |\n|------- |--------------------- |--------------------- |----------:|---------:|---------:|\n| Sha256 |             .NET 7.0 |             .NET 7.0 |  51.90 us | 0.341 us | 0.302 us |\n|    Md5 |             .NET 7.0 |             .NET 7.0 |  21.96 us | 0.052 us | 0.049 us |\n| Sha256 | .NET Framework 4.8.1 | .NET Framework 4.8.1 | 206.33 us | 2.069 us | 1.834 us |\n|    Md5 | .NET Framework 4.8.1 | .NET Framework 4.8.1 |  23.28 us | 0.094 us | 0.083 us |\n| Sha256 |                 Mono |                 Mono | 167.70 us | 1.216 us | 1.137 us |\n|    Md5 |                 Mono |                 Mono |  42.12 us | 0.145 us | 0.136 us |\n| Sha256 |        NativeAOT 7.0 |        NativeAOT 7.0 |  51.45 us | 0.226 us | 0.200 us |\n|    Md5 |        NativeAOT 7.0 |        NativeAOT 7.0 |  21.88 us | 0.050 us | 0.041 us |\n```\n\nThere are many predefined job attributes which you can use. For example, you can compare `LegacyJitX86`, `LegacyJitX64`, and `RyuJitX64`:\n\n```cs\n[LegacyJitX86Job, LegacyJitX64Job, RyuJitX64Job]\n```\n\nOr, you can define your own jobs:\n\n```cs\n[Config(typeof(Config))]\npublic class Md5VsSha256\n{\n    private class Config : ManualConfig\n    {\n        public Config()\n        {\n            AddJob(new Job(Job.Dry)\n            {\n                Environment = { Jit = Jit.LegacyJit, Platform = Platform.X64 },\n                Run = { LaunchCount = 3, WarmupCount = 5, IterationCount = 10 },\n                Accuracy = { MaxRelativeError = 0.01 }\n            });\n        }\n    }\n```\n\nRead more: [Jobs](configs/jobs.md), [Configs](configs/configs.md)\n\n\n## Columns\n\nYou can add columns to the summary table:\n\n```cs\n[MinColumn, MaxColumn]\npublic class Md5VsSha256\n```\n\n| Method | Median      | StdDev    | Min         | Max         |\n| ------ | ----------- | --------- | ----------- | ----------- |\n| Sha256 | 131.3200 us | 4.6744 us | 129.8216 us | 147.7630 us |\n| Md5    | 26.2847 us  | 0.4424 us | 25.8442 us  | 27.4258 us  |\n\nYou can also define custom columns based on the full benchmark summary.\n\nRead more: [Columns](configs/columns.md)\n\n## Exporters\n\nYou can export the results of your benchmark in different formats:\n\n```cs\n[MarkdownExporter, AsciiDocExporter, HtmlExporter, CsvExporter, RPlotExporter]\npublic class Md5VsSha256\n```\n\nIf you have installed R, `RPlotExporter` will generate a lot of nice plots:\n\n![](../images/v0.12.0/rplot.png)\n\nRead more: [Exporters](configs/exporters.md)\n\n## Baseline\n\nTo view the relative performance of your benchmarks, mark one of your benchmark methods as the `Baseline`:\n\n```cs\npublic class Sleeps\n{\n    [Benchmark]\n    public void Time50() => Thread.Sleep(50);\n\n    [Benchmark(Baseline = true)]\n    public void Time100() => Thread.Sleep(100);\n\n    [Benchmark]\n    public void Time150() => Thread.Sleep(150);\n}\n```\n\nA new column will be added to the summary table:\n\n| Method  | Median      | StdDev    | Ratio |\n| ------- | ----------- | --------- | ------ |\n| Time100 | 100.2640 ms | 0.1238 ms | 1.00   |\n| Time150 | 150.2093 ms | 0.1034 ms | 1.50   |\n| Time50  | 50.2509 ms  | 0.1153 ms | 0.50   |\n\nRead more: [Baselines](features/baselines.md)\n\n## Params\n\nYou can mark one or several fields or properties in your class with the `Params` attribute. In this attribute, you can specify a set of values. BenchmarkDotNet will run benchmarks for each combination of params values.\n\n```cs\npublic class IntroParams\n{\n    [Params(100, 200)]\n    public int A { get; set; }\n\n    [Params(10, 20)]\n    public int B { get; set; }\n\n    [Benchmark]\n    public void Benchmark()\n    {\n        Thread.Sleep(A + B + 5);\n    }\n}\n```\n\n\n| Method    | Median      | StdDev    | A    | B    |\n| --------- | ----------- | --------- | ---- | ---- |\n| Benchmark | 115.3325 ms | 0.0242 ms | 100  | 10   |\n| Benchmark | 125.3282 ms | 0.0245 ms | 100  | 20   |\n| Benchmark | 215.3024 ms | 0.0375 ms | 200  | 10   |\n| Benchmark | 225.2710 ms | 0.0434 ms | 200  | 20   |\n\nRead more: [Parameterization](features/parameterization.md)\n\n## Languages\n\nYou can also write benchmarks in `F#` or `VB`.\n\n```fs\ntype StringKeyComparison () =\n    let mutable arr : string [] = [||]\n    let dict1 = ConcurrentDictionary<_,_>()\n    let dict2 = ConcurrentDictionary<_,_>(StringComparer.Ordinal)\n\n    [<Params (100, 500, 1000, 2000)>] \n    member val public DictSize = 0 with get, set\n\n    [<GlobalSetup>]\n    member self.GlobalSetupData() =\n        dict1.Clear(); dict2.Clear()\n        arr <- getStrings self.DictSize\n        arr |> Array.iter (fun x -> dict1.[x] <- true ; dict2.[x] <- true)\n\n    [<Benchmark>]\n    member self.StandardLookup () = lookup arr dict1\n\n    [<Benchmark>]\n    member self.OrdinalLookup () = lookup arr dict2\n```\n\n```vb\nPublic Class Sample\n    <Params(1, 2)>\n    Public Property A As Integer\n    <Params(3, 4)>\n    Public Property B As Integer\n\n    <Benchmark>\n    Public Function Benchmark() As Integer\n            return A + B\n    End Function\nEnd Class\n```\n\n## Diagnostics\n\nA diagnoser can attach to your benchmarks and collect additional information.\n\nExamples of diagnosers built in to BenchmarkDotNet are:\n\n- Garbge collection and allocation statistics (`MemoryDiagnoser`).\n- Lock contention and thread pool statistics (`ThreadingDiagnoser`), which is only available on .NET Core 3.0+. \n- JIT inlining events (`InliningDiagnoser`). You can find this diagnoser in a separated package with diagnosers for Windows (`BenchmarkDotNet.Diagnostics.Windows`): [![NuGet](https://img.shields.io/nuget/v/BenchmarkDotNet.svg)](https://www.nuget.org/packages/BenchmarkDotNet.Diagnostics.Windows/)\n\n\nBelow is a sample benchmark using `MemoryDiagnoser`. Note the extra columns on the right-hand side (`Gen 0` and `Allocated`):\n\n```\n    Method |       Mean |    StdDev |  Gen 0 | Allocated |\n---------- |----------- |---------- |------- |---------- |\n Iterative | 31.0739 ns | 0.1091 ns |      - |       0 B |\n      LINQ | 83.0435 ns | 1.0103 ns | 0.0069 |      32 B | \n```\n\nRead more: [Diagnosers](configs/diagnosers.md)\n\n## BenchmarkRunner\n\nThere are several ways to run your benchmarks.\n\n```cs\nvar summary = BenchmarkRunner.Run<MyBenchmarkClass>();\nvar summary = BenchmarkRunner.Run(typeof(MyBenchmarkClass));\nvar summaries = BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args);\n```\n\nRead more: [How to run your benchmarks](guides/how-to-run.md)\n"
  },
  {
    "path": "docs/articles/samples/IntroArguments.md",
    "content": "---\nuid: BenchmarkDotNet.Samples.IntroArguments\n---\n\n## Sample: IntroArguments\n\nAs an alternative to using [`[Params]`](xref:BenchmarkDotNet.Attributes.ParamsAttribute),\n  you can specify arguments for your benchmarks.\nThere are several ways to do it (described below).\n\n\nThe [`[Arguments]`](xref:BenchmarkDotNet.Attributes.ArgumentsAttribute) allows you to provide a set of values.\nEvery value must be a compile-time constant (it's C# language limitation for attributes in general).\nYou can also combine\n  [`[Arguments]`](xref:BenchmarkDotNet.Attributes.ArgumentsAttribute) with\n  [`[Params]`](xref:BenchmarkDotNet.Attributes.ParamsAttribute).\nAs a result, you will get results for each combination of params values.\n\n### Source code\n\n[!code-csharp[IntroArguments.cs](../../../samples/BenchmarkDotNet.Samples/IntroArguments.cs)]\n\n### Output\n\n```markdown\n|    Method | AddExtra5Miliseconds |   a |  b |     Mean |     Error |    StdDev |\n|---------- |--------------------- |---- |--- |---------:|----------:|----------:|\n| Benchmark |                False | 100 | 10 | 110.1 ms | 0.0056 ms | 0.0044 ms |\n| Benchmark |                False | 100 | 20 | 120.1 ms | 0.0155 ms | 0.0138 ms |\n| Benchmark |                False | 200 | 10 | 210.2 ms | 0.0187 ms | 0.0175 ms |\n| Benchmark |                False | 200 | 20 | 220.3 ms | 0.1055 ms | 0.0986 ms |\n| Benchmark |                 True | 100 | 10 | 115.3 ms | 0.1375 ms | 0.1286 ms |\n| Benchmark |                 True | 100 | 20 | 125.3 ms | 0.1212 ms | 0.1134 ms |\n| Benchmark |                 True | 200 | 10 | 215.4 ms | 0.0779 ms | 0.0691 ms |\n| Benchmark |                 True | 200 | 20 | 225.4 ms | 0.0775 ms | 0.0725 ms |\n```\n\n### Links\n\n* @docs.parameterization\n* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroArguments\n\n---"
  },
  {
    "path": "docs/articles/samples/IntroArgumentsPriority.md",
    "content": "---\nuid: BenchmarkDotNet.Samples.IntroArgumentsPriority\n---\n\n## Sample: IntroArgumentsPriority\n\nLike Params also Argument columns can be sorted in the table result through their `Priority`. The priority should be defined only once for multiple Arguments and will keep their inner order as they are defined in the method.\n\n### Source code\n\n[!code-csharp[IntroArgumentsPriority.cs](../../../samples/BenchmarkDotNet.Samples/IntroArgumentsPriority.cs)]\n\n### Output\n\n```markdown\n|        Method |  b |   A | c | d |     Mean |   Error |  StdDev |\n|-------------- |--- |---- |-- |-- |---------:|--------:|--------:|\n| ManyArguments |  ? | 100 | 1 | 2 | 103.4 ms | 0.09 ms | 0.08 ms |\n|     Benchmark |  5 | 100 | ? | ? | 105.5 ms | 0.21 ms | 0.19 ms |\n|     Benchmark | 10 | 100 | ? | ? | 110.5 ms | 0.14 ms | 0.14 ms |\n|     Benchmark | 20 | 100 | ? | ? | 120.4 ms | 0.16 ms | 0.15 ms |\n```\n\n### Links\n\n* Priority BaseClass [`PriorityAttribute.cs`](xref:BenchmarkDotNet.Attributes.PriorityAttribute)\n* @docs.parameterization\n* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroArgumentsPriority\n\n---"
  },
  {
    "path": "docs/articles/samples/IntroArgumentsSource.md",
    "content": "---\nuid: BenchmarkDotNet.Samples.IntroArgumentsSource\n---\n\n## Sample: IntroArgumentsSource\n\nIn case you want to use a lot of values, you should use\n  [`[ArgumentsSource]`](xref:BenchmarkDotNet.Attributes.ArgumentsSourceAttribute).\n\nYou can mark one or several fields or properties in your class by the\n  [`[ArgumentsSource]`](xref:BenchmarkDotNet.Attributes.ArgumentsSourceAttribute) attribute.\nIn this attribute, you have to specify the name of public method/property which is going to provide the values\n  (something that implements `IEnumerable`).\nThe source may be instance or static. If the source is not in the same type as the benchmark, the type containing the source must be specified in the attribute constructor.\n\n### Source code\n\n[!code-csharp[IntroArgumentsSource.cs](../../../samples/BenchmarkDotNet.Samples/IntroArgumentsSource.cs)]\n\n### Output\n\n```markdown\n| Method         | time              |  x |  y |            Mean |          Error |         StdDev |\n|--------------- |------------------ |--- |--- |----------------:|---------------:|---------------:|\n| SingleArgument | 00:00:00.0100000 |  ? |  ? |  15,780,658.9 ns |   53,493.3 ns |   50,037.7 ns |\n| SingleArgument | 00:00:00.1000000 |  ? |  ? | 110,181,308.0 ns |  517,614.4 ns |  484,176.8 ns |\n| ManyArguments  |                ? |  1 |  1 |           3.135 ns |       0.0852 ns |       0.1326 ns |\n| ManyArguments  |                ? |  2 |  2 |          13.571 ns |       0.2180 ns |       0.1933 ns |\n| ManyArguments  |                ? |  4 |  4 |          13.478 ns |       0.2188 ns |       0.1940 ns |\n| ManyArguments  |                ? | 10 | 10 |          13.471 ns |       0.2294 ns |       0.2034 ns |\n```\n\n> `?` is displayed when a column is not applicable for the given benchmark (e.g., `x`/`y` for `SingleArgument`, `time` for `ManyArguments`).\n\n### Another example\n\nIf the values are complex types you need to override `ToString` method to change the display names used in the results.\n\n```cs\n[DryJob]\npublic class WithNonPrimitiveArgumentsSource\n{\n    [Benchmark]\n    [ArgumentsSource(nameof(NonPrimitive))]\n    public void Simple(SomeClass someClass, SomeStruct someStruct)\n    {\n        for (int i = 0; i < someStruct.RangeEnd; i++)\n            Console.WriteLine($\"// array.Values[{i}] = {someClass.Values[i]}\");\n    }\n\n    public IEnumerable<object[]> NonPrimitive()\n    {\n        yield return new object[] { new SomeClass(Enumerable.Range(0, 10).ToArray()), new SomeStruct(10) };\n        yield return new object[] { new SomeClass(Enumerable.Range(0, 15).ToArray()), new SomeStruct(15) };\n    }\n\n    public class SomeClass\n    {\n        public SomeClass(int[] initialValues) => Values = initialValues.Select(val => val * 2).ToArray();\n\n        public int[] Values { get; }\n\n        public override string ToString() => $\"{Values.Length} items\";\n    }\n\n    public struct SomeStruct\n    {\n        public SomeStruct(int rangeEnd) => RangeEnd = rangeEnd;\n\n        public int RangeEnd { get; }\n\n        public override string ToString() => $\"{RangeEnd}\";\n    }\n}\n```\n\n```markdown\n| Method | someClass | someStruct |     Mean | Error |\n|------- |---------- |----------- |---------:|------:|\n| Simple |  10 items |         10 | 887.2 us |    NA |\n| Simple |  15 items |         15 | 963.1 us |    NA |\n```\n\n\n### Links\n\n* @docs.parameterization\n* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroArgumentsSource\n\n---\n"
  },
  {
    "path": "docs/articles/samples/IntroArrayParam.md",
    "content": "---\nuid: BenchmarkDotNet.Samples.IntroArrayParam\n---\n\n## Sample: IntroArrayParam\n\n> [!WARNING]\n> The cost of creating the arguments is not included in the benchmark.\n\nSo if you want to pass an array as an argument, we are going to allocate it before running the benchmark,\n  and the benchmark will not include this operation.\n\n### Source code\n\n[!code-csharp[IntroArrayParam.cs](../../../samples/BenchmarkDotNet.Samples/IntroArrayParam.cs)]\n\n### Output\n\n```markdown\n|        Method |      array | value |      Mean |     Error |    StdDev | Allocated |\n|-------------- |----------- |------ |----------:|----------:|----------:|----------:|\n|  ArrayIndexOf | Array[100] |     4 | 15.558 ns | 0.0638 ns | 0.0597 ns |       0 B |\n| ManualIndexOf | Array[100] |     4 |  5.345 ns | 0.0668 ns | 0.0625 ns |       0 B |\n|  ArrayIndexOf |   Array[3] |     4 | 14.334 ns | 0.1758 ns | 0.1558 ns |       0 B |\n| ManualIndexOf |   Array[3] |     4 |  2.758 ns | 0.0905 ns | 0.1208 ns |       0 B |\n|  ArrayIndexOf | Array[100] |   101 | 78.359 ns | 1.8853 ns | 2.0955 ns |       0 B |\n| ManualIndexOf | Array[100] |   101 | 80.421 ns | 0.6391 ns | 0.5978 ns |       0 B |\n```\n\n### Links\n\n* @docs.parameterization\n* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroArrayParam\n\n---"
  },
  {
    "path": "docs/articles/samples/IntroBasic.md",
    "content": "---\nuid: BenchmarkDotNet.Samples.IntroBasic\ntitle: \"Sample: IntroBasic\"\n---\n\n## Sample: IntroBasic\n\n### Source code\n\n[!code-csharp[IntroBasic.cs](../../../samples/BenchmarkDotNet.Samples/IntroBasic.cs)]\n\n### Links\n\n* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroBasic\n\n---"
  },
  {
    "path": "docs/articles/samples/IntroBenchmarkBaseline.md",
    "content": "---\nuid: BenchmarkDotNet.Samples.IntroBenchmarkBaseline\n---\n\n## Sample: IntroBenchmarkBaseline\n\nYou can mark a method as a baseline with the help of `[Benchmark(Baseline = true)]`.\n\n### Source code\n\n[!code-csharp[IntroBenchmarkBaseline.cs](../../../samples/BenchmarkDotNet.Samples/IntroBenchmarkBaseline.cs)]\n\n### Output\n\nAs a result, you will have additional `Ratio` column in the summary table:\n\n```markdown\n|  Method |      Mean |     Error |    StdDev | Ratio |\n|-------- |----------:|----------:|----------:|------:|\n|  Time50 |  50.46 ms | 0.0779 ms | 0.0729 ms |  0.50 |\n| Time100 | 100.39 ms | 0.0762 ms | 0.0713 ms |  1.00 |\n| Time150 | 150.48 ms | 0.0986 ms | 0.0922 ms |  1.50 |\n```\n\nThis column contains the mean value of the ratio distribution.\n\nFor example, in the case of `Time50`, we divide\n  the first measurement of `Time50` into each measurement of `Time100` (it's the baseline),\n  the second measurement of `Time50` into each measurement of `Time100`,\n  and so on.\nNext, we calculate the mean of all these values and display it in the `Ratio` column.\nFor `Time50`, we have 0.50.\n\nThe `Ratio` column was formerly known as `Scaled`.\nThe old title was a source of misunderstanding and confusion because\n  many developers interpreted it as the ratio of means (e.g., `50.46`/`100.39` for `Time50`).\nThe ratio of distribution means and the mean of the ratio distribution are pretty close to each other in most cases,\n  but they are not equal.\n\nIn @BenchmarkDotNet.Samples.IntroRatioStdDev, you can find an example of how this value can be spoiled by outliers.\n\n### Links\n\n* @docs.baselines\n* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroBenchmarkBaseline\n\n---"
  },
  {
    "path": "docs/articles/samples/IntroCategories.md",
    "content": "---\nuid: BenchmarkDotNet.Samples.IntroCategories\n---\n\n## Sample: IntroCategories\n\nCombined together with `[BenchmarkCategory]` attribute, you can group the benchmarks into categories and filter them by categories.\n\n### Source code\n\n[!code-csharp[IntroCategories.cs](../../../samples/BenchmarkDotNet.Samples/IntroCategories.cs)]\n\n### Command line examples:\n    \n```\n--allCategories=A,B\n--anyCategories=A,B\n```\n\n### Links\n\n* @docs.filters\n* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroCategories\n\n---"
  },
  {
    "path": "docs/articles/samples/IntroCategoryBaseline.md",
    "content": "---\nuid: BenchmarkDotNet.Samples.IntroCategoryBaseline\n---\n\n## Sample: IntroCategoryBaseline\n\nThe only way to have several baselines in the same class is to separate them by categories\n  and mark the class with `[GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByCategory)]`.\n\n### Source code\n\n[!code-csharp[IntroCategoryBaseline.cs](../../../samples/BenchmarkDotNet.Samples/IntroCategoryBaseline.cs)]\n\n### Output\n\n```markdown\n|  Method | Categories |      Mean |     Error |    StdDev | Ratio |\n|-------- |----------- |----------:|----------:|----------:|------:|\n|  Time50 |       Fast |  50.46 ms | 0.0745 ms | 0.0697 ms |  1.00 |\n| Time100 |       Fast | 100.47 ms | 0.0955 ms | 0.0893 ms |  1.99 |\n|         |            |           |           |           |       |\n| Time550 |       Slow | 550.48 ms | 0.0525 ms | 0.0492 ms |  1.00 |\n| Time600 |       Slow | 600.45 ms | 0.0396 ms | 0.0331 ms |  1.09 |\n```\n\n### Links\n\n* @docs.baselines\n* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroCategoryBaseline\n\n---"
  },
  {
    "path": "docs/articles/samples/IntroCategoryDiscoverer.md",
    "content": "---\nuid: BenchmarkDotNet.Samples.IntroCategoryDiscoverer\n---\n\n## Sample: IntroCategoryDiscoverer\n\nThe category discovery strategy can be overridden using an instance of `ICategoryDiscoverer`.\n\n### Source code\n\n[!code-csharp[IntroCategoryDiscoverer.cs](../../../samples/BenchmarkDotNet.Samples/IntroCategoryDiscoverer.cs)]\n\n### Output\n\n```markdown\n| Method | Categories |     Mean | Error |\n|------- |----------- |---------:|------:|\n|    Bar |      All,B | 126.5 us |    NA |\n|    Foo |      All,F | 114.0 us |    NA |\n```\n\n### Links\n\n* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroCategoryDiscoverer\n\n---"
  },
  {
    "path": "docs/articles/samples/IntroColdStart.md",
    "content": "---\n#cspell:ignore runstrategy\nuid: BenchmarkDotNet.Samples.IntroColdStart\n---\n\n## Sample: IntroColdStart\n\nIf you want to measure cold start (without the pilot and warmup stage), the `ColdStart` strategy is your choice.\n\n### Usage\n\n```cs\n[SimpleJob(RunStrategy.ColdStart, launchCount:50)]\npublic class MyBenchmarkClass\n```\n\n### Source code\n\n[!code-csharp[IntroColdStart.cs](../../../samples/BenchmarkDotNet.Samples/IntroColdStart.cs)]\n\n### Output\n\n```markdown\nResult       1: 1 op, 1002034900.00 ns, 1.0020 s/op\nResult       2: 1 op, 10219700.00 ns, 10.2197 ms/op\nResult       3: 1 op, 10406200.00 ns, 10.4062 ms/op\nResult       4: 1 op, 10473900.00 ns, 10.4739 ms/op\nResult       5: 1 op, 10449400.00 ns, 10.4494 ms/op\n```\n\n```markdown\n Method |     Mean |      Error |   StdDev |      Min |        Max |   Median |\n------- |---------:|-----------:|---------:|---------:|-----------:|---------:|\n    Foo | 208.7 ms | 1,707.4 ms | 443.5 ms | 10.22 ms | 1,002.0 ms | 10.45 ms |\n```\n\n### Links\n\n* @docs.runstrategy\n* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroColdStart\n\n---\n"
  },
  {
    "path": "docs/articles/samples/IntroComparableComplexParam.md",
    "content": "---\nuid: BenchmarkDotNet.Samples.IntroComparableComplexParam\n---\n\n## Sample: IntroComparableComplexParam\n\nYou can implement `IComparable` (the non generic version) on your complex parameter class if you want custom ordering behavior for your parameter.\n\nOne use case for this is having a parameter class that overrides `ToString()`, but also providing a custom ordering behavior that isn't the alphabetical order of the result of `ToString()`.\n\n### Source code\n\n[!code-csharp[IntroComparableComplexParam.cs](../../../samples/BenchmarkDotNet.Samples/IntroComparableComplexParam.cs)]\n\n### Links\n\n* @docs.parameterization\n* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroComparableComplexParam\n\n---"
  },
  {
    "path": "docs/articles/samples/IntroConfigSource.md",
    "content": "---\nuid: BenchmarkDotNet.Samples.IntroConfigSource\n---\n\n## Sample: IntroConfigSource\n\nYou can define own config attribute.\n\n### Source code\n\n[!code-csharp[IntroConfigSource.cs](../../../samples/BenchmarkDotNet.Samples/IntroConfigSource.cs)]\n\n### Links\n\n* @docs.configs\n* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroConfigSource\n\n---"
  },
  {
    "path": "docs/articles/samples/IntroConfigUnion.md",
    "content": "---\nuid: BenchmarkDotNet.Samples.IntroConfigUnion\n---\n\n## Sample: IntroConfigUnion\n\n### Source code\n\n[!code-csharp[IntroConfigUnion.cs](../../../samples/BenchmarkDotNet.Samples/IntroConfigUnion.cs)]\n\n### Links\n\n* @docs.configs\n* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroConfigUnion\n\n---"
  },
  {
    "path": "docs/articles/samples/IntroCustomMono.md",
    "content": "---\nuid: BenchmarkDotNet.Samples.IntroCustomMono\n---\n\n## Sample: IntroCustomMono\n\nBenchmarkDotNet allows you to compare different runtimes, including Mono.\nIf you apply `[MonoJob]` attribute to your class we use your default mono runtime.\nIf you want to compare different versions of Mono you need to provide use the custom paths.\nYou can do this today by using the overloaded ctor of MonoJob attribute or by specifying the runtime in a fluent way.\n\nThe mono runtime can also operate as an ahead-of-time compiler. Using mono's AOT mode requires providing the AOT compilation\narguments, as well as the path to mono's corlib. (See IntroCustomMonoObjectStyleAot in the below example).\n\n### Source code\n\n[!code-csharp[IntroCustomMono.cs](../../../samples/BenchmarkDotNet.Samples/IntroCustomMono.cs)]\n\n### Links\n\n* @docs.customizing-runtime\n* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroCustomMono\n\n---"
  },
  {
    "path": "docs/articles/samples/IntroCustomMonoArguments.md",
    "content": "---\nuid: BenchmarkDotNet.Samples.IntroCustomMonoArguments\n---\n\n## Sample: IntroCustomMonoArguments\n\n\n### Source code\n\n[!code-csharp[IntroCustomMonoArguments.cs](../../../samples/BenchmarkDotNet.Samples/IntroCustomMonoArguments.cs)]\n\n### Output\n\n```markdown\n| Method |               Job |          Arguments |       Mean |    StdDev |\n|------- |------------------ |------------------- |-----------:|----------:|\n| Sample | Inlining disabled | --optimize=-inline | 19.4252 ns | 0.4525 ns |\n| Sample |  Inlining enabled |  --optimize=inline |  0.0000 ns | 0.0000 ns |\n```\n\n### Links\n\n* @docs.customizing-runtime\n* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroCustomMonoArguments\n\n---"
  },
  {
    "path": "docs/articles/samples/IntroDeferredExecution.md",
    "content": "---\nuid: BenchmarkDotNet.Samples.IntroDeferredExecution\n---\n\n## Sample: IntroDeferredExecution\n\nIn LINQ, execution of a query is usually [deferred](https://learn.microsoft.com/dotnet/standard/linq/deferred-execution-example) until the moment when you actually request the data. If your benchmark just returns `IEnumerable` or `IQueryable` it's not measuring the execution of the query, just the creation.\n\nThis is why we decided to warn you about this issue whenever it happens:\n\n```log\nBenchmark IntroDeferredExecution.Wrong returns a deferred execution result (IEnumerable<Int32>). You need to either change the method declaration to return a materialized result or consume it on your own. You can use .Consume() extension method to do that.\n```\n\nDon't worry! We are also providing you with a `Consume` extension method which can execute given `IEnumerable` or `IQueryable` and consume its results. All you need to do is to create a [`Consumer`](xref:BenchmarkDotNet.Engines.Consumer) instance, preferably store it in a field (to exclude the cost of creating Consumer from the benchmark itself) and pass it to `Consume` extension method.\n\n**Do not call `.ToArray()` because it's an expensive operation and it might dominate given benchmark!**\n\n### Source code\n\n[!code-csharp[IntroDeferredExecution.cs](../../../samples/BenchmarkDotNet.Samples/IntroDeferredExecution.cs)]\n\n### Links\n\n* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroDeferredExecution\n\n---"
  },
  {
    "path": "docs/articles/samples/IntroDisassembly.md",
    "content": "---\nuid: BenchmarkDotNet.Samples.IntroDisassembly\n---\n\n## Sample: IntroDisassembly\n\n### Source code\n\n[!code-csharp[IntroDisassembly.cs](../../../samples/BenchmarkDotNet.Samples/IntroDisassembly.cs)]\n\n### Output\n\n```x86asm\n; .NET Framework 4.7.2 (CLR 4.0.30319.42000), 32bit LegacyJIT-v4.7.3110.0\n05452718 BenchmarkDotNet.Samples.IntroDisassembly.Sum()\nIL_0000: ldc.r8 0\nIL_0009: stloc.0\n0545271c d9ee            fldz\nIL_000a: ldc.i4.0\nIL_000b: stloc.1\nIL_000c: br.s IL_0017\n0545271e 33c0            xor     eax,eax\nIL_000e: ldloc.0\nIL_000f: ldloc.1\nIL_0010: conv.r8\nIL_0011: add\nIL_0012: stloc.0\n05452720 8945fc          mov     dword ptr [ebp-4],eax\n05452723 db45fc          fild    dword ptr [ebp-4]\n05452726 dec1            faddp   st(1),st\nIL_0013: ldloc.1\nIL_0014: ldc.i4.1\nIL_0015: add\nIL_0016: stloc.1\n05452728 40              inc     eax\nIL_0017: ldloc.1\nIL_0018: ldc.i4.s 64\nIL_001a: blt.s IL_000e\n05452729 83f840          cmp     eax,40h\n0545272c 7cf2            jl      05452720\nIL_001c: ldloc.0\nIL_001d: ret\n0545272e 8be5            mov     esp,ebp\n```\n\n```x86asm\n; .NET Core 2.1.0 (CoreCLR 4.6.26515.07, CoreFX 4.6.26515.06), 64bit RyuJIT\n00007ffa`6c621320 BenchmarkDotNet.Samples.IntroDisassembly.Sum()\nIL_0000: ldc.r8 0\nIL_0009: stloc.0\n00007ffa`6c621323 c4e17857c0      vxorps  xmm0,xmm0,xmm0\nIL_000a: ldc.i4.0\nIL_000b: stloc.1\nIL_000c: br.s IL_0017\n00007ffa`6c621328 33c0            xor     eax,eax\nIL_000e: ldloc.0\nIL_000f: ldloc.1\nIL_0010: conv.r8\nIL_0011: add\nIL_0012: stloc.0\n00007ffa`6c62132a c4e17057c9      vxorps  xmm1,xmm1,xmm1\n00007ffa`6c62132f c4e1732ac8      vcvtsi2sd xmm1,xmm1,eax\n00007ffa`6c621334 c4e17b58c1      vaddsd  xmm0,xmm0,xmm1\nIL_0013: ldloc.1\nIL_0014: ldc.i4.1\nIL_0015: add\nIL_0016: stloc.1\n00007ffa`6c621339 ffc0            inc     eax\nIL_0017: ldloc.1\nIL_0018: ldc.i4.s 64\nIL_001a: blt.s IL_000e\n00007ffa`6c62133b 83f840          cmp     eax,40h\n00007ffa`6c62133e 7cea            jl      00007ffa`6c62132a\nIL_001c: ldloc.0\nIL_001d: ret\n00007ffa`6c621340 c3              ret\n```\n\n```x86asm\nMono 5.12.0 (Visual Studio), 64bit\n Sum\nsub    $0x18,%rsp\nmov    %rsi,(%rsp)\nxorpd  %xmm0,%xmm0\nmovsd  %xmm0,0x8(%rsp)\nxor    %esi,%esi\njmp    2e \nxchg   %ax,%ax\nmovsd  0x8(%rsp),%xmm0\ncvtsi2sd %esi,%xmm1\naddsd  %xmm1,%xmm0\nmovsd  %xmm0,0x8(%rsp)\ninc    %esi\ncmp    $0x40,%esi\njl     18 \nmovsd  0x8(%rsp),%xmm0\nmov    (%rsp),%rsi\nadd    $0x18,%rsp\nretq   \n```\n\n### Links\n\n* @docs.diagnosers\n* @docs.disassembler\n* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroDisassembly\n\n---"
  },
  {
    "path": "docs/articles/samples/IntroDisassemblyAllJits.md",
    "content": "---\nuid: BenchmarkDotNet.Samples.IntroDisassemblyAllJits\n---\n\n## Sample: IntroDisassemblyAllJits\n\nYou can use a single config to compare the generated assembly code for ALL JITs. \n\nBut to allow benchmarking any target platform architecture the project which defines benchmarks has to target **AnyCPU**. \n\n```xml\n<PropertyGroup>\n  <PlatformTarget>AnyCPU</PlatformTarget>\n</PropertyGroup>\n```\n\n### Source code\n\n[!code-csharp[IntroDisassemblyAllJits.cs](../../../samples/BenchmarkDotNet.Samples/IntroDisassemblyAllJits.cs)]\n\n### Output\n\nThe disassembly result can be obtained [here](https://adamsitnik.com/files/disasm/Jit_Devirtualization-disassembly-report.html).\nThe file was too big to embed it in this doc page.\n\n### Links\n\n* @docs.diagnosers\n* @docs.disassembler\n* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroDisassemblyAllJits\n\n---"
  },
  {
    "path": "docs/articles/samples/IntroDisassemblyDry.md",
    "content": "---\nuid: BenchmarkDotNet.Samples.IntroDisassemblyDry\n---\n\n## Sample: IntroDisassemblyDry\n\n**Getting only the Disassembly without running the benchmarks for a long time.**\n\nSometimes you might be interested only in the disassembly, not the results of the benchmarks.\nIn that case you can use **Job.Dry** which runs the benchmark only **once**.\n\n### Source code\n\n[!code-csharp[IntroDisassemblyDry.cs](../../../samples/BenchmarkDotNet.Samples/IntroDisassemblyDry.cs)]\n\n### Links\n\n* @docs.diagnosers\n* @docs.disassembler\n* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroDisassemblyDry\n\n---"
  },
  {
    "path": "docs/articles/samples/IntroDisassemblyRyuJit.md",
    "content": "---\nuid: BenchmarkDotNet.Samples.IntroDisassemblyRyuJit\n---\n\n## Sample: IntroDisassemblyRyuJit\n\n### Source code\n\n[!code-csharp[IntroDisassemblyRyuJit.cs](../../../samples/BenchmarkDotNet.Samples/IntroDisassemblyRyuJit.cs)]\n\n### Output\n\n![](../../images/disasm-demo.png)\n\n### Links\n\n* @docs.diagnosers\n* @docs.disassembler\n* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroDisassemblyRyuJit\n\n---"
  },
  {
    "path": "docs/articles/samples/IntroDotMemoryDiagnoser.md",
    "content": "---\nuid: BenchmarkDotNet.Samples.IntroDotMemoryDiagnoser\n---\n\n## Sample: IntroDotMemoryDiagnoser\n\nIf you want to get a memory allocation profile of your benchmarks, just add the `[DotMemoryDiagnoser]` attribute, as shown below.\nAs a result, BenchmarkDotNet performs bonus benchmark runs using attached\n  [dotMemory Command-Line Profiler](https://www.jetbrains.com/help/dotmemory/Working_with_dotMemory_Command-Line_Profiler.html).\nThe obtained dotMemory workspaces are saved to the `artifacts` folder.\nThese dotMemory workspaces can be opened using the [standalone dotMemory](https://www.jetbrains.com/dotmemory/),\n  or [dotMemory in Rider](https://www.jetbrains.com/help/rider/Memory_profiling_of_.NET_code.html).\n\n### Source code\n\n[!code-csharp[IntroDotMemoryDiagnoser.cs](../../../samples/BenchmarkDotNet.Samples/IntroDotMemoryDiagnoser.cs)]\n\n### Links\n\n* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroDotMemoryDiagnoser\n\n---"
  },
  {
    "path": "docs/articles/samples/IntroDotTraceDiagnoser.md",
    "content": "---\nuid: BenchmarkDotNet.Samples.IntroDotTraceDiagnoser\n---\n\n## Sample: IntroDotTraceDiagnoser\n\nIf you want to get a performance profile of your benchmarks, just add the `[DotTraceDiagnoser]` attribute, as shown below.\nAs a result, BenchmarkDotNet performs bonus benchmark runs using attached\n  [dotTrace Command-Line Profiler](https://www.jetbrains.com/help/profiler/Performance_Profiling__Profiling_Using_the_Command_Line.html).\nThe obtained snapshots are saved to the `artifacts` folder.\nThese snapshots can be opened using the [standalone dotTrace](https://www.jetbrains.com/profiler/),\n  or [dotTrace in Rider](https://www.jetbrains.com/help/rider/Performance_Profiling.html).\n\n### Source code\n\n[!code-csharp[IntroDotTraceDiagnoser.cs](../../../samples/BenchmarkDotNet.Samples/IntroDotTraceDiagnoser.cs)]\n\n### Links\n\n* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroDotTraceDiagnoser\n\n---"
  },
  {
    "path": "docs/articles/samples/IntroEnvVars.md",
    "content": "---\nuid: BenchmarkDotNet.Samples.IntroEnvVars\n---\n\n## Sample: IntroEnvVars\n\nYou can configure custom environment variables for the process that is running your benchmarks.\nOne reason for doing this might be checking out how different\n [compilation](https://learn.microsoft.com/dotnet/core/runtime-config/compilation),\n [threading](https://learn.microsoft.com/dotnet/core/runtime-config/threading),\n [garbage collector](https://learn.microsoft.com/dotnet/core/runtime-config/garbage-collector)\n settings affect the performance of .NET Core.\n\n### Source code\n\n[!code-csharp[IntroEnvVars.cs](../../../samples/BenchmarkDotNet.Samples/IntroEnvVars.cs)]\n\n### Links\n\n* @docs.customizing-runtime\n* @docs.configs\n* @docs.jobs\n* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroEnvVars\n\n---"
  },
  {
    "path": "docs/articles/samples/IntroEventPipeProfiler.md",
    "content": "﻿---\nuid: BenchmarkDotNet.Samples.IntroEventPipeProfiler\n---\n\n## Sample: EventPipeProfiler\n\nThe `EventPipeProfiler` can be enabled using the `[EventPipeProfiler(...)]` attribute. This attribute takes the following profiles:\n - `CpuSampling` - Useful for tracking CPU usage and general .NET runtime information. This is the default option.\n - `GcVerbose` - Tracks GC collections and samples object allocations.\n - `GcCollect` - Tracks GC collections only at very low overhead.\n - `Jit` - Logging when Just in time (JIT) compilation occurs. Logging of the internal workings of the Just In Time compiler. This is fairly verbose. It details decisions about interesting optimization (like inlining and tail call)\n\n### Source code\n\n[!code-csharp[EventPipeProfiler.cs](../../../samples/BenchmarkDotNet.Samples/IntroEventPipeProfiler.cs)]\n\n### Output\n\nThe output should contain information about the exported trace file which can be analyzed using [SpeedScope](https://www.speedscope.app/).\n\n```markdown\n// * Diagnostic Output - EventPipeProfiler *\nExported 1 trace file(s). Example:\nC:\\Work\\BenchmarkDotNet\\samples\\BenchmarkDotNet.Samples\\BenchmarkDotNet.Artifacts\\BenchmarkDotNet.Samples.IntroEventPipeProfiler.Sleep-20200406-090113.speedscope.json\n```\n"
  },
  {
    "path": "docs/articles/samples/IntroEventPipeProfilerAdvanced.md",
    "content": "﻿---\nuid: BenchmarkDotNet.Samples.IntroEventPipeProfilerAdvanced\n---\n\n## Sample: EventPipeProfilerAdvanced\n\nThe most advanced and powerful way to use `EventPipeProfiler` is a custom configuration. As you can see the below configuration adds `EventPipeProfiler` that constructor can take the profile and/or a list of providers. \nBoth `EventPipeProfiler` and `dotnet trace` use the `Microsoft.Diagnostics.NETCore.Client` package internally. So before you start using the custom configuration of this profiler, it is worth reading the documentation [here](https://github.com/dotnet/diagnostics/blob/main/documentation/dotnet-trace-instructions.md) and [here](https://learn.microsoft.com/dotnet/core/diagnostics/dotnet-trace#dotnet-trace-collect) where you can find more information about how to configure provider list.\n\n### Source code\n\n[!code-csharp[EventPipeProfilerAdvanced.cs](../../../samples/BenchmarkDotNet.Samples/IntroEventPipeProfilerAdvanced.cs)]\n\n### Output\n\nThe output should contain information about the exported trace file which can be analyzed using [SpeedScope](https://www.speedscope.app/).\n\n```markdown\n// * Diagnostic Output - EventPipeProfiler *\nExported 1 trace file(s). Example:\nC:\\Work\\BenchmarkDotNet\\samples\\BenchmarkDotNet.Samples\\BenchmarkDotNet.Artifacts\\BenchmarkDotNet.Samples.IntroEventPipeProfilerAdvanced.RentAndReturn_Shared-20200406-090136.speedscope.json\n```\n"
  },
  {
    "path": "docs/articles/samples/IntroExceptionDiagnoser.md",
    "content": "---\nuid: BenchmarkDotNet.Samples.IntroExceptionDiagnoser\n---\n\n## Sample: IntroExceptionDiagnoser\n\nThe `ExceptionDiagnoser` uses [AppDomain.FirstChanceException](https://learn.microsoft.com/en-us/dotnet/api/system.appdomain.firstchanceexception) API to report:\n\n* Exception frequency: The number of exceptions thrown during the operations divided by the number of operations.\n\n### Source code\n\n[!code-csharp[IntroExceptionDiagnoser.cs](../../../samples/BenchmarkDotNet.Samples/IntroExceptionDiagnoser.cs)]\n\n### Output\n\n|                 Method |     Mean |     Error |    StdDev | Exception frequency |\n|----------------------- |---------:|----------:|----------:|--------------------:|\n| ThrowExceptionRandomly | 4.936 us | 0.1542 us | 0.4499 us |              0.1381 |\n\n### Links\n\n* @docs.diagnosers\n* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroExceptionDiagnoser\n\n---"
  },
  {
    "path": "docs/articles/samples/IntroExport.md",
    "content": "---\nuid: BenchmarkDotNet.Samples.IntroExport\n---\n\n## Sample: IntroExport\n\nBenchmarkDotNet has a lot of predefined exporters.\n\n### Source code\n\n[!code-csharp[IntroExport.cs](../../../samples/BenchmarkDotNet.Samples/IntroExport.cs)]\n\n### Links\n\n* @docs.exporters\n* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroExport\n\n---"
  },
  {
    "path": "docs/articles/samples/IntroExportJson.md",
    "content": "---\nuid: BenchmarkDotNet.Samples.IntroExportJson\n---\n\n## Sample: IntroExportJson\n\nBenchmarkDotNet has a set of json exporters. You can customize the following properties of these exporters:\n\n* `fileNameSuffix`: a string which be placed in the end of target file name.\n* `indentJson`=`false`/`true`: should we format json or not.\n* `excludeMeasurements`=`false`/`true`: should we exclude detailed information about measurements or not\n  (the final summary with statistics will be in the json file anyway).\n\n### Source code\n\n[!code-csharp[IntroExportJson.cs](../../../samples/BenchmarkDotNet.Samples/IntroExportJson.cs)]\n\n### Output\n\nExample of `IntroJsonExport-report-brief.json`:\n\n```js\n{\n   \"Title\":\"IntroJsonExport\",\n   \"HostEnvironmentInfo\":{\n      \"BenchmarkDotNetCaption\":\"BenchmarkDotNet-Dev.Core\",\n      \"BenchmarkDotNetVersion\":\"0.9.9.0\",\n      \"OsVersion\":\"Microsoft Windows NT 6.2.9200.0\",\n      \"ProcessorName\":{\n         \"IsValueCreated\":true,\n         \"Value\":\"Intel(R) Core(TM) i7-4702MQ CPU 2.20GHz\"\n      },\n      \"ProcessorCount\":8,\n      \"ClrVersion\":\"MS.NET 4.0.30319.42000\",\n      \"Architecture\":\"64-bit\",\n      \"HasAttachedDebugger\":false,\n      \"HasRyuJit\":true,\n      \"Configuration\":\"RELEASE\",\n      \"JitModules\":\"clrjit-v4.6.1586.0\",\n      \"DotNetCliVersion\":\"1.0.0-preview2-003121\",\n      \"ChronometerFrequency\":2143474,\n      \"HardwareTimerKind\":\"Tsc\"\n   },\n   \"Benchmarks\":[\n      {\n         \"ShortInfo\":\"IntroJsonExport_Sleep10\",\n         \"Namespace\":\"BenchmarkDotNet.Samples.Intro\",\n         \"Type\":\"IntroJsonExport\",\n         \"Method\":\"Sleep10\",\n         \"MethodTitle\":\"Sleep10\",\n         \"Parameters\":\"\",\n         \"Properties\":{\n            \"Mode\":\"Throughput\",\n            \"Platform\":\"Host\",\n            \"Jit\":\"Host\",\n            \"Runtime\":\"Host\",\n            \"GcMode\":\"Host\",\n            \"WarmupCount\":\"Auto\",\n            \"IterationCount\":\"Auto\",\n            \"LaunchCount\":\"Auto\",\n            \"IterationTime\":\"Auto\",\n            \"Affinity\":\"Auto\"\n         },\n         \"Statistics\":{\n            \"N\":20,\n            \"Min\":10265993.7209375,\n            \"LowerFence\":10255329.082734371,\n            \"Q1\":10337369.528437499,\n            \"Median\":10360382.6953125,\n            \"Mean\":10362283.085796878,\n            \"Q3\":10392063.158906251,\n            \"UpperFence\":10474103.60460938,\n            \"Max\":10436008.3209375,\n            \"InterquartileRange\":54693.630468752235,\n            \"Outliers\":[\n               \n            ],\n            \"StandardError\":10219.304338928456,\n            \"Variance\":2088683623.4328396,\n            \"StandardDeviation\":45702.118369205156,\n            \"Skewness\":-0.1242777170069375,\n            \"Kurtosis\":2.31980277935226,\n            \"ConfidenceInterval\":{\n               \"Mean\":10362283.085796878,\n               \"Error\":10219.304338928456,\n               \"Level\":6,\n               \"Margin\":20029.836504299772,\n               \"Lower\":10342253.249292579,\n               \"Upper\":10382312.922301177\n            },\n            \"Percentiles\":{\n               \"P0\":10265993.7209375,\n               \"P25\":10338555.905625,\n               \"P50\":10360382.6953125,\n               \"P67\":10373496.555659376,\n               \"P80\":10400703.4841875,\n               \"P85\":10417280.326718749,\n               \"P90\":10424125.595812501,\n               \"P95\":10435620.51609375,\n               \"P100\":10436008.3209375\n            }\n         }\n      },{\n         \"ShortInfo\":\"IntroJsonExport_Sleep20\",\n         \"Namespace\":\"BenchmarkDotNet.Samples.Intro\",\n         \"Type\":\"IntroJsonExport\",\n         \"Method\":\"Sleep20\",\n         \"MethodTitle\":\"Sleep20\",\n         \"Parameters\":\"\",\n         \"Properties\":{\n            \"Mode\":\"Throughput\",\n            \"Platform\":\"Host\",\n            \"Jit\":\"Host\",\n            \"Runtime\":\"Host\",\n            \"GcMode\":\"Host\",\n            \"WarmupCount\":\"Auto\",\n            \"IterationCount\":\"Auto\",\n            \"LaunchCount\":\"Auto\",\n            \"IterationTime\":\"Auto\",\n            \"Affinity\":\"Auto\"\n         },\n         \"Statistics\":{\n            \"N\":20,\n            \"Min\":20258672.37,\n            \"LowerFence\":20206333.269843742,\n            \"Q1\":20325342.761249997,\n            \"Median\":20362636.192500003,\n            \"Mean\":20360791.931687497,\n            \"Q3\":20404682.4221875,\n            \"UpperFence\":20523691.913593754,\n            \"Max\":20422396.073125,\n            \"InterquartileRange\":79339.66093750298,\n            \"Outliers\":[\n               \n            ],\n            \"StandardError\":10728.817907277158,\n            \"Variance\":2302150673.7502208,\n            \"StandardDeviation\":47980.732317777525,\n            \"Skewness\":-0.50826238372439869,\n            \"Kurtosis\":2.11050327966268,\n            \"ConfidenceInterval\":{\n               \"Mean\":20360791.931687497,\n               \"Error\":10728.817907277158,\n               \"Level\":6,\n               \"Margin\":21028.48309826323,\n               \"Lower\":20339763.448589232,\n               \"Upper\":20381820.414785761\n            },\n            \"Percentiles\":{\n               \"P0\":20258672.37,\n               \"P25\":20327638.975312497,\n               \"P50\":20362636.192500003,\n               \"P67\":20391669.3762875,\n               \"P80\":20406370.68625,\n               \"P85\":20412542.034406248,\n               \"P90\":20414412.5376875,\n               \"P95\":20416606.697718751,\n               \"P100\":20422396.073125\n            }\n         }\n      }\n   ]\n}\n```\n\n### Links\n\n* @docs.exporters\n* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroExportJson\n\n---\n"
  },
  {
    "path": "docs/articles/samples/IntroExportXml.md",
    "content": "---\nuid: BenchmarkDotNet.Samples.IntroExportXml\n---\n\n## Sample: IntroExportXml\n\nBenchmarkDotNet has a set of XML exporters. You can customize the following properties of these exporters:\n\n* `fileNameSuffix`: a string which be placed in the end of target file name.\n* `indentXml`=`false`/`true`: should we format xml or not.\n* `excludeMeasurements`=`false`/`true`: should we exclude detailed information about measurements or not\n  (the final summary with statistics will be in the XML file anyway).\n\n\n### Source code\n\n[!code-csharp[IntroExportXml.cs](../../../samples/BenchmarkDotNet.Samples/IntroExportXml.cs)]\n\n### Output\n\nExample of `IntroXmlExport-report-brief.xml`:\n\n```xml\n<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Summary>\n  <Title>IntroXmlExport</Title>\n  <HostEnvironmentInfo>\n    <BenchmarkDotNetCaption>BenchmarkDotNet</BenchmarkDotNetCaption>\n    <BenchmarkDotNetVersion>0.10.9.20170805-develop</BenchmarkDotNetVersion>\n    <OsVersion>Windows 10 Redstone 2 (10.0.15063)</OsVersion>\n    <ProcessorName>Intel Core i7-3770K CPU 3.50GHz (Ivy Bridge)</ProcessorName>\n    <ProcessorCount>8</ProcessorCount>\n    <RuntimeVersion>.NET Framework 4.7 (CLR 4.0.30319.42000)</RuntimeVersion>\n    <Architecture>64bit</Architecture>\n    <HasAttachedDebugger>False</HasAttachedDebugger>\n    <HasRyuJit>True</HasRyuJit>\n    <Configuration>RELEASE</Configuration>\n    <JitModules>clrjit-v4.7.2101.1</JitModules>\n    <DotNetSdkVersion>1.0.4</DotNetSdkVersion>\n    <ChronometerFrequency>\n      <Hertz>3410220</Hertz>\n    </ChronometerFrequency>\n    <HardwareTimerKind>Tsc</HardwareTimerKind>\n  </HostEnvironmentInfo>\n  <Benchmarks>\n    <Benchmark>\n      <DisplayInfo>IntroXmlExport.Sleep10: DefaultJob</DisplayInfo>\n      <Namespace>BenchmarkDotNet.Samples.Intro</Namespace>\n      <Type>IntroXmlExport</Type>\n      <Method>Sleep10</Method>\n      <MethodTitle>Sleep10</MethodTitle>\n      <Statistics>\n        <N>15</N>\n        <Min>10989865.8785938</Min>\n        <LowerFence>10989836.0967969</LowerFence>\n        <Q1>10990942.6053125</Q1>\n        <Median>10991249.5870313</Median>\n        <Mean>10991270.0524583</Mean>\n        <Q3>10991680.2776563</Q3>\n        <UpperFence>10992786.7861719</UpperFence>\n        <Max>10992115.5501563</Max>\n        <InterquartileRange>737.672343749553</InterquartileRange>\n        <StandardError>148.484545262958</StandardError>\n        <Variance>330714.902729213</Variance>\n        <StandardDeviation>575.07817097262</StandardDeviation>\n        <Skewness>-0.67759778074187</Skewness>\n        <Kurtosis>3.14296703520386</Kurtosis>\n        <ConfidenceInterval>\n          <N>15</N>\n          <Mean>10991270.0524583</Mean>\n          <StandardError>148.484545262958</StandardError>\n          <Level>L999</Level>\n          <Margin>614.793505974065</Margin>\n          <Lower>10990655.2589524</Lower>\n          <Upper>10991884.8459643</Upper>\n        </ConfidenceInterval>\n        <Percentiles>\n          <P0>10989865.8785938</P0>\n          <P25>10991027.3689063</P25>\n          <P50>10991249.5870313</P50>\n          <P67>10991489.490875</P67>\n          <P80>10991696.7722187</P80>\n          <P85>10991754.5031875</P85>\n          <P90>10991933.1939688</P90>\n          <P95>10992067.441125</P95>\n          <P100>10992115.5501563</P100>\n        </Percentiles>\n      </Statistics>\n    </Benchmark>\n  </Benchmarks>\n</Summary>\n```\n\n### Links\n\n* @docs.exporters\n* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroExportXml\n\n---"
  },
  {
    "path": "docs/articles/samples/IntroFilters.md",
    "content": "---\nuid: BenchmarkDotNet.Samples.IntroFilters\n---\n\n## Sample: IntroFilters\n\nYou can either use one of the predefined `Filter` types or create a custom type which implements `IFilter` interface. \n\n### Source code\n\n[!code-csharp[IntroFilters.cs](../../../samples/BenchmarkDotNet.Samples/IntroFilters.cs)]\n\n### Links\n\n* @docs.filters\n* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroFilters\n\n---"
  },
  {
    "path": "docs/articles/samples/IntroFluentConfigBuilder.md",
    "content": "---\nuid: BenchmarkDotNet.Samples.IntroFluentConfigBuilder\n---\n\n## Sample: IntroFluentConfigBuilder\n\nThere is no need to create new Config type, you can simply use fluent interface.\n\n### Source code\n\n[!code-csharp[IntroFluentConfigBuilder.cs](../../../samples/BenchmarkDotNet.Samples/IntroFluentConfigBuilder.cs)]\n\n### Links\n\n* @docs.configs\n* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroFluentConfigBuilder\n\n---"
  },
  {
    "path": "docs/articles/samples/IntroGcMode.md",
    "content": "---\nuid: BenchmarkDotNet.Samples.IntroGcMode\n---\n\n## Sample: IntroGcMode\n\n### Source code\n\n[!code-csharp[IntroGcMode.cs](../../../samples/BenchmarkDotNet.Samples/IntroGcMode.cs)]\n\n### Output\n\n\n### Links\n\n* @docs.jobs\n* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroGcMode\n\n---"
  },
  {
    "path": "docs/articles/samples/IntroGenericTypeArguments.md",
    "content": "---\nuid: BenchmarkDotNet.Samples.IntroGenericTypeArguments\n---\n\n## Sample: IntroGenericTypeArguments\n\n### Source code\n\n[!code-csharp[IntroGenericTypeArguments.cs](../../../samples/BenchmarkDotNet.Samples/IntroGenericTypeArguments.cs)]\n\n### Links\n\n* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroGenericTypeArguments\n\n---"
  },
  {
    "path": "docs/articles/samples/IntroHardwareCounters.md",
    "content": "---\nuid: BenchmarkDotNet.Samples.IntroHardwareCounters\n---\n\n## Sample: IntroHardwareCounters\n\nThis diagnoser is not enabled in explicit way as the other diagnosers.\nYou need to specify `[HardwareCounters]` and we choose the right diagnoser in the runtime.\n\n### Source code\n\n[!code-csharp[IntroHardwareCounters.cs](../../../samples/BenchmarkDotNet.Samples/IntroHardwareCounters.cs)]\n\n### Output\n\n|             Method |        Mean | Mispredict rate | BranchInstructions/Op | BranchMispredictions/Op |\n|------------------- |------------ |---------------- |---------------------- |------------------------ |\n|       SortedBranch |  21.4539 us |           0,04% |                 70121 |                      24 |\n|     UnsortedBranch | 136.1139 us |          23,70% |                 68788 |                   16301 |\n|   SortedBranchless |  28.6705 us |           0,06% |                 35711 |                      22 |\n| UnsortedBranchless |  28.9336 us |           0,05% |                 35578 |                      17 |\n\n### Links\n\n* @docs.diagnosers\n* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroHardwareCounters\n\n---"
  },
  {
    "path": "docs/articles/samples/IntroInProcess.md",
    "content": "---\nuid: BenchmarkDotNet.Samples.IntroInProcess\n---\n\n## Sample: IntroInProcess\n\nInProcessEmitToolchain is our toolchain which does not generate any new executable.\nIt emits IL on the fly and runs it from within the process itself.\nIt can be useful if want to run the benchmarks very fast or if you want to run them for framework which we don't support.\nAn example could be a local build of CoreCLR.\n\n### Usage\n\n```cs\n[InProcessAttribute]\npublic class TypeWithBenchmarks\n{\n}\n```\n\n\n### Source code\n\n[!code-csharp[IntroInProcess.cs](../../../samples/BenchmarkDotNet.Samples/IntroInProcess.cs)]\n\n### Output\n\n\n### Links\n\n* @docs.toolchains\n* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroInProcess\n\n---"
  },
  {
    "path": "docs/articles/samples/IntroInProcessWrongEnv.md",
    "content": "---\nuid: BenchmarkDotNet.Samples.IntroInProcessWrongEnv\n---\n\n## Sample: IntroInProcessWrongEnv\n\n### Source code\n\n[!code-csharp[IntroInProcessWrongEnv.cs](../../../samples/BenchmarkDotNet.Samples/IntroInProcessWrongEnv.cs)]\n\n### Output\n\n\n### Links\n\n* @docs.toolchains\n* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroInProcessWrongEnv\n\n---"
  },
  {
    "path": "docs/articles/samples/IntroInliningDiagnoser.md",
    "content": "---\nuid: BenchmarkDotNet.Samples.IntroInliningDiagnoser\n---\n\n## Sample: IntroInliningDiagnoser\n\nThis sample shows how to add InliningDiagnoser with events from only one namespace (BenchmarkDotNet.Samples).\n\n### Source code\n\n[!code-csharp[IntroInliningDiagnoser.cs](../../../samples/BenchmarkDotNet.Samples/IntroInliningDiagnoser.cs)]"
  },
  {
    "path": "docs/articles/samples/IntroJitStatsDiagnoser.md",
    "content": "---\nuid: BenchmarkDotNet.Samples.IntroJitStatsDiagnoser\n---\n\n## Sample: IntroJitStatsDiagnoser\n\nThis diagnoser shows various stats from the JIT compiler that were collected during entire benchmark run (warmup phase and BenchmarkDotNet-generated boilerplate code are included):\n* Amount of JITted methods.\n* Amount of [tiered methods](https://learn.microsoft.com/en-us/dotnet/core/whats-new/dotnet-core-3-0#tiered-compilation).\n* How much memory JIT allocated during the benchmark.\n\n### Restrictions\n\n* Windows only\n\n### Source code\n\n[!code-csharp[IntroJitStatsDiagnoser.cs](../../../samples/BenchmarkDotNet.Samples/IntroJitStatsDiagnoser.cs)]\n\n### Output\n\n| Method |     Mean |    Error |   StdDev | Methods JITted | Methods Tiered | JIT allocated memory |\n|------- |---------:|---------:|---------:|---------------:|---------------:|---------------------:|\n|  Sleep | 15.50 ms | 0.052 ms | 0.048 ms |          1,102 |            214 |            221,736 B |\n\n### Links\n\n* @docs.diagnosers\n* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroJitStatsDiagnoser\n\n---"
  },
  {
    "path": "docs/articles/samples/IntroJobBaseline.md",
    "content": "﻿---\nuid: BenchmarkDotNet.Samples.IntroJobBaseline\n---\n\n## Sample: IntroJobBaseline\n\nIf you want to compare several runtime configuration,\n  you can mark one of your jobs with `baseline = true`.\n\n### Source code\n\n[!code-csharp[IntroJobBaseline.cs](../../../samples/BenchmarkDotNet.Samples/IntroJobBaseline.cs)]\n\n### Output\n\n```ini\nBenchmarkDotNet=v0.10.12, OS=Windows 10 Redstone 3 [1709, Fall Creators Update] (10.0.16299.192)\nProcessor=Intel Core i7-6700HQ CPU 2.60GHz (Skylake), ProcessorCount=8\nFrequency=2531249 Hz, Resolution=395.0619 ns, Timer=TSC\n.NET Core SDK=2.0.3\n  [Host]     : .NET Core 2.0.3 (Framework 4.6.25815.02), 64bit RyuJIT\n  Job-MXFYPZ : .NET Framework 4.7 (CLR 4.0.30319.42000), 64bit RyuJIT-v4.7.2600.0\n  Core       : .NET Core 2.0.3 (Framework 4.6.25815.02), 64bit RyuJIT\n  Mono       : Mono 5.4.0 (Visual Studio), 64bit \n```\n\n```markdown\n    Method | Runtime |     Mean |     Error |    StdDev | Ratio | RatioSD |\n---------- |-------- |---------:|----------:|----------:|------:|--------:|\n SplitJoin |     Clr | 19.42 us | 0.2447 us | 0.1910 us |  1.00 |    0.00 |\n SplitJoin |    Core | 13.00 us | 0.2183 us | 0.1935 us |  0.67 |    0.01 |\n SplitJoin |    Mono | 39.14 us | 0.7763 us | 1.3596 us |  2.02 |    0.07 |\n```\n\n### Links\n\n* @docs.baselines\n* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroJobBaseline\n\n---"
  },
  {
    "path": "docs/articles/samples/IntroJoin.md",
    "content": "---\nuid: BenchmarkDotNet.Samples.IntroJoin\n---\n\n## Sample: IntroJoin\n\nIf you are using `BenchmarkSwitcher` and want to run all the benchmarks with a category from all types and join them into one summary table, use the `--join` option (or `BenchmarkSwitcher.RunAllJoined`): \n\n### Source code\n\n[!code-csharp[IntroJoin.cs](../../../samples/BenchmarkDotNet.Samples/IntroJoin.cs)]\n\n### Command line\n\n```\n--join --allCategories=IntroJoinA\n```\n\n### Output\n\n```markdown\n|       Type | Method |     Mean | Error |\n|----------- |------- |---------:|------:|\n| IntroJoin1 |      A | 10.99 ms |    NA |\n| IntroJoin2 |      A | 12.50 ms |    NA |\n```\n\n### Links\n\n* @docs.filters\n* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroJoin\n\n---"
  },
  {
    "path": "docs/articles/samples/IntroLargeAddressAware.md",
    "content": "---\nuid: BenchmarkDotNet.Samples.IntroLargeAddressAware\ntitle: \"Sample: IntroLargeAddressAware\"\n---\n\n## Sample: IntroLargeAddressAware\n\n### Source code\n\n[!code-csharp[IntroLargeAddressAware.cs](../../../samples/BenchmarkDotNet.Samples/IntroLargeAddressAware.cs)]\n\n### Links\n\n* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroLargeAddressAware\n\n---"
  },
  {
    "path": "docs/articles/samples/IntroMaui.md",
    "content": "---\nuid: BenchmarkDotNet.Samples.Maui\n---\n\n## Sample: IntroMaui\n\nTo use BenchmarkDotNet with [.NET MAUI](https://dotnet.microsoft.com/apps/maui), you will need to build a small UI for running benchmarks and displaying the results.\n\n.NET MAUI allows you to run your benchmarks on Android, iOS, Mac Catalyst, and Windows from a single codebase.\n\nOther notes:\n\n* Use `Release` builds when running actual benchmarks.\n* Consider disabling trimming appropriately for your benchmarks.\n\n### Source code\n\n[!code-csharp[MainPage.xaml.cs](../../../samples/BenchmarkDotNet.Samples.Maui/MainPage.xaml.cs)]\n\n### Output\n\n#### Windows\n\n![MAUI Output - Windows](../../images/maui-screenshot-windows.png)\n\n#### Android\n\n![MAUI Output - Android](../../images/maui-screenshot-android.png)\n\n#### iOS\n\n![MAUI Output - iOS](../../images/maui-screenshot-ios.png)\n\n#### Mac Catalyst\n\n![MAUI Output - mac](../../images/maui-screenshot-mac.png)\n\n### Links\n\n* [.NET MAUI Documentation](https://learn.microsoft.com/dotnet/maui/)\n* [Trimming in .NET MAUI](https://learn.microsoft.com/dotnet/maui/deployment/trimming)\n* The permanent link to this sample: @BenchmarkDotNet.Samples.Maui\n\n---\n"
  },
  {
    "path": "docs/articles/samples/IntroMonitoring.md",
    "content": "---\n#cspell:ignore runstrategy\nuid: BenchmarkDotNet.Samples.IntroMonitoring\n---\n\n## Sample: IntroMonitoring\n\nIf a benchmark method takes at least 100ms, you can also use the `Monitoring` strategy.\nIn this case, the pilot stage will be omitted, by default you get 1 iteration = 1 operation\n  (or you can manually set amount of operation in an iteration).\nAlso you can use `[IterationSetup]` and `[IterationCleanup]` in this case: it shouldn't affect time measurements\n  (but it can affect results of MemoryDiagnoser).\nIt's a perfect mode for benchmarks which doesn't have a steady state and the performance distribution is tricky:\n  `Monitoring` will help you to collect a set of measurements and get statistics.\n\n### Usage\n\n```cs\n[SimpleJob(RunStrategy.Monitoring, launchCount: 10, warmupCount: 0, iterationCount: 100)]\npublic class MyBenchmarkClass\n```\n\n### Source code\n\n[!code-csharp[IntroMonitoring.cs](../../../samples/BenchmarkDotNet.Samples/IntroMonitoring.cs)]\n\n### Output\n\n```markdown\nResult       1: 1 op, 61552600.00 ns, 61.5526 ms/op\nResult       2: 1 op, 10141700.00 ns, 10.1417 ms/op\nResult       3: 1 op, 10482900.00 ns, 10.4829 ms/op\nResult       4: 1 op, 50410900.00 ns, 50.4109 ms/op\nResult       5: 1 op, 10421400.00 ns, 10.4214 ms/op\nResult       6: 1 op, 20556100.00 ns, 20.5561 ms/op\nResult       7: 1 op, 70473200.00 ns, 70.4732 ms/op\nResult       8: 1 op, 50581700.00 ns, 50.5817 ms/op\nResult       9: 1 op, 10559000.00 ns, 10.5590 ms/op\nResult      10: 1 op, 70496300.00 ns, 70.4963 ms/op\n```\n\n| Method |     Mean |    Error |   StdDev |      Min |       Q1 |       Q3 |      Max |\n|------- |---------:|---------:|---------:|---------:|---------:|---------:|---------:|\n|    Foo | 36.57 ms | 40.03 ms | 26.47 ms | 10.14 ms | 10.48 ms | 61.55 ms | 70.50 ms |\n\n### Links\n\n* @docs.runstrategy\n* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroMonitoring\n\n---\n"
  },
  {
    "path": "docs/articles/samples/IntroMultimodal.md",
    "content": "---\nuid: BenchmarkDotNet.Samples.IntroMultimodal\n---\n\n## Sample: IntroMultimodal\n\n\n### Source code\n\n[!code-csharp[IntroMultimodal.cs](../../../samples/BenchmarkDotNet.Samples/IntroMultimodal.cs)]\n\n### Output\n\n```markdown\n      Method |     Mean |      Error |      StdDev |   Median | MValue |\n------------ |---------:|-----------:|------------:|---------:|-------:|\n    Unimodal | 100.5 ms |  0.0713 ms |   0.0667 ms | 100.5 ms |  2.000 |\n     Bimodal | 144.5 ms | 16.9165 ms |  49.8787 ms | 100.6 ms |  3.571 |\n    Trimodal | 182.5 ms | 27.4285 ms |  80.8734 ms | 200.5 ms |  4.651 |\n Quadrimodal | 226.6 ms | 37.2269 ms | 109.7644 ms | 200.7 ms |  5.882 |\n\n// * Warnings *\nMultimodalDistribution\n  IntroMultimodal.Bimodal: MainJob     -> It seems that the distribution is bimodal (mValue = 3.57)\n  IntroMultimodal.Trimodal: MainJob    -> It seems that the distribution is multimodal (mValue = 4.65)\n  IntroMultimodal.Quadrimodal: MainJob -> It seems that the distribution is multimodal (mValue = 5.88)\n```\n\n### Links\n\n* @docs.statistics\n* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroMultimodal\n\n---"
  },
  {
    "path": "docs/articles/samples/IntroNativeMemory.md",
    "content": "---\nuid: BenchmarkDotNet.Samples.IntroNativeMemory\n---\n\n## Sample: IntroNativeMemory\n\nThe `NativeMemoryProfiler` uses `EtwProfiler` to profile the code using ETW and adds the extra columns `Allocated native memory` and `Native memory leak` to the benchmark results table.\n\n### Source code\n\n[!code-csharp[IntroNativeMemory.cs](../../../samples/BenchmarkDotNet.Samples/IntroNativeMemory.cs)]\n\n### Output\n\n|                Method |         Mean |         Error |       StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated | Allocated native memory | Native memory leak |\n|---------------------- |-------------:|--------------:|-------------:|------:|------:|------:|----------:|------------------------:|-------------------:|\n|       BitmapWithLeaks | 73,456.43 ns |  22,498.10 ns | 1,233.197 ns |     - |     - |     - |     177 B |                 13183 B |            11615 B |\n|                Bitmap | 91,590.08 ns | 101,468.12 ns | 5,561.810 ns |     - |     - |     - |     180 B |                 12624 B |                  - |\n|          AllocHGlobal |     79.91 ns |      43.93 ns |     2.408 ns |     - |     - |     - |         - |                    80 B |                  - |\n| AllocHGlobalWithLeaks |    103.50 ns |     153.21 ns |     8.398 ns |     - |     - |     - |         - |                    80 B |               80 B |\n\n### Profiling memory leaks\n\nThe BenchmarkDotNet repeats benchmarking function many times. Sometimes it can cause a memory overflow. In this case, the BenchmarkDotNet shows the message: \n\n```ini\nOutOfMemoryException!\nBenchmarkDotNet continues to run additional iterations until desired accuracy level is achieved. It's possible only if the benchmark method doesn't have any side-effects.\nIf your benchmark allocates memory and keeps it alive, you are creating a memory leak.\nYou should redesign your benchmark and remove the side-effects. You can use `OperationsPerInvoke`, `IterationSetup` and `IterationCleanup` to do that.\n```\n\nIn this case, you should try to reduce the number of invocation, by adding `[ShortRunJob]` attribute or using `Job.Short` for custom configuration.\n\n### Links\n\n* @docs.diagnosers\n* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroNativeMemory\n\n---"
  },
  {
    "path": "docs/articles/samples/IntroNuGet.md",
    "content": "﻿---\nuid: BenchmarkDotNet.Samples.IntroNuGet\n---\n\n## Sample: IntroNuGet\n\nYou can set specific versions of NuGet dependencies for each job using MsBuild properties in your csproj.\nIt allows comparing different versions of the same package (if there are no breaking changes in API).\n\n### Source code\n\n[!code-csharp[IntroNuGet.cs](../../../samples/BenchmarkDotNet.Samples/IntroNuGet.cs)]\n\n### Output\n\n| Method                    | Job    | Arguments           | Mean     | Error     | StdDev    |\n|-------------------------- |------- |-------------------- |---------:|----------:|----------:|\n| ToImmutableArrayBenchmark | v9.0.0 | /p:SciVersion=9.0.0 | 1.173 μs | 0.0057 μs | 0.0086 μs |\n| ToImmutableArrayBenchmark | v9.0.3 | /p:SciVersion=9.0.3 | 1.173 μs | 0.0038 μs | 0.0058 μs |\n| ToImmutableArrayBenchmark | v9.0.5 | /p:SciVersion=9.0.5 | 1.172 μs | 0.0107 μs | 0.0157 μs |\n\n### Links\n\n* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroNuGet\n\n---"
  },
  {
    "path": "docs/articles/samples/IntroOrderAttr.md",
    "content": "---\nuid: BenchmarkDotNet.Samples.IntroOrderAttr\n---\n\n## Sample: IntroOrderAttr\n\n### Source code\n\n[!code-csharp[IntroOrderAttr.cs](../../../samples/BenchmarkDotNet.Samples/IntroOrderAttr.cs)]\n\n### Links\n\n* @docs.orderers\n* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroOrderAttr\n\n---"
  },
  {
    "path": "docs/articles/samples/IntroOrderManual.md",
    "content": "---\nuid: BenchmarkDotNet.Samples.IntroOrderManual\n---\n\n## Sample: IntroOrderManual\n\n### Source code\n\n[!code-csharp[IntroOrderManual.cs](../../../samples/BenchmarkDotNet.Samples/IntroOrderManual.cs)]\n\n### Links\n\n* @docs.orderers\n* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroOrderManual\n\n---"
  },
  {
    "path": "docs/articles/samples/IntroOutliers.md",
    "content": "---\nuid: BenchmarkDotNet.Samples.IntroOutliers\n---\n\n## Sample: IntroOutliers\n\n### Source code\n\n[!code-csharp[IntroOutliers.cs](../../../samples/BenchmarkDotNet.Samples/IntroOutliers.cs)]\n\n### Output\n\n```markdown\n Method |                 Job | OutlierMode |     Mean |       Error |      StdDev |\n------- |-------------------- |------------ |---------:|------------:|------------:|\n    Foo |  DontRemoveOutliers |  DontRemove | 150.5 ms | 239.1911 ms | 158.2101 ms |\n    Foo | RemoveUpperOutliers | RemoveUpper | 100.5 ms |   0.1931 ms |   0.1149 ms |\n\n// * Hints *\nOutliers\n  IntroOutliers.Foo: DontRemoveOutliers  -> 1 outlier  was  detected\n  IntroOutliers.Foo: RemoveUpperOutliers -> 1 outlier  was  removed\n```\n\n### Links\n\n* @docs.statistics\n* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroOutliers\n\n---"
  },
  {
    "path": "docs/articles/samples/IntroParams.md",
    "content": "---\nuid: BenchmarkDotNet.Samples.IntroParams\n---\n\n## Sample: IntroParams\n\nYou can mark one or several fields or properties in your class by\n  the [`[Params]`](xref:BenchmarkDotNet.Attributes.ParamsAttribute) attribute.\nIn this attribute, you can specify set of values.\nEvery value must be a compile-time constant.\nAs a result, you will get results for each combination of params values.\n\n### Source code\n\n[!code-csharp[IntroParams.cs](../../../samples/BenchmarkDotNet.Samples/IntroParams.cs)]\n\n### Output\n\n```markdown\n|    Method |   A |  B |     Mean |   Error |  StdDev |\n|---------- |---- |--- |---------:|--------:|--------:|\n| Benchmark | 100 | 10 | 115.3 ms | 0.13 ms | 0.12 ms |\n| Benchmark | 100 | 20 | 125.4 ms | 0.14 ms | 0.12 ms |\n| Benchmark | 200 | 10 | 215.5 ms | 0.19 ms | 0.18 ms |\n| Benchmark | 200 | 20 | 225.4 ms | 0.17 ms | 0.16 ms |\n```\n\n### Links\n\n* @docs.parameterization\n* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroParams\n\n---"
  },
  {
    "path": "docs/articles/samples/IntroParamsAllValues.md",
    "content": "---\nuid: BenchmarkDotNet.Samples.IntroParamsAllValues\n---\n\n## Sample: IntroParamsAllValues\n\nIf you want to use all possible values of an `enum` or another type with a small number of values, you can use the [`[ParamsAllValues]`](xref:BenchmarkDotNet.Attributes.ParamsAllValuesAttribute) attribute, instead of listing all the values by hand. The types supported by the attribute are:\n\n* `bool`\n* any `enum` that is not marked with `[Flags]`\n* `Nullable<T>`, where `T` is an enum or boolean\n\n### Source code\n\n[!code-csharp[IntroParamsAllValues.cs](../../../samples/BenchmarkDotNet.Samples/IntroParamsAllValues.cs)]\n\n### Output\n\n```markdown\n    Method |     E |     B |     Mean | Error |\n---------- |------ |------ |---------:|------:|\n Benchmark |   One |     ? | 101.4 ms |    NA |\n Benchmark |   One | False | 111.1 ms |    NA |\n Benchmark |   One |  True | 122.0 ms |    NA |\n Benchmark |   Two |     ? | 201.3 ms |    NA |\n Benchmark |   Two | False | 212.1 ms |    NA |\n Benchmark |   Two |  True | 221.3 ms |    NA |\n Benchmark | Three |     ? | 301.4 ms |    NA |\n Benchmark | Three | False | 311.5 ms |    NA |\n Benchmark | Three |  True | 320.8 ms |    NA |\n```\n\n### Links\n\n* @docs.parameterization\n* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroParamsAllValues\n\n---"
  },
  {
    "path": "docs/articles/samples/IntroParamsPriority.md",
    "content": "---\nuid: BenchmarkDotNet.Samples.IntroParamsPriority\n---\n\n## Sample: IntroParamsPriority\n\nIn order to sort columns of parameters in the results table you can use the Property `Priority` inside the params attribute. The priority range is `[Int32.MinValue;Int32.MaxValue]`, lower priorities will appear earlier in the column order. The default priority is set to `0`.\n\n### Source code\n\n[!code-csharp[IntroParamsPriority.cs](../../../samples/BenchmarkDotNet.Samples/IntroParamsPriority.cs)]\n\n### Output\n\n```markdown\n|    Method |  B |   A |     Mean |   Error |  StdDev |\n|---------- |--- |---- |---------:|--------:|--------:|\n| Benchmark | 10 | 100 | 115.4 ms | 0.12 ms | 0.11 ms |\n```\n\n### Links\n\n* Priority BaseClass [`PriorityAttribute.cs`](xref:BenchmarkDotNet.Attributes.PriorityAttribute)\n* @docs.parameterization\n* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroParamsPriority\n\n---\n"
  },
  {
    "path": "docs/articles/samples/IntroParamsSource.md",
    "content": "﻿---\nuid: BenchmarkDotNet.Samples.IntroParamsSource\n---\n\n## Sample: IntroParamsSource\n\nIn case you want to use a lot of values, you should use\n  [`[ParamsSource]`](xref:BenchmarkDotNet.Attributes.ParamsSourceAttribute)\nYou can mark one or several fields or properties in your class by the\n  [`[Params]`](xref:BenchmarkDotNet.Attributes.ParamsAttribute) attribute.\nIn this attribute, you have to specify the name of public method/property which is going to provide the values\n  (something that implements `IEnumerable`).\nThe source may be instance or static. If the source is not in the same type as the benchmark, the type containing the source must be specified in the attribute constructor.\n\n### Source code\n\n[!code-csharp[IntroParamsSource.cs](../../../samples/BenchmarkDotNet.Samples/IntroParamsSource.cs)]\n\n### Output\n\n```markdown\n|    Method |  B |   A |     Mean |   Error |  StdDev |\n|---------- |--- |---- |---------:|--------:|--------:|\n| Benchmark | 10 | 100 | 115.5 ms | 0.17 ms | 0.16 ms |\n| Benchmark | 10 | 200 | 215.6 ms | 0.15 ms | 0.14 ms |\n| Benchmark | 20 | 100 | 125.5 ms | 0.19 ms | 0.18 ms |\n| Benchmark | 20 | 200 | 225.5 ms | 0.23 ms | 0.22 ms |\n```\n\n### Remarks\n\n**A remark about IParam.**\n\nYou don't need to use `IParam` anymore since `0.11.0`.\nJust use complex types as you wish and override `ToString` method to change the display names used in the results.\n\n\n### Links\n\n* @docs.parameterization\n* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroParamsSource\n\n---"
  },
  {
    "path": "docs/articles/samples/IntroPercentiles.md",
    "content": "---\nuid: BenchmarkDotNet.Samples.IntroPercentiles\n---\n\n## Sample: IntroPercentiles\n\nThe percentile represents a higher boundary for specified percentage of the measurements.\nFor example, 95th percentile = 500ms means that 95% of all samples are not slower than 500ms.\nThis metric is not very useful in microbenchmarks, as the values from consequent runs have a very narrow distribution.\nHowever, real-world scenarios often have so-called long tail distribution\n  (due to IO delays, locks, memory access latency and so on), so the average execution time cannot be trusted.\n\nThe percentiles allow to include the tail of distribution into the comparison.\nHowever, it requires some preparations steps.\nAt first, you should have enough runs to count percentiles from.\nThe `IterationCount` in the config should be set to 10-20 runs at least.  \n\nSecond, the count of iterations for each run should not be very high, or the peak timings will be averaged.\nThe `IterationTime = 25` works fine for most cases;\n  for long-running benchmarks the `Mode = Mode.SingleRun` will be the best choice. \nHowever, feel free to experiment with the config values.\n\nThird, if you want to be sure that measurements are repeatable, set the `LaunchCount` to 3 or higher.\n\nAnd last, don't forget to include the columns into the config.\nThey are not included by default (as said above, these are not too useful for most of the benchmarks).\nThere're predefined `StatisticColumn.P0`..`StatisticColumn.P100` for absolute timing percentiles.\n\n### Example\n\nRun the IntroPercentiles sample. It contains three benchmark methods.\n\n* First delays for 20 ms constantly.\n* The second has random delays for 10..30 ms.\n* And the third delays for 10ms 85 times of 100 and delays for 40ms 15 times of 100.\n\nHere's the output from the benchmark (some columns removed for brevity):\n\n|         Method |     Median |     StdDev | Ratio |         P0 |        P50 |        P80 |        P85 |        P95 |       P100 |\n|--------------- |----------- |----------- |------ |----------- |----------- |----------- |----------- |----------- |----------- |\n| ConstantDelays | 20.3813 ms |  0.2051 ms |  1.00 | 20.0272 ms | 20.3813 ms | 20.4895 ms | 20.4954 ms | 20.5869 ms | 21.1471 ms |\n|   RandomDelays | 19.8055 ms |  5.7556 ms |  0.97 | 10.0793 ms | 19.8055 ms | 25.4173 ms | 26.5187 ms | 29.0313 ms | 29.4550 ms |\n|     RareDelays | 10.3385 ms | 11.4828 ms |  0.51 | 10.0157 ms | 10.3385 ms | 10.5211 ms | 40.0560 ms | 40.3992 ms | 40.4674 ms |\n\nAlso, it's very easy to screw the results with incorrect setup. For example, the same code being run with\n\n```cs\nnew Job\n{\n\tIterationCount = 5,\n\tIterationTime = 500\n}\n```\n\ncompletely hides the peak values:\n\n|         Method |     Median |    StdDev | Ratio |         P0 |        P50 |        P80 |        P85 |        P95 |       P100 |\n|--------------- |----------- |---------- |------ |----------- |----------- |----------- |----------- |----------- |----------- |\n| ConstantDelays | 20.2692 ms | 0.0308 ms |  1.00 | 20.1986 ms | 20.2692 ms | 20.2843 ms | 20.2968 ms | 20.3097 ms | 20.3122 ms |\n|   RandomDelays | 18.9965 ms | 0.8601 ms |  0.94 | 18.1339 ms | 18.9965 ms | 19.8126 ms | 19.8278 ms | 20.4485 ms | 20.9466 ms |\n|     RareDelays | 14.0912 ms | 2.8619 ms |  0.70 | 10.2606 ms | 14.0912 ms | 15.7653 ms | 17.3862 ms | 18.6728 ms | 18.6940 ms |\n\n### Source code\n\n[!code-csharp[IntroPercentiles.cs](../../../samples/BenchmarkDotNet.Samples/IntroPercentiles.cs)]\n\n### Links\n\n* @docs.statistics\n* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroPercentiles\n\n---\n"
  },
  {
    "path": "docs/articles/samples/IntroPowerPlan.md",
    "content": "---\nuid: BenchmarkDotNet.Samples.IntroPowerPlan\n---\n\n## Sample: IntroPowerPlan\n\nThis sample shows how we can manipulate with power plans. In BenchmarkDotNet we could change power plan in two ways. The first one is to set one from the list:\n\n* PowerSaver, guid: a1841308-3541-4fab-bc81-f71556f20b4a\n* Balanced, guid: 381b4222-f694-41f0-9685-ff5bb260df2e\n* High-Performance, guid: 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c (the default one)\n* Ultimate Performance, guid: e9a42b02-d5df-448d-aa00-03f14749eb61\n* UserPowerPlan (a current power plan set in computer)\nThe second one rely on guid string. We could easily found currently set GUIDs with cmd command\n\n```cmd\npowercfg /list\n```\n\nIf we set power plans in two ways at the same time, the second one will be used.\n\n### Source code\n\n[!code-csharp[IntroPowerPlan.cs](../../../samples/BenchmarkDotNet.Samples/IntroPowerPlan.cs)]\n\n### Links\n\n* @docs.powerplans\n* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroPowerPlan\n\n---\n"
  },
  {
    "path": "docs/articles/samples/IntroRankColumn.md",
    "content": "---\nuid: BenchmarkDotNet.Samples.IntroRankColumn\n---\n\n## Sample: IntroRankColumn\n\n\n### Source code\n\n[!code-csharp[IntroRankColumn.cs](../../../samples/BenchmarkDotNet.Samples/IntroRankColumn.cs)]\n\n### Output\n\n```markdown\n Method | Factor |     Mean |    Error |    StdDev | Rank | Rank | Rank |\n------- |------- |---------:|---------:|----------:|-----:|-----:|-----:|\n    Foo |      1 | 100.8 ms | 2.250 ms | 0.1272 ms |    1 |    I |    * |\n    Foo |      2 | 200.8 ms | 4.674 ms | 0.2641 ms |    2 |   II |   ** |\n    Bar |      1 | 200.9 ms | 2.012 ms | 0.1137 ms |    2 |   II |   ** |\n    Bar |      2 | 400.7 ms | 4.509 ms | 0.2548 ms |    3 |  III |  *** |\n```\n\n### Links\n\n* @docs.statistics\n* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroRankColumn\n\n---"
  },
  {
    "path": "docs/articles/samples/IntroRatioSD.md",
    "content": "---\nuid: BenchmarkDotNet.Samples.IntroRatioSD\n---\n\n## Sample: IntroRatioSD\n\nThe ratio of two benchmarks is not a single number, it's a distribution.\nIn most simple cases, the range of the ratio distribution is narrow,\n  and BenchmarkDotNet displays a single column `Ratio` with the mean value.\nHowever, it also adds the `RatioSD` column (the standard deviation of the ratio distribution)\n  in complex situations.\nIn the below example, the baseline benchmark is spoiled by a single outlier\n\n### Source code\n\n[!code-csharp[IntroRatioSD.cs](../../../samples/BenchmarkDotNet.Samples/IntroRatioSD.cs)]\n\n### Output\n\nHere are statistics details for the baseline benchmark:\n\n```ini\nMean = 600.6054 ms, StdErr = 500.0012 ms (83.25%); N = 10, StdDev = 1,581.1428 ms\nMin = 100.2728 ms, Q1 = 100.3127 ms, Median = 100.4478 ms, Q3 = 100.5011 ms, Max = 5,100.6163 ms\nIQR = 0.1884 ms, LowerFence = 100.0301 ms, UpperFence = 100.7837 ms\nConfidenceInterval = [-1,789.8568 ms; 2,991.0677 ms] (CI 99.9%), Margin = 2,390.4622 ms (398.01% of Mean)\nSkewness = 2.28, Kurtosis = 6.57, MValue = 2\n-------------------- Histogram --------------------\n[-541.891 ms ;  743.427 ms) | @@@@@@@@@\n[ 743.427 ms ; 2027.754 ms) | \n[2027.754 ms ; 3312.082 ms) | \n[3312.082 ms ; 4458.453 ms) | \n[4458.453 ms ; 5742.780 ms) | @\n---------------------------------------------------\n```\n\nAs you can see, a single outlier significantly affected the metrics.\nBecause of this, BenchmarkDotNet adds the `Median` and the `RatioSD` columns in the summary table:\n\n```markdown\n Method |      Mean |         Error |        StdDev |    Median | Ratio | RatioSD |\n------- |----------:|--------------:|--------------:|----------:|------:|--------:|\n   Base | 600.61 ms | 2,390.4622 ms | 1,581.1428 ms | 100.45 ms |  1.00 |    0.00 |\n   Slow | 200.50 ms |     0.4473 ms |     0.2959 ms | 200.42 ms |  1.80 |    0.62 |\n   Fast |  50.54 ms |     0.3435 ms |     0.2272 ms |  50.48 ms |  0.45 |    0.16 |\n```\n\nLet's look at the `Base` and `Slow` benchmarks.\nThe `Mean` values are `600` and `200` milliseconds; the \"Scaled Mean\" value is 0.3.\nThe `Median` values are `100` and `200` milliseconds; the \"Scaled Median\" value is 2.\nBoth values are misleading.\nBenchmarkDotNet evaluates the ratio distribution and displays the mean (1.80) and the standard deviation (0.62).\n\n### Links\n\n* @docs.baselines\n* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroRatioSD\n\n---\n"
  },
  {
    "path": "docs/articles/samples/IntroRatioStyle.md",
    "content": "---\nuid: BenchmarkDotNet.Samples.IntroRatioStyle\n---\n\n## Sample: IntroRatioStyle\n\nUsing `RatioStyle`, we can override the style of the \"Ratio\" column in `SummaryStyle`.\nHere are the possible values:\n\n* `Value`: default value that shows the ration value between the current benchmark and the baseline benchmark (e.g., `0.15` or `1.15`)\n* `Percentage`: express the ration in percentage (e.g., `-85%` or `+15%`)\n* `Trend`: shows how much the current benchmark is faster or slower than the base benchmark (e.g., `6.63x faster` or `1.15x slower`)\n\n### Source code\n\n[!code-csharp[IntroRatioStyle.cs](../../../samples/BenchmarkDotNet.Samples/IntroRatioStyle.cs)]\n\n### Output\n\nWith the given `RatioStyle.Trend`, we have the following table:\n\n```markdown\n|   Method |       Mean |   Error |  StdDev |        Ratio | RatioSD |\n|--------- |-----------:|--------:|--------:|-------------:|--------:|\n| Baseline | 1,000.6 ms | 2.48 ms | 0.14 ms |     baseline |         |\n|      Bar |   150.9 ms | 1.30 ms | 0.07 ms | 6.63x faster |   0.00x |\n|      Foo | 1,150.4 ms | 5.17 ms | 0.28 ms | 1.15x slower |   0.00x |\n```\n\nWith the default `RatioStyle.Value`, we get the following table:\n\n```markdown\n|   Method |       Mean |   Error |  StdDev | Ratio |\n|--------- |-----------:|--------:|--------:|------:|\n| Baseline | 1,000.3 ms | 2.71 ms | 0.15 ms |  1.00 |\n|      Bar |   150.6 ms | 1.67 ms | 0.09 ms |  0.15 |\n|      Foo | 1,150.6 ms | 7.41 ms | 0.41 ms |  1.15 |\n```\n\nIf we use `RatioStyle.Percentage`, we get the following table:\n\n```markdown\n|   Method |       Mean |   Error |  StdDev |    Ratio | RatioSD |\n|--------- |-----------:|--------:|--------:|---------:|--------:|\n| Baseline | 1,000.3 ms | 4.69 ms | 0.26 ms | baseline |         |\n|      Bar |   150.7 ms | 1.42 ms | 0.08 ms |     -85% |    0.1% |\n|      Foo | 1,150.3 ms | 6.13 ms | 0.34 ms |     +15% |    0.0% |\n```\n\n### Links\n\n* @docs.baselines\n* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroRatioStyle\n\n---\n"
  },
  {
    "path": "docs/articles/samples/IntroSetupCleanupGlobal.md",
    "content": "---\nuid: BenchmarkDotNet.Samples.IntroSetupCleanupGlobal\n---\n\n## Sample: IntroSetupCleanupGlobal\n\nA method which is marked by the [`[GlobalSetup]`](xref:BenchmarkDotNet.Attributes.GlobalSetupAttribute)\n  attribute will be executed only once per a benchmarked method\n  after initialization of benchmark parameters and before all the benchmark method invocations.\nA method which is marked by the [`[GlobalCleanup]`](xref:BenchmarkDotNet.Attributes.GlobalCleanupAttribute)\n  attribute will be executed only once per a benchmarked method\n  after all the benchmark method invocations.\nIf you are using some unmanaged resources (e.g., which were created in the `GlobalSetup` method),\n  they can be disposed in the `GlobalCleanup` method.\n\n### Source code\n\n[!code-csharp[IntroSetupCleanupGlobal.cs](../../../samples/BenchmarkDotNet.Samples/IntroSetupCleanupGlobal.cs)]\n\n### Links\n\n* @docs.setup-and-cleanup\n* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroSetupCleanupGlobal\n\n---"
  },
  {
    "path": "docs/articles/samples/IntroSetupCleanupIteration.md",
    "content": "---\nuid: BenchmarkDotNet.Samples.IntroSetupCleanupIteration\n---\n\n## Sample: IntroSetupCleanupIteration\n\nA method which is marked by the [`[IterationSetup]`](xref:BenchmarkDotNet.Attributes.IterationSetupAttribute)\n  attribute will be executed exactly once *before each benchmark invocation*, forcing `UnrollFactor=1` and `InvocationCount=1` (we have changed that in 0.11.0).\nIt's not recommended to use this attribute in microbenchmarks because it can spoil the results.\nHowever, if you are writing a macrobenchmark (e.g. a benchmark which takes at least 100ms) and\n  you want to prepare some data before each invocation,\n  [`[IterationSetup]`](xref:BenchmarkDotNet.Attributes.IterationSetupAttribute) can be useful.\n\nA method which is marked by the [`[IterationCleanup]`](xref:BenchmarkDotNet.Attributes.IterationCleanupAttribute)\n  attribute will be executed exactly once *after each invocation*.\nThis attribute has the same set of constraint with `[IterationSetup]`: it's not recommended to use\n  [`[IterationCleanup]`](xref:BenchmarkDotNet.Attributes.IterationCleanupAttribute) in microbenchmarks.\n\n### Source code\n\n[!code-csharp[IntroSetupCleanupIteration.cs](../../../samples/BenchmarkDotNet.Samples/IntroSetupCleanupIteration.cs)]\n\n### The order of method calls\n\n```cs\n// GlobalSetup\n\n// IterationSetup (1)    // IterationSetup Jitting\n// IterationCleanup (1)  // IterationCleanup Jitting\n\n// IterationSetup (2)    // MainWarmup1\n// Benchmark             // MainWarmup1\n// IterationCleanup (2)  // MainWarmup1\n\n// IterationSetup (3)    // MainWarmup2\n// Benchmark             // MainWarmup2\n// IterationCleanup (3)  // MainWarmup2\n\n// IterationSetup (4)    // MainTarget1\n// Benchmark             // MainTarget1\n// IterationCleanup (4)  // MainTarget1\n\n// IterationSetup (5)    // MainTarget2\n// Benchmark             // MainTarget2\n// IterationCleanup (5)  // MainTarget2\n\n// IterationSetup (6)    // MainTarget3\n// Benchmark             // MainTarget3\n// IterationCleanup (6)  // MainTarget3\n\n// GlobalCleanup\n```\n\n### Links\n\n* @docs.setup-and-cleanup\n* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroSetupCleanupIteration\n\n---\n"
  },
  {
    "path": "docs/articles/samples/IntroSetupCleanupTarget.md",
    "content": "---\nuid: BenchmarkDotNet.Samples.IntroSetupCleanupTarget\n---\n\n## Sample: IntroSetupCleanupTarget\n\nSometimes it's useful to run setup or cleanups for specific benchmarks.\nAll four setup and cleanup attributes have a Target property that allow\n  the setup/cleanup method to be run for one or more specific benchmark methods.\n\n### Source code\n\n[!code-csharp[IntroSetupCleanupTarget.cs](../../../samples/BenchmarkDotNet.Samples/IntroSetupCleanupTarget.cs)]\n\n### The order of method calls\n\n```cs\n// GlobalSetup A\n\n// Benchmark A\n\n// GlobalSetup B\n\n// Benchmark B\n\n// GlobalSetup B\n\n// Benchmark C\n\n// Benchmark D\n```\n\n### Links\n\n* @docs.setup-and-cleanup\n* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroSetupCleanupTarget\n\n---\n"
  },
  {
    "path": "docs/articles/samples/IntroStaThread.md",
    "content": "---\nuid: BenchmarkDotNet.Samples.IntroStaThread\n---\n\n## Sample: IntroStaThread\n\nIf the code you want to benchmark requires `[System.STAThread]`\n  then you need to apply this attribute to the benchmarked method.\nBenchmarkDotNet will generate an executable with `[STAThread]` applied to its `Main` method.\n\nUsing this feature on .NET Core requires .NET Core 2.1 or newer. Older versions will not work due to [this](https://github.com/dotnet/runtime/issues/8834) bug.\n\n### Source code\n\n[!code-csharp[IntroStaThread.cs](../../../samples/BenchmarkDotNet.Samples/IntroStaThread.cs)]\n\n### Links\n\n* @docs.customizing-runtime\n* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroStaThread\n\n---"
  },
  {
    "path": "docs/articles/samples/IntroStatisticalTesting.md",
    "content": "---\nuid: BenchmarkDotNet.Samples.IntroStatisticalTesting\n---\n\n## Sample: IntroStatisticalTesting\n\n### Source code\n\n[!code-csharp[IntroStatisticalTesting.cs](../../../samples/BenchmarkDotNet.Samples/IntroStatisticalTesting.cs)]\n\n### Output\n```markdown\n|   Method |      Mean |     Error |    StdDev | Ratio |   Welch(1us)/p-values |    Welch(3%)/p-values | MannWhitney(1us)/p-values | MannWhitney(3%)/p-values |\n|--------- |----------:|----------:|----------:|------:|---------------------- |---------------------- |-------------------------- |------------------------- |\n|  Sleep50 |  53.13 ms | 0.5901 ms | 0.1532 ms |  0.51 | Faster: 1.0000/0.0000 | Faster: 1.0000/0.0000 |     Faster: 1.0000/0.0040 |    Faster: 1.0000/0.0040 |\n|  Sleep97 | 100.07 ms | 0.9093 ms | 0.2361 ms |  0.97 | Faster: 1.0000/0.0000 |   Same: 1.0000/0.1290 |     Faster: 1.0000/0.0040 |      Same: 1.0000/0.1111 |\n|  Sleep99 | 102.23 ms | 2.4462 ms | 0.6353 ms |  0.99 | Faster: 0.9928/0.0072 |   Same: 1.0000/0.9994 |     Faster: 0.9960/0.0079 |      Same: 1.0000/1.0000 |\n| Sleep100 | 103.34 ms | 0.8180 ms | 0.2124 ms |  1.00 |   Base: 0.5029/0.5029 |   Base: 1.0000/1.0000 |       Base: 0.7262/0.7262 |      Base: 1.0000/1.0000 |\n| Sleep101 | 103.73 ms | 2.1591 ms | 0.5607 ms |  1.00 |   Same: 0.1041/0.8969 |   Same: 0.9999/1.0000 |       Same: 0.1111/0.9246 |      Same: 1.0000/1.0000 |\n| Sleep103 | 106.21 ms | 1.2511 ms | 0.3249 ms |  1.03 | Slower: 0.0000/1.0000 |   Same: 0.9447/1.0000 |     Slower: 0.0040/1.0000 |      Same: 0.9246/1.0000 |\n| Sleep150 | 153.16 ms | 3.4929 ms | 0.9071 ms |  1.48 | Slower: 0.0000/1.0000 | Slower: 0.0000/1.0000 |     Slower: 0.0040/1.0000 |    Slower: 0.0040/1.0000 |\n\n// * Legends *\n  Mean                      : Arithmetic mean of all measurements\n  Error                     : Half of 99.9% confidence interval\n  StdDev                    : Standard deviation of all measurements\n  Ratio                     : Mean of the ratio distribution ([Current]/[Baseline])\n  Welch(1us)/p-values       : Welch-based TOST equivalence test with 1 us threshold. Format: 'Result: p-value(Slower)|p-value(Faster)'\n  Welch(3%)/p-values        : Welch-based TOST equivalence test with 3% threshold. Format: 'Result: p-value(Slower)|p-value(Faster)'\n  MannWhitney(1us)/p-values : MannWhitney-based TOST equivalence test with 1 us threshold. Format: 'Result: p-value(Slower)|p-value(Faster)'\n  MannWhitney(3%)/p-values  : MannWhitney-based TOST equivalence test with 3% threshold. Format: 'Result: p-value(Slower)|p-value(Faster)'\n  1 ms                      : 1 Millisecond (0.001 sec)\n```\n\n### Links\n\n* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroStatisticalTesting\n\n---"
  },
  {
    "path": "docs/articles/samples/IntroStatisticsColumns.md",
    "content": "---\nuid: BenchmarkDotNet.Samples.IntroStatisticsColumns\n---\n\n## Sample: IntroStatisticsColumns\n\n\n### Source code\n\n[!code-csharp[IntroStatisticsColumns.cs](../../../samples/BenchmarkDotNet.Samples/IntroStatisticsColumns.cs)]\n\n### Output\n\n| Method |     Mean |     Error |    StdDev | Skewness | Kurtosis | Ratio | RatioSD |\n|------- |---------:|----------:|----------:|---------:|---------:|------:|--------:|\n|   Md5A | 15.91 us | 0.0807 us | 0.1209 us |   0.4067 |    1.646 |  1.00 |    0.00 |\n|   Md5B | 15.89 us | 0.0709 us | 0.1062 us |   0.5893 |    2.141 |  1.00 |    0.01 |\n| Sha256 | 36.62 us | 0.6390 us | 0.9564 us |   1.1363 |    4.014 |  2.30 |    0.06 |\n\n\n### Links\n\n* @docs.statistics\n* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroStatisticsColumns\n\n---"
  },
  {
    "path": "docs/articles/samples/IntroStopOnFirstError.md",
    "content": "---\nuid: BenchmarkDotNet.Samples.IntroStopOnFirstError\n---\n\n## Sample: IntroStopOnFirstError\n\nBenchmarkDotNet can be configured to stop on first error. You just have to add `StopOnFirstError` attribute to your class or use `--stopOnFirstError` command line argument.\n\n### Source code\n\n[!code-csharp[IntroStopOnFirstError.cs](../../../samples/BenchmarkDotNet.Samples/IntroStopOnFirstError.cs)]\n\n### Links\n\n* @docs.configs\n* @docs.console-args\n* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroStopOnFirstError\n\n---"
  },
  {
    "path": "docs/articles/samples/IntroSummaryStyle.md",
    "content": "---\nuid: BenchmarkDotNet.SummaryStyle\n---\n\n## SummaryStyle in BenchmarkDotNet\n\n`SummaryStyle` is a class in BenchmarkDotNet that allows customization of the summary reports of benchmark results. It offers several properties to fine-tune how the results are displayed.\n\n### Usage\n\nYou can customize the summary report by specifying various properties of `SummaryStyle`. These properties include formatting options like whether to print units in the header or content, setting the maximum width for parameter columns, and choosing units for size and time measurements.\n\n### Source Code\n\n[!code-csharp[IntroSummaryStyle.cs](../../../samples/BenchmarkDotNet.Samples/IntroSummaryStyle.cs)]\n\n### Properties\n\n- `PrintUnitsInHeader`: Boolean to indicate if units should be printed in the header.\n- `PrintUnitsInContent`: Boolean to control unit printing in the content.\n- `PrintZeroValuesInContent`: Determines if zero values should be printed.\n- `MaxParameterColumnWidth`: Integer defining the max width for parameter columns.\n- `SizeUnit`: Optional `SizeUnit` to specify the unit for size measurements.\n- `TimeUnit`: Optional `TimeUnit` for time measurement units.\n- `CultureInfo`: `CultureInfo` to define culture-specific formatting.\n\n### Example Output\n\nUsing SummaryStyle options:\n\n```markdown\n| Method | N   | Mean [ns]     | Error [ns] | StdDev [ns] |\n|------- |---- |--------------:|-----------:|------------:|\n| Sleep  | 10  |  15,644,973.1 |   32,808.7 |    30,689.3 |\n| Sleep  | 100 | 109,440,686.7 |  236,673.8 |   221,384.8 |\n```\n\nDefault:\n\n```markdown\n| Method | N   | Mean      | Error    | StdDev   |\n|------- |---- |----------:|---------:|---------:|\n| Sleep  | 10  |  15.65 ms | 0.039 ms | 0.034 ms |\n| Sleep  | 100 | 109.20 ms | 0.442 ms | 0.392 ms |\n```\n\n### Links\n\n* @docs.SummaryStyle\n* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroSummaryStyle\n\n"
  },
  {
    "path": "docs/articles/samples/IntroTagColumn.md",
    "content": "---\nuid: BenchmarkDotNet.Samples.IntroTagColumn\n---\n\n## Sample: IntroTagColumn\n\nIn the following example, we introduce two new columns which contains a tag based on a benchmark method name.\n\n### Source code\n\n[!code-csharp[IntroTagColumn.cs](../../../samples/BenchmarkDotNet.Samples/IntroTagColumn.cs)]\n\n### Output\n\n```markdown\n| Method | Mean       | Kind | Number |\n| ------ | ---------- | ---- | ------ |\n| Bar34  | 10.3636 ms | Bar  | 34     |\n| Bar3   | 10.4662 ms | Bar  | 3      |\n| Foo12  | 10.1377 ms | Foo  | 12     |\n| Foo1   | 10.2814 ms | Foo  | 1      |\n```\n\n### Links\n\n* @docs.columns\n* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroTagColumn\n\n---"
  },
  {
    "path": "docs/articles/samples/IntroTailcall.md",
    "content": "---\nuid: BenchmarkDotNet.Samples.IntroTailcall\n---\n\n## Sample: IntroTailcall\n\nYou need to use the `TailcallDiagnoser` attribute to configure it. The available options are:\n\n* logFailuresOnly: Track only the methods that failed to get tail called. True by default.\n* filterByNamespace : Track only the methods from declaring type's namespace. Set to false if you want to see all Jit tail events. True by default.\n\n### Restrictions\n\n* Windows only\n* x64\n\n### Source code\n\n[!code-csharp[IntroTailcall.cs](../../../samples/BenchmarkDotNet.Samples/IntroTailcall.cs)]\n\n### Output\n\n```markdown\n// * Diagnostic Output - TailCallDiagnoser *\n--------------------\n\n--------------------\nJit_TailCalling.Calc: LegacyJitX64(Jit=LegacyJit, Platform=X64, Runtime=Clr)\n--------------------\n\n--------------------\nJit_TailCalling.Calc: LegacyJitX86(Jit=LegacyJit, Platform=X86, Runtime=Clr)\n--------------------\n\n--------------------\nJit_TailCalling.Calc: RyuJitX64(Jit=RyuJit, Platform=X64)\n--------------------\nCaller: <null>.<null> - <null>\nCallee: BenchmarkDotNet.Samples.JIT.Jit_TailCalling.FactorialWithTailing - int64  (int32,int32)\nTail prefix: False\nTail call type: RecursiveLoop\n-------------------\n```\n\n### Links\n\n* @docs.diagnosers\n* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroTailcall\n\n---"
  },
  {
    "path": "docs/articles/samples/IntroTemplate.txt",
    "content": "---\nuid: BenchmarkDotNet.Samples.SAMPLENAME\n---\n\n## Sample: SAMPLENAME\n\n### Source code\n\n[!code-csharp[SAMPLENAME.cs](../../../samples/BenchmarkDotNet.Samples/SAMPLENAME.cs)]\n\n### Output\n\n\n### Links\n\n* TODO\n* The permanent link to this sample: @BenchmarkDotNet.Samples.SAMPLENAME\n\n---"
  },
  {
    "path": "docs/articles/samples/IntroThreadingDiagnoser.md",
    "content": "---\nuid: BenchmarkDotNet.Samples.IntroThreadingDiagnoser\n---\n\n## Sample: IntroThreadingDiagnoser\n\nThe `ThreadingDiagnoser` uses new APIs [exposed](https://github.com/dotnet/corefx/issues/35500) in .NET Core 3.0 to report:\n\n* Completed Work Items: The number of work items that have been processed in ThreadPool (per single operation)\n* Lock Contentions: The number of times there **was contention** upon trying to take a Monitor's lock (per single operation)\n\n### Source code\n\n[!code-csharp[IntroThreadingDiagnoser.cs](../../../samples/BenchmarkDotNet.Samples/IntroThreadingDiagnoser.cs)]\n\n### Output\n\n|              Method |          Mean |     StdDev |        Median | Completed Work Items | Lock Contentions |\n|-------------------- |--------------:|-----------:|--------------:|---------------------:|-----------------:|\n| CompleteOneWorkItem | 8,073.5519 ns | 69.7261 ns | 8,111.6074 ns |               1.0000 |                - |\n\n### Links\n\n* @docs.diagnosers\n* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroThreadingDiagnoser\n\n---"
  },
  {
    "path": "docs/articles/samples/IntroUnicode.md",
    "content": "---\nuid: BenchmarkDotNet.Samples.IntroUnicode\n---\n\n## Sample: IntroUnicode\n\nSome of the BenchmarkDotNet exporters use Unicode symbols that are not ASCII-compatible (e.g., `μ` or `±`).\nUnfortunately, some terminals are not supported such symbols.\nThat's why BenchmarkDotNet prints only ASCII characters by default (`μ` will be replaced by `u`).\nIf you want to display Unicode symbols in your terminal, you should use `[UnicodeConsoleLoggerAttribute]` (see usage examples below).\n\n> [!WARNING]\n> This feature works only with terminal(s)|text editor(s) that support Unicode.\n> On Windows, you may have some troubles with Unicode symbols\n>   if system default code page configured as non-English\n>   (in Control Panel + Regional and Language Options, Language for Non-Unicode Programs).\n\n### Source code\n\n[!code-csharp[IntroUnicode.cs](../../../samples/BenchmarkDotNet.Samples/IntroUnicode.cs)]\n\n### Output\n\n```markdown\nMean = 1.0265 μs, StdErr = 0.0005 μs (0.05%); N = 15, StdDev = 0.0018 μs\nMin = 1.0239 μs, Q1 = 1.0248 μs, Median = 1.0264 μs, Q3 = 1.0280 μs, Max = 1.0296 μs\nIQR = 0.0033 μs, LowerFence = 1.0199 μs, UpperFence = 1.0329 μs\nConfidenceInterval = [1.0245 μs; 1.0285 μs] (CI 99.9%), Margin = 0.0020 μs (0.19% of Mean)\nSkewness = 0.12, Kurtosis = 1.56, MValue = 2\n-------------------- Histogram --------------------\n[1.023 μs ; 1.030 μs) | @@@@@@@@@@@@@@@\n---------------------------------------------------\n```\n\n```markdown\n Method |     Mean |     Error |    StdDev |\n------- |---------:|----------:|----------:|\n    Foo | 1.027 μs | 0.0020 μs | 0.0018 μs |\n```\n\n### Links\n\n* @BenchmarkDotNet.Attributes.UnicodeConsoleLoggerAttribute\n* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroUnicode\n\n---\n"
  },
  {
    "path": "docs/articles/samples/IntroVisualStudioProfiler.md",
    "content": "---\nuid: BenchmarkDotNet.Samples.IntroVisualStudioProfiler\n---\n\n## Sample: Visual Studio Profiler\n\nUsing the [Microsoft.VisualStudio.BenchmarkDotNetDiagnosers](https://www.nuget.org/packages/Microsoft.VisualStudio.DiagnosticsHub.BenchmarkDotNetDiagnosers) NuGet package you can capture performance profiles of your benchmarks that can be opened in Visual Studio. \n\n### Source code\n\n[!code-csharp[IntroVisualStudioDiagnoser.cs](../../../samples/BenchmarkDotNet.Samples/IntroVisualStudioDiagnoser.cs)]\n\n### Output\nThe output will contain a path to the collected diagsession and automatically open in Visual Studio when launched from it.\n\n```markdown\n// * Diagnostic Output - VSDiagnosticsDiagnoser *\nCollection result moved to 'C:\\Work\\BenchmarkDotNet\\samples\\BenchmarkDotNet.Samples\\bin\\Release\\net8.0\\BenchmarkDotNet.Artifacts\\BenchmarkDotNet_IntroVisualStudioProfiler_20241205_192056.diagsession'.\nSession : {d54ebddb-2d6d-404f-b1da-10acbc89635f}\n  Stopped\nExported diagsession file: C:\\Work\\BenchmarkDotNet\\samples\\BenchmarkDotNet.Samples\\bin\\Release\\net8.0\\BenchmarkDotNet.Artifacts\\BenchmarkDotNet_IntroVisualStudioProfiler_20241205_192056.diagsession.\nOpening diagsession in VisualStudio: 15296\n```"
  },
  {
    "path": "docs/articles/samples/IntroWakeLock.md",
    "content": "---\nuid: BenchmarkDotNet.Samples.IntroWakeLock\n---\n\n## Sample: IntroWakeLock\n\nRunning benchmarks may sometimes take enough time such that the system enters sleep or turns off the display.\n\nUsing a WakeLock prevents the Windows system doing so.\n\n### Source code\n\n[!code-csharp[IntroWakeLock.cs](../../../samples/BenchmarkDotNet.Samples/IntroWakeLock.cs)]\n\n### Command line\n\n```\n--wakeLock None\n```\n```\n--wakeLock System\n```\n```\n--wakeLock Display\n```\n\n### Links\n\n* @BenchmarkDotNet.Attributes.WakeLockAttribute\n* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroWakeLock\n\n---\n"
  },
  {
    "path": "docs/articles/samples/IntroWasm.md",
    "content": "---\nuid: BenchmarkDotNet.Samples.IntroWasm\n---\n\n## Sample: IntroWasm\n\n`WasmToolchain` builds benchmarks as WebAssembly and runs them under a JavaScript engine (V8 by default).\n\nIt is supported on Windows, Linux, and macOS.\n\nIf you hit `NETSDK1147` (missing workload), install the required workload (for example: `dotnet workload install wasm-tools`).\n\n### Source code\n\n[!code-csharp[IntroWasm.cs](../../../samples/BenchmarkDotNet.Samples/IntroWasm.cs)]\n\n### Links\n\n* @docs.toolchains\n* The permanent link to this sample: @BenchmarkDotNet.Samples.IntroWasm\n\n---\n"
  },
  {
    "path": "docs/articles/samples/toc.yml",
    "content": "- name: IntroArguments\n  href: IntroArguments.md\n- name: IntroArgumentsSource\n  href: IntroArgumentsSource.md\n- name: IntroArrayParam\n  href: IntroArrayParam.md\n- name: IntroBasic\n  href: IntroBasic.md\n- name: IntroBenchmarkBaseline\n  href: IntroBenchmarkBaseline.md\n- name: IntroCategories\n  href: IntroCategories.md\n- name: IntroCategoryBaseline\n  href: IntroCategoryBaseline.md\n- name: IntroCategoryDiscoverer\n  href: IntroCategoryDiscoverer.md\n- name: IntroColdStart\n  href: IntroColdStart.md\n- name: IntroComparableComplexParam\n  href: IntroComparableComplexParam.md\n- name: IntroConfigSource\n  href: IntroConfigSource.md\n- name: IntroConfigUnion\n  href: IntroConfigUnion.md\n- name: IntroCustomMono\n  href: IntroCustomMono.md\n- name: IntroCustomMonoArguments\n  href: IntroCustomMonoArguments.md\n- name: IntroDeferredExecution\n  href: IntroDeferredExecution.md\n- name: IntroDisassembly\n  href: IntroDisassembly.md\n- name: IntroDisassemblyAllJits\n  href: IntroDisassemblyAllJits.md\n- name: IntroDisassemblyDry\n  href: IntroDisassemblyDry.md\n- name: IntroDisassemblyRyuJit\n  href: IntroDisassemblyRyuJit.md\n- name: IntroDotTraceDiagnoser\n  href: IntroDotTraceDiagnoser.md\n- name: IntroDotMemoryDiagnoser\n  href: IntroDotMemoryDiagnoser.md\n- name: IntroEnvVars\n  href: IntroEnvVars.md\n- name: IntroEventPipeProfiler\n  href: IntroEventPipeProfiler.md\n- name: IntroEventPipeProfilerAdvanced\n  href: IntroEventPipeProfilerAdvanced.md\n- name: IntroExport\n  href: IntroExport.md\n- name: IntroExportJson\n  href: IntroExportJson.md\n- name: IntroExportXml\n  href: IntroExportXml.md\n- name: IntroFilters\n  href: IntroFilters.md\n- name: IntroFluentConfigBuilder\n  href: IntroFluentConfigBuilder.md\n- name: IntroGcMode\n  href: IntroGcMode.md\n- name: IntroGenericTypeArguments\n  href: IntroGenericTypeArguments.md\n- name: IntroHardwareCounters\n  href: IntroHardwareCounters.md\n- name: IntroInliningDiagnoser\n  href: IntroInliningDiagnoser.md\n- name: IntroInProcess\n  href: IntroInProcess.md\n- name: IntroInProcessWrongEnv\n  href: IntroInProcessWrongEnv.md\n- name: IntroJitStatsDiagnoser\n  href: IntroJitStatsDiagnoser.md\n- name: IntroJobBaseline\n  href: IntroJobBaseline.md\n- name: IntroJoin\n  href: IntroJoin.md\n- name: IntroLargeAddressAware\n  href: IntroLargeAddressAware.md\n- name: IntroMonitoring\n  href: IntroMonitoring.md\n- name: IntroMultimodal\n  href: IntroMultimodal.md\n- name: IntroNativeMemory\n  href: IntroNativeMemory.md\n- name: IntroNuGet\n  href: IntroNuGet.md\n- name: IntroOrderAttr\n  href: IntroOrderAttr.md\n- name: IntroOrderManual\n  href: IntroOrderManual.md\n- name: IntroOutliers\n  href: IntroOutliers.md\n- name: IntroParams\n  href: IntroParams.md\n- name: IntroParamsAllValues\n  href: IntroParamsAllValues.md\n- name: IntroParamsSource\n  href: IntroParamsSource.md\n- name: IntroPercentiles\n  href: IntroPercentiles.md\n- name: IntroPowerPlan\n  href: IntroPowerPlan.md\n- name: IntroRankColumn\n  href: IntroRankColumn.md\n- name: IntroRatioSD\n  href: IntroRatioSD.md\n- name: IntroRatioStyle\n  href: IntroRatioStyle.md\n- name: IntroSetupCleanupGlobal\n  href: IntroSetupCleanupGlobal.md\n- name: IntroSetupCleanupIteration\n  href: IntroSetupCleanupIteration.md\n- name: IntroSetupCleanupTarget\n  href: IntroSetupCleanupTarget.md\n- name: IntroStaThread\n  href: IntroStaThread.md\n- name: IntroStatisticalTesting\n  href: IntroStatisticalTesting.md\n- name: IntroStatisticsColumns\n  href: IntroStatisticsColumns.md\n- name: IntroStopOnFirstError\n  href: IntroStopOnFirstError.md\n- name: IntroTagColumn\n  href: IntroTagColumn.md\n- name: IntroTailcall\n  href: IntroTailcall.md\n- name: IntroVisualStudioProfiler\n  href: IntroVisualStudioProfiler.md\n- name: IntroWakeLock\n  href: IntroWakeLock.md\n- name: IntroWasm\n  href: IntroWasm.md\n- name: IntroUnicode\n  href: IntroUnicode.md\n- name: IntroMaui\n  href: IntroMaui.md"
  },
  {
    "path": "docs/articles/team.md",
    "content": "# Team\n\nMaintainers:\n  [Andrey Akinshin](https://github.com/AndreyAkinshin) (Project Lead),\n  [Adam Sitnik](https://github.com/adamsitnik),\n  [Yegor Stepanov](https://github.com/YegorStepanov),\n  [Tim Cassell](https://github.com/timcassell).\n\n[All contributors on GitHub (200+)](https://github.com/dotnet/BenchmarkDotNet/graphs/contributors)\n\nBenchmarkDotNet is a part of the [.NET Foundation](https://dotnetfoundation.org)."
  },
  {
    "path": "docs/articles/toc.yml",
    "content": "- name: Overview\n  href: overview.md\n- name: Guides\n  href: guides/toc.yml\n- name: Features\n  href: features/toc.yml\n- name: Configs\n  href: configs/toc.yml\n- name: Samples\n  href: samples/toc.yml\n- name: Contributing\n  href: contributing/toc.yml\n- name: FAQ\n  href: faq.md\n- name: Team\n  href: team.md\n- name: License\n  href: license.md\n- name: Analyzers\n  href: analyzers.md\n"
  },
  {
    "path": "docs/docfx.json",
    "content": "{\n  \"metadata\": [\n    {\n      \"src\": [\n        {\n          \"files\": [\n            \"src/BenchmarkDotNet/bin/Release/netstandard2.0/BenchmarkDotNet.dll\",\n            \"src/BenchmarkDotNet/bin/Release/netstandard2.0/BenchmarkDotNet.Annotations.dll\"\n          ],\n          \"src\": \"..\"\n        }\n      ],\n      \"dest\": \"api\",\n      \"filter\": \"filter.yml\",\n      \"properties\": {\n        \"TargetFramework\": \"netstandard2.0\"\n      },\n      \"disableGitFeatures\": true\n    }\n  ],\n  \"build\": {\n    \"content\": [\n      {\n        \"files\": [\n          \"api/**.yml\",\n          \"api/index.md\"\n        ]\n      },\n      {\n        \"files\": [\n          \"articles/**.md\",\n          \"articles/**/toc.yml\",\n          \"changelog/toc.yml\",\n          \"changelog/*.md\",\n          \"toc.yml\",\n          \"*.md\"\n        ]\n      }\n    ],\n    \"resource\": [\n      {\n        \"files\": [\n          \"images/**\",\n          \"logo/**\"\n        ]\n      }\n    ],\n    \"dest\": \"_site\",\n    \"globalMetadataFiles\": [],\n    \"fileMetadataFiles\": [],\n    \"template\": [\n      \"default\",\n      \"modern\",\n      \"template\"\n    ],\n    \"xrefService\": [\n      \"https://xref.docs.microsoft.com/query?uid={uid}\"\n    ],\n    \"markdownEngineName\": \"markdig\",\n    \"noLangKeyword\": false,\n    \"keepFileLink\": false,\n    \"cleanupCacheHistory\": false,\n    \"disableGitFeatures\": false,\n    \"globalMetadata\" :\n    {\n      \"_appTitle\" : \"BenchmarkDotNet\",\n      \"_appFooter\" : \"Copyright &copy; 2013–2024 .NET Foundation and contributors\",\n      \"_appLogoPath\" : \"logo/icon.svg\",\n      \"_appFaviconPath\": \"logo/icon-32.png\",\n      \"_enableSearch\": true,\n      \"_disableContribution\": true\n    },\n    \"sitemap\":\n    {\n      \"baseUrl\": \"https://benchmarkdotnet.org/\",\n      \"priority\": 0.8,\n      \"changefreq\": \"monthly\",\n      \"fileOptions\":{\n          \"**/articles/**\": {\n              \"priority\": 0.8\n          },\n          \"**/changelog/**\": {\n              \"priority\": 0.5\n          },\n          \"**/api/**\": {\n              \"priority\": 0.3\n          }\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "docs/filter.yml",
    "content": "apiRules:\n- exclude:\n    uidRegex: ^System\\.Object\n    type: member # Avoid list of inherited Object members for each type.\n"
  },
  {
    "path": "docs/guide/README.md",
    "content": "Old versions of the NuGet package use `https://raw.githubusercontent.com/dotnet/BenchmarkDotNet/master/docs/guide/logo.png` as a logo url.\nSo, we have to keep the `logo.png` file for backward compatibility."
  },
  {
    "path": "docs/template/public/main.css",
    "content": "#logo {\n  width: 50px;\n  height: 50px;\n}\n\n#breadcrumb {\n  display: none;\n}\n\n.affix {\n  display: none !important;\n}"
  },
  {
    "path": "docs/template/public/main.js",
    "content": "export default {\n  iconLinks: [\n    {\n      icon: 'github',\n      href: 'https://github.com/dotnet/BenchmarkDotNet',\n      title: 'GitHub'\n    },\n    {\n      icon: 'twitter',\n      href: 'https://twitter.com/BenchmarkDotNet',\n      title: 'Twitter'\n    },\n    {\n      icon: 'heart',\n      href: 'https://github.com/sponsors/AndreyAkinshin',\n      title: 'Sponsor'\n    }\n  ]\n}"
  },
  {
    "path": "docs/toc.yml",
    "content": "- name: Articles\n  href: articles/\n- name: API\n  href: api/\n  homepage: api/index.md\n- name: ChangeLog\n  href: changelog/\n  homepage: changelog/index.md"
  },
  {
    "path": "samples/BenchmarkDotNet.Maui.slnx",
    "content": "<Solution>\n  <Configurations>\n    <Platform Name=\"Any CPU\" />\n    <Platform Name=\"x64\" />\n    <Platform Name=\"x86\" />\n  </Configurations>\n  <Folder Name=\"/samples/\">\n    <Project Path=\"BenchmarkDotNet.Samples.Maui/BenchmarkDotNet.Samples.Maui.csproj\" />\n  </Folder>\n  <Folder Name=\"/src/\">\n    <Project Path=\"../src/BenchmarkDotNet.Annotations/BenchmarkDotNet.Annotations.csproj\" />\n    <Project Path=\"../src/BenchmarkDotNet/BenchmarkDotNet.csproj\" />\n  </Folder>\n</Solution>\n"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/BenchmarkDotNet.Samples.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\n  <Import Project=\"..\\..\\build\\common.props\" />\n  <PropertyGroup>\n    <AssemblyTitle>BenchmarkDotNet.Samples</AssemblyTitle>\n    <TargetFrameworks>net8.0;net462</TargetFrameworks>\n    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>\n    <AssemblyName>BenchmarkDotNet.Samples</AssemblyName>\n    <OutputType>Exe</OutputType>\n    <PackageId>BenchmarkDotNet.Samples</PackageId>\n    <PlatformTarget>AnyCPU</PlatformTarget>\n    <DebugSymbols>true</DebugSymbols>\n    <NoWarn>$(NoWarn);CA1018;CA5351;CA1825</NoWarn>\n    <!-- Disable entry point generation as this project has it's own entry point -->\n    <GenerateProgramFile>false</GenerateProgramFile>\n    <!-- Disable parallel tests between TargetFrameworks -->\n    <TestTfmsInParallel>false</TestTfmsInParallel>\n  </PropertyGroup>\n  <ItemGroup Condition=\" '$(TargetFrameworkIdentifier)' == '.NETFramework' \">\n    <Reference Include=\"System.Reflection\" />\n  </ItemGroup>\n  <PropertyGroup>\n    <!-- Use 8.0.0 as baseline package for IntroNuGet -->\n    <SihVersion Condition=\"'$(SihVersion)' == ''\">8.0.0</SihVersion>\n  </PropertyGroup>\n  <ItemGroup>\n    <PackageReference Include=\"System.IO.Hashing\" Version=\"[$(SihVersion)]\" />\n  </ItemGroup>\n  <ItemGroup>\n    <PackageReference Include=\"System.Drawing.Common\" Version=\"10.0.3\" />\n    <!-- The Test SDK is required only for the VSTest Adapter to work -->\n    <PackageReference Include=\"Microsoft.NET.Test.Sdk\" Version=\"18.0.1\" />\n    <!-- This package enables the Visual Studio Profiler integration IntroVisualStudioProfiler.cs -->\n    <PackageReference Include=\"Microsoft.VisualStudio.DiagnosticsHub.BenchmarkDotNetDiagnosers\" Version=\"18.3.36812.1\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ProjectReference Include=\"..\\..\\src\\BenchmarkDotNet.Diagnostics.dotTrace\\BenchmarkDotNet.Diagnostics.dotTrace.csproj\" />\n    <ProjectReference Include=\"..\\..\\src\\BenchmarkDotNet.Diagnostics.dotMemory\\BenchmarkDotNet.Diagnostics.dotMemory.csproj\" />\n    <ProjectReference Include=\"..\\..\\src\\BenchmarkDotNet\\BenchmarkDotNet.csproj\" />\n    <ProjectReference Include=\"..\\..\\src\\BenchmarkDotNet.Diagnostics.Windows\\BenchmarkDotNet.Diagnostics.Windows.csproj\" />\n    <ProjectReference Include=\"..\\..\\src\\BenchmarkDotNet.TestAdapter\\BenchmarkDotNet.TestAdapter.csproj\" />\n  </ItemGroup>\n  <ItemGroup>\n    <!-- Enables analyzers for this project (this is required since ProjectReference is not transitive). -->\n    <ProjectReference Include=\"..\\..\\src\\BenchmarkDotNet.Analyzers\\BenchmarkDotNet.Analyzers.csproj\" ReferenceOutputAssembly=\"false\" OutputItemType=\"Analyzer\"/>\n  </ItemGroup>\n  <Import Project=\"..\\..\\build\\common.targets\" />\n</Project>\n"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/BenchmarkDotNet.Samples.csproj.DotSettings",
    "content": "﻿<wpf:ResourceDictionary xml:space=\"preserve\" xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\" xmlns:s=\"clr-namespace:System;assembly=mscorlib\" xmlns:ss=\"urn:shemas-jetbrains-com:settings-storage-xaml\" xmlns:wpf=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">\n\t<s:Boolean x:Key=\"/Default/CodeInspection/Highlighting/InspectionSeverities/=ArrangeConstructorOrDestructorBody/@EntryIndexRemoved\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/CodeInspection/Highlighting/InspectionSeverities/=ArrangeLocalFunctionBody/@EntryIndexRemoved\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/CodeInspection/Highlighting/InspectionSeverities/=ArrangeMethodOrOperatorBody/@EntryIndexRemoved\">True</s:Boolean>\n\t<s:String x:Key=\"/Default/CodeInspection/Highlighting/InspectionSeverities/=ArrangeAccessorOwnerBody/@EntryIndexedValue\">DO_NOT_SHOW</s:String>\n\t<s:String x:Key=\"/Default/CodeInspection/Highlighting/InspectionSeverities/=ArrangeConstructorOrDestructorBody/@EntryIndexedValue\"></s:String>\n\t<s:String x:Key=\"/Default/CodeInspection/Highlighting/InspectionSeverities/=ArrangeLocalFunctionBody/@EntryIndexedValue\"></s:String>\n\t<s:String x:Key=\"/Default/CodeInspection/Highlighting/InspectionSeverities/=ArrangeMethodOrOperatorBody/@EntryIndexedValue\"></s:String>\n\t<s:String x:Key=\"/Default/CodeInspection/Highlighting/InspectionSeverities/=ArrangeTypeMemberModifiers/@EntryIndexedValue\">DO_NOT_SHOW</s:String>\n\t<s:String x:Key=\"/Default/CodeInspection/Highlighting/InspectionSeverities/=ArrangeTypeModifiers/@EntryIndexedValue\">DO_NOT_SHOW</s:String>\n\t<s:String x:Key=\"/Default/CodeInspection/Highlighting/InspectionSeverities/=FieldCanBeMadeReadOnly_002EGlobal/@EntryIndexedValue\">DO_NOT_SHOW</s:String>\n\t<s:String x:Key=\"/Default/CodeInspection/Highlighting/InspectionSeverities/=FieldCanBeMadeReadOnly_002ELocal/@EntryIndexedValue\">DO_NOT_SHOW</s:String>\n\t<s:String x:Key=\"/Default/CodeInspection/Highlighting/InspectionSeverities/=ForCanBeConvertedToForeach/@EntryIndexedValue\">DO_NOT_SHOW</s:String>\n\t<s:String x:Key=\"/Default/CodeInspection/Highlighting/InspectionSeverities/=InconsistentNaming/@EntryIndexedValue\">DO_NOT_SHOW</s:String>\n\t<s:String x:Key=\"/Default/CodeInspection/Highlighting/InspectionSeverities/=LoopCanBeConvertedToQuery/@EntryIndexedValue\">DO_NOT_SHOW</s:String>\n\t<s:String x:Key=\"/Default/CodeInspection/Highlighting/InspectionSeverities/=MemberCanBeMadeStatic_002EGlobal/@EntryIndexedValue\">DO_NOT_SHOW</s:String>\n\t<s:String x:Key=\"/Default/CodeInspection/Highlighting/InspectionSeverities/=MemberCanBeMadeStatic_002ELocal/@EntryIndexedValue\">DO_NOT_SHOW</s:String>\n\t<s:String x:Key=\"/Default/CodeInspection/Highlighting/InspectionSeverities/=TailRecursiveCall/@EntryIndexedValue\">DO_NOT_SHOW</s:String>\n\t<s:String x:Key=\"/Default/CodeInspection/Highlighting/InspectionSeverities/=UnusedMember_002EGlobal/@EntryIndexedValue\">DO_NOT_SHOW</s:String>\n\t<s:String x:Key=\"/Default/CodeInspection/Highlighting/InspectionSeverities/=UnusedMember_002ELocal/@EntryIndexedValue\">DO_NOT_SHOW</s:String>\n    <s:Boolean x:Key=\"/Default/CodeInspection/Highlighting/InspectionSeverities/=RemoveRedundantBraces/@EntryIndexRemoved\">True</s:Boolean>\n    <s:String x:Key=\"/Default/CodeInspection/Highlighting/InspectionSeverities/=PossibleNullReferenceException/@EntryIndexedValue\">DO_NOT_SHOW</s:String>\n    <s:String x:Key=\"/Default/CodeInspection/Highlighting/InspectionSeverities/=RedundantExplicitArrayCreation/@EntryIndexedValue\">DO_NOT_SHOW</s:String>\n    <s:String x:Key=\"/Default/CodeInspection/Highlighting/InspectionSeverities/=UnusedParameter_002EGlobal/@EntryIndexedValue\">DO_NOT_SHOW</s:String>\n    <s:String x:Key=\"/Default/CodeInspection/Highlighting/InspectionSeverities/=UnusedParameter_002ELocal/@EntryIndexedValue\">DO_NOT_SHOW</s:String>\t\n</wpf:ResourceDictionary>"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroArguments.cs",
    "content": "using System.Threading;\nusing BenchmarkDotNet.Attributes;\n\nnamespace BenchmarkDotNet.Samples\n{\n    public class IntroArguments\n    {\n        [Params(true, false)] // Arguments can be combined with Params\n        public bool AddExtra5Milliseconds;\n\n        [Benchmark]\n        [Arguments(100, 10)]\n        [Arguments(100, 20)]\n        [Arguments(200, 10)]\n        [Arguments(200, 20)]\n        public void Benchmark(int a, int b)\n        {\n            if (AddExtra5Milliseconds)\n                Thread.Sleep(a + b + 5);\n            else\n                Thread.Sleep(a + b);\n        }\n    }\n}"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroArgumentsPriority.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Threading;\nusing BenchmarkDotNet.Attributes;\n\nnamespace BenchmarkDotNet.Samples\n{\n    public class IntroArgumentsPriority\n    {\n        [Params(100, Priority = 0)] // Argument priority can be combined with Params priority\n        public int A { get; set; }\n\n        [Arguments(5, Priority = -10)] // Define priority just once for multiple argument attributes\n        [Arguments(10)]\n        [Arguments(20)]\n        [Benchmark]\n        public void Benchmark(int b) => Thread.Sleep(A + b);\n\n        [Benchmark]\n        [ArgumentsSource(nameof(Numbers), Priority = 10)]\n        public void ManyArguments(int c, int d) => Thread.Sleep(A + c + d);\n\n        public IEnumerable<object[]> Numbers()\n        {\n            yield return new object[] { 1, 2 };\n        }\n    }\n}"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroArgumentsSource.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Threading;\nusing BenchmarkDotNet.Attributes;\n\nnamespace BenchmarkDotNet.Samples\n{\n    public class IntroArgumentsSource\n    {\n        [Benchmark]\n        [ArgumentsSource(nameof(Numbers))]\n        public double ManyArguments(double x, double y) => Math.Pow(x, y);\n\n        public IEnumerable<object[]> Numbers() // for multiple arguments it's an IEnumerable of array of objects (object[])\n        {\n            yield return new object[] { 1.0, 1.0 };\n            yield return new object[] { 2.0, 2.0 };\n            yield return new object[] { 4.0, 4.0 };\n            yield return new object[] { 10.0, 10.0 };\n        }\n\n        [Benchmark]\n        [ArgumentsSource(typeof(BenchmarkArguments), nameof(BenchmarkArguments.TimeSpans))] // when the arguments come from a different type, specify that type here\n        public void SingleArgument(TimeSpan time) => Thread.Sleep(time);\n    }\n\n    public static class BenchmarkArguments\n    {\n        public static IEnumerable<object> TimeSpans() // for single argument it's an IEnumerable of objects (object)\n        {\n            yield return TimeSpan.FromMilliseconds(10);\n            yield return TimeSpan.FromMilliseconds(100);\n        }\n    }\n}"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroArrayParam.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing BenchmarkDotNet.Attributes;\n\nnamespace BenchmarkDotNet.Samples\n{\n    public class IntroArrayParam\n    {\n        [Benchmark]\n        [ArgumentsSource(nameof(Data))]\n        public int ArrayIndexOf(int[] array, int value)\n            => Array.IndexOf(array, value);\n\n        [Benchmark]\n        [ArgumentsSource(nameof(Data))]\n        public int ManualIndexOf(int[] array, int value)\n        {\n            for (int i = 0; i < array.Length; i++)\n                if (array[i] == value)\n                    return i;\n\n            return -1;\n        }\n\n        public IEnumerable<object[]> Data()\n        {\n            yield return new object[] { new int[] { 1, 2, 3 }, 4 };\n            yield return new object[] { Enumerable.Range(0, 100).ToArray(), 4 };\n            yield return new object[] { Enumerable.Range(0, 100).ToArray(), 101 };\n        }\n    }\n}"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroBasic.cs",
    "content": "﻿using System.Threading;\nusing BenchmarkDotNet.Attributes;\n\nnamespace BenchmarkDotNet.Samples\n{\n    // It is very easy to use BenchmarkDotNet. You should just create a class\n    public class IntroBasic\n    {\n        // And define a method with the Benchmark attribute\n        [Benchmark]\n        public void Sleep() => Thread.Sleep(10);\n\n        // You can write a description for your method.\n        [Benchmark(Description = \"Thread.Sleep(10)\")]\n        public void SleepWithDescription() => Thread.Sleep(10);\n    }\n}\n"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroBenchmarkBaseline.cs",
    "content": "﻿using System.Threading;\nusing BenchmarkDotNet.Attributes;\n\nnamespace BenchmarkDotNet.Samples\n{\n    public class IntroBenchmarkBaseline\n    {\n        [Benchmark]\n        public void Time50() => Thread.Sleep(50);\n\n        [Benchmark(Baseline = true)]\n        public void Time100() => Thread.Sleep(100);\n\n        [Benchmark]\n        public void Time150() => Thread.Sleep(150);\n    }\n}"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroCategories.cs",
    "content": "using System.Threading;\nusing BenchmarkDotNet.Attributes;\n\nnamespace BenchmarkDotNet.Samples\n{\n    [DryJob]\n    [CategoriesColumn]\n    [BenchmarkCategory(\"Awesome\")]\n    [AnyCategoriesFilter(\"A\", \"1\")]\n    public class IntroCategories\n    {\n        [Benchmark]\n        [BenchmarkCategory(\"A\", \"1\")]\n        public void A1() => Thread.Sleep(10); // Will be benchmarked\n\n        [Benchmark]\n        [BenchmarkCategory(\"A\", \"2\")]\n        public void A2() => Thread.Sleep(10); // Will be benchmarked\n\n        [Benchmark]\n        [BenchmarkCategory(\"B\", \"1\")]\n        public void B1() => Thread.Sleep(10); // Will be benchmarked\n\n        [Benchmark]\n        [BenchmarkCategory(\"B\", \"2\")]\n        public void B2() => Thread.Sleep(10);\n    }\n}"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroCategoryBaseline.cs",
    "content": "﻿using System.Threading;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Configs;\n\nnamespace BenchmarkDotNet.Samples\n{\n    [GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByCategory)]\n    [CategoriesColumn]\n    public class IntroCategoryBaseline\n    {\n        [BenchmarkCategory(\"Fast\"), Benchmark(Baseline = true)]\n        public void Time50() => Thread.Sleep(50);\n\n        [BenchmarkCategory(\"Fast\"), Benchmark]\n        public void Time100() => Thread.Sleep(100);\n\n        [BenchmarkCategory(\"Slow\"), Benchmark(Baseline = true)]\n        public void Time550() => Thread.Sleep(550);\n\n        [BenchmarkCategory(\"Slow\"), Benchmark]\n        public void Time600() => Thread.Sleep(600);\n    }\n}"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroCategoryDiscoverer.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Reflection;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Running;\n\nnamespace BenchmarkDotNet.Samples\n{\n    [DryJob]\n    [CategoriesColumn]\n    [CustomCategoryDiscoverer]\n    public class IntroCategoryDiscoverer\n    {\n        private class CustomCategoryDiscoverer : DefaultCategoryDiscoverer\n        {\n            public override string[] GetCategories(MethodInfo method)\n            {\n                var categories = new List<string>();\n                categories.AddRange(base.GetCategories(method));\n                categories.Add(\"All\");\n                categories.Add(method.Name.Substring(0, 1));\n                return categories.ToArray();\n            }\n        }\n\n        [AttributeUsage(AttributeTargets.Class)]\n        private class CustomCategoryDiscovererAttribute : Attribute, IConfigSource\n        {\n            public CustomCategoryDiscovererAttribute()\n            {\n                Config = ManualConfig.CreateEmpty()\n                    .WithCategoryDiscoverer(new CustomCategoryDiscoverer());\n            }\n\n            public IConfig Config { get; }\n        }\n\n\n        [Benchmark]\n        public void Foo() { }\n\n        [Benchmark]\n        public void Bar() { }\n    }\n}"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroColdStart.cs",
    "content": "﻿using System;\nusing System.Threading;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Engines;\n\nnamespace BenchmarkDotNet.Samples\n{\n    [SimpleJob(RunStrategy.ColdStart, iterationCount: 5)]\n    [MinColumn, MaxColumn, MeanColumn, MedianColumn]\n    public class IntroColdStart\n    {\n        private bool firstCall;\n\n        [Benchmark]\n        public void Foo()\n        {\n            if (firstCall == false)\n            {\n                firstCall = true;\n                Console.WriteLine(\"// First call\");\n                Thread.Sleep(1000);\n            }\n            else\n                Thread.Sleep(10);\n        }\n    }\n}"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroComparableComplexParam.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing BenchmarkDotNet.Attributes;\n\nnamespace BenchmarkDotNet.Samples\n{\n    public class IntroComparableComplexParam\n    {\n        [ParamsSource(nameof(ValuesForA))]\n        public ComplexParam? A { get; set; }\n\n        public IEnumerable<ComplexParam> ValuesForA => [new ComplexParam(1, \"First\"), new ComplexParam(2, \"Second\")];\n\n        [Benchmark]\n        public object? Benchmark() => A;\n\n        // Only non generic IComparable is required to provide custom order behavior, but implementing IComparable<> too is customary.\n        public class ComplexParam : IComparable<ComplexParam>, IComparable\n        {\n            public ComplexParam(int value, string name)\n            {\n                Value = value;\n                Name = name;\n            }\n\n            public int Value { get; set; }\n\n            public string Name { get; set; }\n\n            public override string ToString() => Name;\n\n            public int CompareTo(ComplexParam? other) => other == null ? 1 : Value.CompareTo(other.Value);\n\n            public int CompareTo(object? obj)\n            {\n                if (obj == null)\n                    return 1;\n\n                if (obj is not ComplexParam other)\n                    throw new ArgumentException();\n\n                return CompareTo(other);\n            }\n        }\n    }\n}"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroConfigSource.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing System.Threading;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Jobs;\n\nnamespace BenchmarkDotNet.Samples\n{\n    [MyConfigSource(Jit.LegacyJit, Jit.RyuJit)]\n    public class IntroConfigSource\n    {\n        /// <summary>\n        /// Dry-x64 jobs for specific jits\n        /// </summary>\n        private class MyConfigSourceAttribute : Attribute, IConfigSource\n        {\n            public IConfig Config { get; }\n\n            public MyConfigSourceAttribute(params Jit[] jits)\n            {\n                var jobs = jits\n                    .Select(jit => new Job(Job.Dry) { Environment = { Jit = jit, Platform = Platform.X64 } })\n                    .ToArray();\n                Config = ManualConfig.CreateEmpty().AddJob(jobs);\n            }\n        }\n\n        [Benchmark]\n        public void Foo()\n        {\n            Thread.Sleep(10);\n        }\n    }\n}"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroConfigUnion.cs",
    "content": "﻿using System.Threading;\nusing BenchmarkDotNet.Analysers;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Columns;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Exporters;\nusing BenchmarkDotNet.Exporters.Csv;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Loggers;\n\nnamespace BenchmarkDotNet.Samples\n{\n    [Config(typeof(Config))]\n    public class IntroConfigUnion\n    {\n        private class Config : ManualConfig\n        {\n            public Config()\n            {\n                AddJob(Job.Dry);\n                AddLogger(ConsoleLogger.Default);\n                AddColumn(TargetMethodColumn.Method, StatisticColumn.Max);\n                AddExporter(RPlotExporter.Default, CsvExporter.Default);\n                AddAnalyser(EnvironmentAnalyser.Default);\n                UnionRule = ConfigUnionRule.AlwaysUseLocal;\n            }\n        }\n\n        [Benchmark]\n        public void Foo()\n        {\n            Thread.Sleep(10);\n        }\n    }\n}"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroCultureInfo.cs",
    "content": "using System.Globalization;\nusing System.Threading;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Configs;\n\nnamespace BenchmarkDotNet.Samples\n{\n    [Config(typeof(Config))]\n    [ShortRunJob]\n    public class IntroCultureInfo\n    {\n        private class Config : ManualConfig\n        {\n            public Config()\n            {\n                CultureInfo = (CultureInfo) CultureInfo.InvariantCulture.Clone();\n                CultureInfo.NumberFormat.NumberDecimalSeparator = \"@\";\n            }\n        }\n\n        [Benchmark]\n        public void Foo() => Thread.Sleep(100);\n    }\n}"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroCustomMono.cs",
    "content": "﻿using BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Running;\n\nnamespace BenchmarkDotNet.Samples\n{\n    // *** Attribute Style ***\n\n    [MonoJob(\"Mono x64\", @\"C:\\Program Files\\Mono\\bin\\mono.exe\")]\n    [MonoJob(\"Mono x86\", @\"C:\\Program Files (x86)\\Mono\\bin\\mono.exe\")]\n    public class IntroCustomMono\n    {\n        [Benchmark]\n        public void Foo()\n        {\n            // Benchmark body\n        }\n    }\n\n    // *** Object Style ***\n\n    [Config(typeof(Config))]\n    public class IntroCustomMonoObjectStyle\n    {\n        private class Config : ManualConfig\n        {\n            public Config()\n            {\n                AddJob(Job.ShortRun.WithRuntime(new MonoRuntime(\n                    \"Mono x64\", @\"C:\\Program Files\\Mono\\bin\\mono.exe\")));\n                AddJob(Job.ShortRun.WithRuntime(new MonoRuntime(\n                    \"Mono x86\", @\"C:\\Program Files (x86)\\Mono\\bin\\mono.exe\")));\n            }\n        }\n\n        [Benchmark]\n        public void Foo()\n        {\n            // Benchmark body\n        }\n    }\n\n    // ** Object Style, Using AOT **\n\n    [Config(typeof(Config))]\n    public class IntroCustomMonoObjectStyleAot\n    {\n        private class Config : ManualConfig\n        {\n            public void AddMono (string name, string mono_top_dir)\n            {\n                var aot_compile_args  = \"--aot=llvm\";\n                var mono_bcl = $@\"{mono_top_dir}\\lib\\mono\\4.5\";\n                var mono_bin = $@\"{mono_top_dir}\\bin\\mono.exe\";\n                AddJob(Job.ShortRun.WithRuntime(new MonoRuntime(\n                    name, mono_bin, aot_compile_args, mono_bcl)));\n            }\n\n            public Config()\n            {\n                AddMono(\"Mono x64\", @\"C:\\Program Files\\Mono\");\n                AddMono(\"Mono x86\", @\"C:\\Program Files (x86)\\Mono\");\n            }\n        }\n\n        [Benchmark]\n        public void Foo()\n        {\n            // Benchmark body\n        }\n    }\n\n    // *** Fluent Config ***\n\n    public class IntroCustomMonoFluentConfig\n    {\n        public static void Run()\n        {\n            BenchmarkRunner.Run<IntroCustomMonoFluentConfig>(ManualConfig\n                .CreateMinimumViable()\n                .AddJob(Job.ShortRun.WithRuntime(new MonoRuntime(\n                    \"Mono x64\", @\"C:\\Program Files\\Mono\\bin\\mono.exe\")))\n                .AddJob(Job.ShortRun.WithRuntime(new MonoRuntime(\n                    \"Mono x86\", @\"C:\\Program Files (x86)\\Mono\\bin\\mono.exe\"))));\n        }\n\n        [Benchmark]\n        public void Foo()\n        {\n            // Benchmark body\n        }\n    }\n}"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroCustomMonoArguments.cs",
    "content": "﻿using BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Jobs;\n\nnamespace BenchmarkDotNet.Samples\n{\n    [Config(typeof(ConfigWithCustomArguments))]\n    public class IntroCustomMonoArguments\n    {\n        public class ConfigWithCustomArguments : ManualConfig\n        {\n            public ConfigWithCustomArguments()\n            {\n                // --optimize=MODE , -O=mode\n                // MODE is a comma separated list of optimizations. They also allow\n                // optimizations to be turned off by prefixing the optimization\n                // name with a minus sign.\n\n                AddJob(Job.Default\n                    .WithRuntime(MonoRuntime.Default)\n                    .WithArguments([new MonoArgument(\"--optimize=inline\")])\n                    .WithId(\"Inlining enabled\"));\n                AddJob(Job.Default\n                    .WithRuntime(MonoRuntime.Default)\n                    .WithArguments([new MonoArgument(\"--optimize=-inline\")])\n                    .WithId(\"Inlining disabled\"));\n            }\n        }\n\n        [Benchmark]\n        public void Sample()\n        {\n            ShouldGetInlined(); ShouldGetInlined(); ShouldGetInlined();\n            ShouldGetInlined(); ShouldGetInlined(); ShouldGetInlined();\n            ShouldGetInlined(); ShouldGetInlined(); ShouldGetInlined();\n        }\n\n        private void ShouldGetInlined() { }\n    }\n}"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroDeferredExecution.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Linq;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Engines;\n\nnamespace BenchmarkDotNet.Samples\n{\n    public class IntroDeferredExecution\n    {\n        private readonly int[] numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\n\n        private readonly Consumer consumer = new Consumer();\n\n        /// <summary>\n        /// this benchmark returns a deferred LINQ query which is NOT executed\n        /// so the benchmark measures the cost of creating the query, not the actual execution\n        /// this is WRONG\n        /// You can read more about LINQ and Deferred Execution <see href=\"https://blogs.msdn.microsoft.com/charlie/2007/12/10/linq-and-deferred-execution/\">here</see>\n        /// </summary>\n        /// <returns>deferred LINQ query</returns>\n        [Benchmark]\n        public IEnumerable<int> Wrong() => from number in numbers orderby number descending select number;\n\n        /// <summary>\n        /// this benchmark uses .Consume extension method which executes given deferred query and consumes its result\n        /// so the benchmark measures the cost of creating the query and executing it\n        /// </summary>\n        [Benchmark]\n        public void Ok() => (from number in numbers orderby number descending select number).Consume(consumer);\n    }\n}"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroDisassembly.cs",
    "content": "﻿using BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Diagnosers;\nusing System.Linq;\n\nnamespace BenchmarkDotNet.Samples\n{\n    [DisassemblyDiagnoser(printInstructionAddresses: true, syntax: DisassemblySyntax.Masm)]\n    public class IntroDisassembly\n    {\n        private int[] field = Enumerable.Range(0, 100).ToArray();\n\n        [Benchmark]\n        public int SumLocal()\n        {\n            var local = field; // we use local variable that points to the field\n\n            int sum = 0;\n            for (int i = 0; i < local.Length; i++)\n                sum += local[i];\n\n            return sum;\n        }\n\n        [Benchmark]\n        public int SumField()\n        {\n            int sum = 0;\n            for (int i = 0; i < field.Length; i++)\n                sum += field[i];\n\n            return sum;\n        }\n    }\n}"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroDisassemblyAllJits.cs",
    "content": "﻿using BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Diagnosers;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Jobs;\n\nnamespace BenchmarkDotNet.Samples\n{\n    [Config(typeof(MultipleJits))]\n    public class IntroDisassemblyAllJits\n    {\n        public class MultipleJits : ManualConfig\n        {\n            public MultipleJits()\n            {\n                AddJob(Job.ShortRun.WithPlatform(Platform.X86).WithRuntime(new MonoRuntime(name: \"Mono x86\", customPath: @\"C:\\Program Files (x86)\\Mono\\bin\\mono.exe\")));\n                AddJob(Job.ShortRun.WithPlatform(Platform.X64).WithRuntime(new MonoRuntime(name: \"Mono x64\", customPath: @\"C:\\Program Files\\Mono\\bin\\mono.exe\")));\n\n                AddJob(Job.ShortRun.WithJit(Jit.LegacyJit).WithPlatform(Platform.X86).WithRuntime(ClrRuntime.Net462));\n                AddJob(Job.ShortRun.WithJit(Jit.LegacyJit).WithPlatform(Platform.X64).WithRuntime(ClrRuntime.Net462));\n\n                AddJob(Job.ShortRun.WithJit(Jit.RyuJit).WithPlatform(Platform.X64).WithRuntime(ClrRuntime.Net462));\n\n                // RyuJit for .NET Core 5.0\n                AddJob(Job.ShortRun.WithJit(Jit.RyuJit).WithPlatform(Platform.X64).WithRuntime(CoreRuntime.Core50));\n\n                AddDiagnoser(new DisassemblyDiagnoser(new DisassemblyDiagnoserConfig(maxDepth: 3, exportDiff: true)));\n            }\n        }\n\n        private Increment increment = new Increment();\n\n        [Benchmark]\n        public int CallVirtualMethod() => increment.OperateTwice(10);\n\n        public abstract class Operation  // abstract unary integer operation\n        {\n            public abstract int Operate(int input);\n\n            public int OperateTwice(int input) => Operate(Operate(input)); // two virtual calls to Operate\n        }\n\n        public sealed class Increment : Operation // concrete, sealed operation: increment by fixed amount\n        {\n            public readonly int Amount;\n            public Increment(int amount = 1) { Amount = amount; }\n\n            public override int Operate(int input) => input + Amount;\n        }\n    }\n}"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroDisassemblyDry.cs",
    "content": "﻿using BenchmarkDotNet.Attributes;\n\nnamespace BenchmarkDotNet.Samples\n{\n    [DisassemblyDiagnoser(maxDepth: 3)]\n    [DryJob]\n    public class IntroDisassemblyDry\n    {\n        [Benchmark]\n        public void Foo()\n        {\n\n        }\n    }\n}"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroDisassemblyRyuJit.cs",
    "content": "﻿using System.Linq;\nusing BenchmarkDotNet.Attributes;\n\nnamespace BenchmarkDotNet.Samples\n{\n    [DisassemblyDiagnoser(printSource: true)]\n    [RyuJitX64Job]\n    public class IntroDisassemblyRyuJit\n    {\n        private int[] field = Enumerable.Range(0, 100).ToArray();\n\n        [Benchmark]\n        public int SumLocal()\n        {\n            var local = field; // we use local variable that points to the field\n\n            int sum = 0;\n            for (int i = 0; i < local.Length; i++)\n                sum += local[i];\n\n            return sum;\n        }\n\n        [Benchmark]\n        public int SumField()\n        {\n            int sum = 0;\n            for (int i = 0; i < field.Length; i++)\n                sum += field[i];\n\n            return sum;\n        }\n    }\n}"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroDotMemoryDiagnoser.cs",
    "content": "using BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Diagnostics.dotMemory;\nusing System.Collections.Generic;\n\nnamespace BenchmarkDotNet.Samples\n{\n    // Profile benchmarks via dotMemory SelfApi profiling for all jobs\n    [DotMemoryDiagnoser]\n    [SimpleJob] // external-process execution\n    [InProcess] // in-process execution\n    public class IntroDotMemoryDiagnoser\n    {\n        [Params(1024)]\n        public int Size;\n\n        private byte[] dataArray = default!;\n        private IEnumerable<byte> dataEnumerable = default!;\n\n        [GlobalSetup]\n        public void Setup()\n        {\n            dataArray = new byte[Size];\n            dataEnumerable = dataArray;\n        }\n\n        [Benchmark]\n        public int IterateArray()\n        {\n            var count = 0;\n            foreach (var _ in dataArray)\n                count++;\n\n            return count;\n        }\n\n        [Benchmark]\n        public int IterateEnumerable()\n        {\n            var count = 0;\n            foreach (var _ in dataEnumerable)\n                count++;\n\n            return count;\n        }\n    }\n}"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroDotTraceDiagnoser.cs",
    "content": "using BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Diagnostics.dotTrace;\n\nnamespace BenchmarkDotNet.Samples\n{\n    // Profile benchmarks via dotTrace SelfApi profiling for all jobs\n    // See: https://www.nuget.org/packages/JetBrains.Profiler.SelfApi\n    [DotTraceDiagnoser]\n    [SimpleJob] // external-process execution\n    [InProcess] // in-process execution\n    public class IntroDotTraceDiagnoser\n    {\n        [Benchmark]\n        public void Fibonacci() => Fibonacci(30);\n\n        private static int Fibonacci(int n)\n        {\n            return n <= 1 ? n : Fibonacci(n - 1) + Fibonacci(n - 2);\n        }\n    }\n}"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroEnvVars.cs",
    "content": "﻿using BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Jobs;\n\nnamespace BenchmarkDotNet.Samples\n{\n    [Config(typeof(ConfigWithCustomEnvVars))]\n    public class IntroEnvVars\n    {\n        private class ConfigWithCustomEnvVars : ManualConfig\n        {\n            public ConfigWithCustomEnvVars()\n            {\n                AddJob(Job.Default.WithRuntime(CoreRuntime.Core80).WithId(\"Inlining enabled\"));\n                AddJob(Job.Default.WithRuntime(CoreRuntime.Core80)\n                    .WithEnvironmentVariables([\n                        new EnvironmentVariable(\"DOTNET_JitNoInline\", \"1\"),\n                        new EnvironmentVariable(\"COMPlus_JitNoInline\", \"1\")\n                    ])\n                    .WithId(\"Inlining disabled\"));\n            }\n        }\n\n        [Benchmark]\n        public void Foo()\n        {\n            // Benchmark body\n        }\n    }\n}\n"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroEventPipeProfiler.cs",
    "content": "﻿using System.Threading;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Diagnosers;\n\nnamespace BenchmarkDotNet.Samples\n{\n    [ShortRunJob]\n    [EventPipeProfiler(EventPipeProfile.CpuSampling)]\n    public class IntroEventPipeProfiler\n    {\n        [Benchmark]\n        public void Sleep() => Thread.Sleep(2000);\n    }\n}"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroEventPipeProfilerAdvanced.cs",
    "content": "﻿using System.Buffers;\nusing System.Diagnostics.Tracing;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Diagnosers;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Jobs;\nusing Microsoft.Diagnostics.NETCore.Client;\nusing Microsoft.Diagnostics.Tracing.Parsers;\n\nnamespace BenchmarkDotNet.Samples\n{\n    [Config(typeof(CustomConfig))]\n    public class IntroEventPipeProfilerAdvanced\n    {\n        private class CustomConfig : ManualConfig\n        {\n            public CustomConfig()\n            {\n                AddJob(Job.ShortRun.WithRuntime(CoreRuntime.Core50));\n\n                var providers = new[]\n                {\n                    new EventPipeProvider(ClrTraceEventParser.ProviderName, EventLevel.Verbose,\n                        (long) (ClrTraceEventParser.Keywords.Exception\n                        | ClrTraceEventParser.Keywords.GC\n                        | ClrTraceEventParser.Keywords.Jit\n                        | ClrTraceEventParser.Keywords.JitTracing // for the inlining events\n                        | ClrTraceEventParser.Keywords.Loader\n                        | ClrTraceEventParser.Keywords.NGen)),\n                    new EventPipeProvider(\"System.Buffers.ArrayPoolEventSource\", EventLevel.Informational, long.MaxValue),\n                };\n\n                AddDiagnoser(new EventPipeProfiler(providers: providers));\n            }\n        }\n\n        [Benchmark]\n        public void RentAndReturn_Shared()\n        {\n            var pool = ArrayPool<byte>.Shared;\n            byte[] array = pool.Rent(10000);\n            pool.Return(array);\n        }\n    }\n}"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroExceptionDiagnoser.cs",
    "content": "﻿using BenchmarkDotNet.Attributes;\nusing System;\n\nnamespace BenchmarkDotNet.Samples\n{\n    [ExceptionDiagnoser]\n    public class IntroExceptionDiagnoser\n    {\n        [Benchmark]\n        public void ThrowExceptionRandomly()\n        {\n            try\n            {\n                if (new Random().Next(0, 5) > 1)\n                {\n                    throw new Exception();\n                }\n            }\n            catch\n            {\n                // ignored\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroExport.cs",
    "content": "﻿using System;\nusing System.Threading;\nusing BenchmarkDotNet.Attributes;\n\nnamespace BenchmarkDotNet.Samples\n{\n    [ShortRunJob]\n    [MediumRunJob]\n    [KeepBenchmarkFiles]\n\n    [AsciiDocExporter]\n    [CsvExporter]\n    [CsvMeasurementsExporter]\n    [HtmlExporter]\n    [PlainExporter]\n    [RPlotExporter]\n    [JsonExporterAttribute.Brief]\n    [JsonExporterAttribute.BriefCompressed]\n    [JsonExporterAttribute.Full]\n    [JsonExporterAttribute.FullCompressed]\n    [MarkdownExporterAttribute.Default]\n    [MarkdownExporterAttribute.GitHub]\n    [MarkdownExporterAttribute.StackOverflow]\n    [MarkdownExporterAttribute.Atlassian]\n    [XmlExporterAttribute.Brief]\n    [XmlExporterAttribute.BriefCompressed]\n    [XmlExporterAttribute.Full]\n    [XmlExporterAttribute.FullCompressed]\n    public class IntroExport\n    {\n        private Random random = new Random(42);\n\n        [Benchmark(Baseline = true)]\n        public void Sleep10() => Thread.Sleep(10);\n\n        [Benchmark]\n        public void Sleep50Noisy() => Thread.Sleep(random.Next(100));\n    }\n}"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroExportJson.cs",
    "content": "﻿using System.Threading;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Exporters.Json;\n\nnamespace BenchmarkDotNet.Samples\n{\n    // *** Attribute style ***\n\n    [DryJob]\n    [JsonExporterAttribute.Brief]\n    [JsonExporterAttribute.Full]\n    [JsonExporterAttribute.BriefCompressed]\n    [JsonExporterAttribute.FullCompressed]\n    [JsonExporter(\"-custom\", indentJson: true, excludeMeasurements: true)]\n    public class IntroExportJson\n    {\n        [Benchmark] public void Sleep10() => Thread.Sleep(10);\n        [Benchmark] public void Sleep20() => Thread.Sleep(20);\n    }\n\n    // *** Object style ***\n\n    [Config(typeof(Config))]\n    public class IntroJsonExportObjectStyle\n    {\n        private class Config : ManualConfig\n        {\n            public Config()\n            {\n                AddExporter(JsonExporter.Brief);\n                AddExporter(JsonExporter.Brief);\n                AddExporter(JsonExporter.Full);\n                AddExporter(JsonExporter.BriefCompressed);\n                AddExporter(JsonExporter.FullCompressed);\n                AddExporter(JsonExporter.Custom(\"-custom\", indentJson: true, excludeMeasurements: true));\n            }\n        }\n\n        [Benchmark] public void Sleep10() => Thread.Sleep(10);\n        [Benchmark] public void Sleep20() => Thread.Sleep(20);\n    }\n}"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroExportXml.cs",
    "content": "﻿using System.Threading;\nusing BenchmarkDotNet.Attributes;\n\nnamespace BenchmarkDotNet.Samples\n{\n    [DryJob]\n    [XmlExporterAttribute.Brief]\n    [XmlExporterAttribute.Full]\n    [XmlExporterAttribute.BriefCompressed]\n    [XmlExporterAttribute.FullCompressed]\n    [XmlExporter(\"-custom\", indentXml: true, excludeMeasurements: true)]\n    public class IntroExportXml\n    {\n        [Benchmark] public void Sleep10() => Thread.Sleep(10);\n        [Benchmark] public void Sleep20() => Thread.Sleep(20);\n    }\n}\n"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroFilters.cs",
    "content": "using System.Threading;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Filters;\n\nnamespace BenchmarkDotNet.Samples\n{\n    [DryJob]\n    [Config(typeof(Config))]\n    public class IntroFilters\n    {\n        private class Config : ManualConfig\n        {\n            // We will benchmark ONLY method with\n            // names (which contains \"A\" OR \"1\") AND (have length < 3)\n            public Config()\n            {\n                // benchmark with names which contains \"A\" OR \"1\"\n                AddFilter(new DisjunctionFilter(\n                    new NameFilter(name => name.Contains(\"A\")),\n                    new NameFilter(name => name.Contains(\"1\"))\n                ));\n\n                // benchmark with names with length < 3\n                AddFilter(new NameFilter(name => name.Length < 3));\n            }\n        }\n\n        [Benchmark] public void A1() => Thread.Sleep(10); // Will be benchmarked\n        [Benchmark] public void A2() => Thread.Sleep(10); // Will be benchmarked\n        [Benchmark] public void A3() => Thread.Sleep(10); // Will be benchmarked\n        [Benchmark] public void B1() => Thread.Sleep(10); // Will be benchmarked\n        [Benchmark] public void B2() => Thread.Sleep(10);\n        [Benchmark] public void B3() => Thread.Sleep(10);\n        [Benchmark] public void C1() => Thread.Sleep(10); // Will be benchmarked\n        [Benchmark] public void C2() => Thread.Sleep(10);\n        [Benchmark] public void C3() => Thread.Sleep(10);\n        [Benchmark] public void Aaa() => Thread.Sleep(10);\n    }\n}"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroFluentConfigBuilder.cs",
    "content": "﻿using System;\nusing System.Security.Cryptography;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Validators;\n\nnamespace BenchmarkDotNet.Samples\n{\n    public class Algo_Md5VsSha256\n    {\n        private const int N = 10000;\n        private readonly byte[] data;\n\n        private readonly MD5 md5 = MD5.Create();\n        private readonly SHA256 sha256 = SHA256.Create();\n\n        public Algo_Md5VsSha256()\n        {\n            data = new byte[N];\n            new Random(42).NextBytes(data);\n        }\n\n        [Benchmark(Baseline = true)]\n        public byte[] Md5() => md5.ComputeHash(data);\n\n        [Benchmark]\n        public byte[] Sha256() => sha256.ComputeHash(data);\n    }\n\n    public class IntroFluentConfigBuilder\n    {\n        public static void Run()\n        {\n            BenchmarkRunner\n                .Run<Algo_Md5VsSha256>(\n                    DefaultConfig.Instance\n                        .AddJob(Job.Default.WithRuntime(ClrRuntime.Net462))\n                        .AddJob(Job.Default.WithRuntime(CoreRuntime.Core80))\n                        .AddValidator(ExecutionValidator.FailOnError));\n        }\n    }\n}"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroGcMode.cs",
    "content": "﻿using System.Runtime.CompilerServices;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Order;\n\nnamespace BenchmarkDotNet.Samples\n{\n    [Config(typeof(Config))]\n    [Orderer(SummaryOrderPolicy.FastestToSlowest)]\n    [MemoryDiagnoser]\n    public class IntroGcMode\n    {\n        private class Config : ManualConfig\n        {\n            public Config()\n            {\n                AddJob(Job.MediumRun.WithGcServer(true).WithGcForce(true).WithId(\"ServerForce\"));\n                AddJob(Job.MediumRun.WithGcServer(true).WithGcForce(false).WithId(\"Server\"));\n                AddJob(Job.MediumRun.WithGcServer(false).WithGcForce(true).WithId(\"Workstation\"));\n                AddJob(Job.MediumRun.WithGcServer(false).WithGcForce(false).WithId(\"WorkstationForce\"));\n            }\n        }\n\n        [Benchmark(Description = \"new byte[10kB]\")]\n        public byte[] Allocate()\n        {\n            return new byte[10000];\n        }\n\n        [Benchmark(Description = \"stackalloc byte[10kB]\")]\n        public unsafe void AllocateWithStackalloc()\n        {\n            var array = stackalloc byte[10000];\n            Consume(array);\n        }\n\n        [MethodImpl(MethodImplOptions.NoInlining)]\n        private static unsafe void Consume(byte* input)\n        {\n        }\n    }\n}"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroGenericTypeArguments.cs",
    "content": "using System;\nusing BenchmarkDotNet.Attributes;\n\nnamespace BenchmarkDotNet.Samples\n{\n    [GenericTypeArguments(typeof(int))]\n    [GenericTypeArguments(typeof(char))]\n    public class IntroGenericTypeArguments<T>\n    {\n        [Benchmark] public T Create() => Activator.CreateInstance<T>();\n    }\n}"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroHardwareCounters.cs",
    "content": "﻿using System;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Diagnosers;\n\nnamespace BenchmarkDotNet.Samples\n{\n    [HardwareCounters(\n        HardwareCounter.BranchMispredictions,\n        HardwareCounter.BranchInstructions)]\n    public class IntroHardwareCounters\n    {\n        private const int N = 32767;\n        private readonly int[] sorted, unsorted;\n\n        public IntroHardwareCounters()\n        {\n            var random = new Random(0);\n            unsorted = new int[N];\n            sorted = new int[N];\n            for (int i = 0; i < N; i++)\n                sorted[i] = unsorted[i] = random.Next(256);\n            Array.Sort(sorted);\n        }\n\n        private static int Branch(int[] data)\n        {\n            int sum = 0;\n            for (int i = 0; i < N; i++)\n                if (data[i] >= 128)\n                    sum += data[i];\n            return sum;\n        }\n\n        private static int Branchless(int[] data)\n        {\n            int sum = 0;\n            for (int i = 0; i < N; i++)\n            {\n                int t = (data[i] - 128) >> 31;\n                sum += ~t & data[i];\n            }\n            return sum;\n        }\n\n        [Benchmark]\n        public int SortedBranch() => Branch(sorted);\n\n        [Benchmark]\n        public int UnsortedBranch() => Branch(unsorted);\n\n        [Benchmark]\n        public int SortedBranchless() => Branchless(sorted);\n\n        [Benchmark]\n        public int UnsortedBranchless() => Branchless(unsorted);\n    }\n}"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroHidingColumns.cs",
    "content": "﻿using BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Columns;\n\nnamespace BenchmarkDotNet.Samples\n{\n    [MemoryDiagnoser] // adds Gen0, Gen1, Gen2 and Allocated Bytes columns\n    [HideColumns(Column.Gen0, Column.Gen1, Column.Gen2)] // dont display GenX columns\n    public class IntroHidingColumns\n    {\n        [Benchmark]\n        public byte[] AllocateArray() => new byte[100_000];\n    }\n}\n"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroInProcess.cs",
    "content": "﻿using System.Runtime.CompilerServices;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Order;\nusing BenchmarkDotNet.Toolchains.InProcess.Emit;\n\nnamespace BenchmarkDotNet.Samples\n{\n    [Config(typeof(Config))]\n    [Orderer(SummaryOrderPolicy.FastestToSlowest)]\n    [MemoryDiagnoser]\n    public class IntroInProcess\n    {\n        private class Config : ManualConfig\n        {\n            public Config()\n            {\n                AddJob(Job.MediumRun\n                    .WithLaunchCount(1)\n                    .WithId(\"OutOfProc\"));\n\n                AddJob(Job.MediumRun\n                    .WithLaunchCount(1)\n                    .WithToolchain(InProcessEmitToolchain.Default)\n                    .WithId(\"InProcess\"));\n            }\n        }\n\n        [Benchmark(Description = \"new byte[10kB]\")]\n        public byte[] Allocate()\n        {\n            return new byte[10000];\n        }\n\n        [Benchmark(Description = \"stackalloc byte[10kB]\")]\n        public unsafe void AllocateWithStackalloc()\n        {\n            var array = stackalloc byte[10000];\n            Consume(array);\n        }\n\n        [MethodImpl(MethodImplOptions.NoInlining)]\n        private static unsafe void Consume(byte* input)\n        {\n        }\n    }\n}"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroInProcessWrongEnv.cs",
    "content": "﻿using System;\nusing System.Runtime.CompilerServices;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Order;\nusing BenchmarkDotNet.Toolchains.InProcess;\nusing BenchmarkDotNet.Toolchains.InProcess.Emit;\n\nnamespace BenchmarkDotNet.Samples\n{\n    [Config(typeof(Config))]\n    [Orderer(SummaryOrderPolicy.FastestToSlowest)]\n    [MemoryDiagnoser]\n    public class IntroInProcessWrongEnv\n    {\n        private class Config : ManualConfig\n        {\n            public Config()\n            {\n                var wrongPlatform = Environment.Is64BitProcess\n                    ? Platform.X64\n                    : Platform.X86;\n\n                AddJob(Job.MediumRun\n                    .WithLaunchCount(1)\n                    .WithPlatform(wrongPlatform)\n                    .WithToolchain(InProcessEmitToolchain.Default)\n                    .WithId(\"InProcess\"));\n\n                AddValidator(InProcessValidator.DontFailOnError);\n            }\n        }\n\n        [Benchmark(Description = \"new byte[10kB]\")]\n        public byte[] Allocate()\n        {\n            return new byte[10000];\n        }\n\n        [Benchmark(Description = \"stackalloc byte[10kB]\")]\n        public unsafe void AllocateWithStackalloc()\n        {\n            var array = stackalloc byte[10000];\n            Consume(array);\n        }\n\n        [MethodImpl(MethodImplOptions.NoInlining)]\n        private static unsafe void Consume(byte* input)\n        {\n        }\n    }\n}"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroInliningDiagnoser.cs",
    "content": "﻿using BenchmarkDotNet.Attributes;\nusing System.Runtime.CompilerServices;\n\nnamespace BenchmarkDotNet.Samples\n{\n    [Diagnostics.Windows.Configs.InliningDiagnoser(logFailuresOnly: false, allowedNamespaces: [\"BenchmarkDotNet.Samples\"])]\n    public class IntroInliningDiagnoser\n    {\n        [Benchmark]\n        public int IterationTest()\n        {\n            int j = 0;\n            for (int i = 0; i < short.MaxValue; ++i)\n            {\n                j = i + AddThree(i);\n            }\n\n            return j + ReturnFive() + AddThree(ReturnFive());\n        }\n\n        [Benchmark]\n        public int SplitJoin()\n            => string.Join(\",\", new string[1000]).Split(',').Length;\n\n        private int ReturnFive()\n        {\n            return 5;\n        }\n\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        private int AddThree(int a)\n        {\n            return a + 3;\n        }\n    }\n}\n"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroJitStatsDiagnoser.cs",
    "content": "﻿using System.Threading;\nusing BenchmarkDotNet.Attributes;\n\nnamespace BenchmarkDotNet.Samples\n{\n    [Diagnostics.Windows.Configs.JitStatsDiagnoser]\n    public class IntroJitStatsDiagnoser\n    {\n        [Benchmark]\n        public void Sleep() => Thread.Sleep(10);\n    }\n}"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroJobBaseline.cs",
    "content": "﻿using BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Jobs;\n\nnamespace BenchmarkDotNet.Samples\n{\n    [SimpleJob(runtimeMoniker: RuntimeMoniker.Net462, baseline: true)]\n    [SimpleJob(runtimeMoniker: RuntimeMoniker.Mono)]\n    [SimpleJob(runtimeMoniker: RuntimeMoniker.Net50)]\n    public class IntroJobBaseline\n    {\n        [Benchmark]\n        public int SplitJoin()\n            => string.Join(\",\", new string[1000]).Split(',').Length;\n    }\n}"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroJoin.cs",
    "content": "using System.Threading;\nusing BenchmarkDotNet.Attributes;\n\nnamespace BenchmarkDotNet.Samples\n{\n    // Run BenchmarkSwitcher with arguments: \"--join --category=IntroJoinA\"\n\n    [DryJob]\n    public class IntroJoin1\n    {\n        [Benchmark]\n        [BenchmarkCategory(\"IntroJoinA\")]\n        public void A() => Thread.Sleep(10);\n\n        [Benchmark]\n        [BenchmarkCategory(\"IntroJoinB\")]\n        public void B() => Thread.Sleep(10);\n    }\n\n    [DryJob]\n    public class IntroJoin2\n    {\n        [Benchmark]\n        [BenchmarkCategory(\"IntroJoinA\")]\n        public void A() => Thread.Sleep(10);\n\n        [Benchmark]\n        [BenchmarkCategory(\"IntroJoinB\")]\n        public void B() => Thread.Sleep(10);\n    }\n}"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroLargeAddressAware.cs",
    "content": "﻿using System;\nusing System.Runtime.InteropServices;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Jobs;\n\nnamespace BenchmarkDotNet.Samples\n{\n    [MemoryDiagnoser]\n    [Config(typeof(Config))]\n    public class IntroLargeAddressAware\n    {\n        private class Config : ManualConfig\n        {\n            public Config()\n            {\n                AddJob(Job.Default\n                    .WithRuntime(ClrRuntime.Net462)\n                    .WithPlatform(Platform.X86)\n                    .WithLargeAddressAware(value: RuntimeInformation.IsOSPlatform(OSPlatform.Windows))\n                    .WithId(\"Framework\"));\n            }\n        }\n\n        [Benchmark]\n        public void AllocateMoreThan2GB()\n        {\n            const int oneGB = 1024 * 1024 * 1024;\n            const int halfGB = oneGB / 2;\n            byte[] bytes1 = new byte[oneGB];\n            byte[] bytes2 = new byte[oneGB];\n            byte[] bytes3 = new byte[halfGB];\n            GC.KeepAlive(bytes1);\n            GC.KeepAlive(bytes2);\n            GC.KeepAlive(bytes3);\n        }\n    }\n}\n"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroMemoryRandomization.cs",
    "content": "﻿using BenchmarkDotNet.Attributes;\nusing System;\n\nnamespace BenchmarkDotNet.Samples\n{\n    public class IntroMemoryRandomization\n    {\n        [Params(512 * 4)]\n        public int Size;\n\n        private int[] array = default!;\n        private int[] destination = default!;\n\n        [GlobalSetup]\n        public void Setup()\n        {\n            array = new int[Size];\n            destination = new int[Size];\n        }\n\n        [Benchmark]\n        [MemoryRandomization(false)]\n        public void Array_RandomizationDisabled() => Array.Copy(array, destination, Size);\n\n        [Benchmark]\n        [MemoryRandomization(true)]\n        [MaxIterationCount(40)] // the benchmark becomes multimodal and need a lower limit of max iterations than the default\n        public void Array_RandomizationEnabled() => Array.Copy(array, destination, Size);\n    }\n}\n"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroMonitoring.cs",
    "content": "﻿using System;\nusing System.Threading;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Engines;\n\nnamespace BenchmarkDotNet.Samples\n{\n    [SimpleJob(RunStrategy.Monitoring, iterationCount: 10, id: \"MonitoringJob\")]\n    [MinColumn, Q1Column, Q3Column, MaxColumn]\n    public class IntroMonitoring\n    {\n        private Random random = new Random(42);\n\n        [Benchmark]\n        public void Foo()\n        {\n            Thread.Sleep(random.Next(10) * 10);\n        }\n    }\n}"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroMultimodal.cs",
    "content": "﻿using System;\nusing System.Threading;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Engines;\n\nnamespace BenchmarkDotNet.Samples\n{\n    [MValueColumn]\n    [SimpleJob(RunStrategy.Throughput, 1, 0, -1, 1, \"MyJob\")]\n    public class IntroMultimodal\n    {\n        private readonly Random rnd = new Random(42);\n\n        private void Multimodal(int n)\n            => Thread.Sleep((rnd.Next(n) + 1) * 100);\n\n        [Benchmark] public void Unimodal() => Multimodal(1);\n        [Benchmark] public void Bimodal() => Multimodal(2);\n        [Benchmark] public void Trimodal() => Multimodal(3);\n        [Benchmark] public void Quadrimodal() => Multimodal(4);\n    }\n}"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroNativeMemory.cs",
    "content": "﻿using System;\nusing System.Drawing;\nusing System.Runtime.InteropServices;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Diagnostics.Windows.Configs;\nusing BenchmarkDotNet.Filters;\n\nnamespace BenchmarkDotNet.Samples\n{\n    [ShortRunJob]\n    [NativeMemoryProfiler]\n    [MemoryDiagnoser]\n    public class IntroNativeMemory\n    {\n#pragma warning disable CA1416\n        [Benchmark, WindowsOnly]\n        public void BitmapWithLeaks()\n        {\n            var flag = new Bitmap(200, 100);\n            var graphics = Graphics.FromImage(flag);\n            var blackPen = new Pen(Color.Black, 3);\n            graphics.DrawLine(blackPen, 100, 100, 500, 100);\n        }\n\n        [Benchmark, WindowsOnly]\n        public void Bitmap()\n        {\n            using (var flag = new Bitmap(200, 100))\n            {\n                using (var graphics = Graphics.FromImage(flag))\n                {\n                    using (var blackPen = new Pen(Color.Black, 3))\n                    {\n                        graphics.DrawLine(blackPen, 100, 100, 500, 100);\n                    }\n                }\n            }\n        }\n#pragma warning restore CA1416\n\n        private const int Size = 20; // Greater value could cause System.OutOfMemoryException for test with memory leaks.\n        private int ArraySize = Size * Marshal.SizeOf<int>();\n\n        [Benchmark]\n        public unsafe void AllocHGlobal()\n        {\n            IntPtr unmanagedHandle = Marshal.AllocHGlobal(ArraySize);\n            Span<byte> unmanaged = new Span<byte>(unmanagedHandle.ToPointer(), ArraySize);\n            Marshal.FreeHGlobal(unmanagedHandle);\n        }\n\n        [Benchmark]\n        public unsafe void AllocHGlobalWithLeaks()\n        {\n            IntPtr unmanagedHandle = Marshal.AllocHGlobal(ArraySize);\n            Span<byte> unmanaged = new Span<byte>(unmanagedHandle.ToPointer(), ArraySize);\n        }\n\n        private class WindowsOnlyAttribute : FilterConfigBaseAttribute\n        {\n            public WindowsOnlyAttribute()\n                : base(new SimpleFilter(_ => RuntimeInformation.IsOSPlatform(OSPlatform.Windows)))\n            {\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroNuGet.cs",
    "content": "﻿using System;\nusing System.IO.Hashing;\nusing System.Linq;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Jobs;\n\nnamespace BenchmarkDotNet.Samples\n{\n    /// <summary>\n    /// Benchmarks between various versions of a NuGet package\n    /// </summary>\n    /// <remarks>\n    /// Only supported with CsProj toolchains.\n    /// </remarks>\n    [Config(typeof(Config))]\n    public class IntroNuGet\n    {\n        // Setup your csproj like this:\n        /*\n        <PropertyGroup>\n          <!-- Use 8.0.0 as default package version if not specified -->\n          <SihVersion Condition=\"'$(SihVersion)' == ''\">8.0.0</SciVersion>\n        </PropertyGroup>\n        <ItemGroup>\n          <PackageReference Include=\"System.IO.Hashing\" Version=\"$(SihVersion)\" />\n        </ItemGroup>\n        */\n        // All versions of the package must be source-compatible with your benchmark code.\n        private class Config : ManualConfig\n        {\n            public Config()\n            {\n                string[] targetVersions = [\n                    \"8.0.0\",\n                    \"9.0.0\",\n                    \"10.0.0\",\n                ];\n\n                foreach (var version in targetVersions)\n                {\n                    AddJob(Job.MediumRun\n                        .WithMsBuildArguments($\"/p:SihVersion={version}\")\n                        .WithId($\"v{version}\")\n                    );\n                }\n            }\n        }\n\n        private static readonly byte[] values;\n\n        static IntroNuGet()\n        {\n            var rand = new Random(Seed: 0);\n            values = new byte[10_000];\n            rand.NextBytes(values);\n        }\n\n        [Benchmark]\n        public void XxHash3Benchmark()\n        {\n            var results = XxHash3.Hash(values);\n        }\n    }\n}"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroOrderAttr.cs",
    "content": "﻿using System.Threading;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Order;\n\nnamespace BenchmarkDotNet.Samples\n{\n    [Orderer(SummaryOrderPolicy.FastestToSlowest, MethodOrderPolicy.Declared, jobOrderPolicy: JobOrderPolicy.Numeric)]\n    [DryJob]\n    public class IntroOrderAttr\n    {\n        [Params(1, 2, 3)]\n        public int X { get; set; }\n\n        [Benchmark]\n        public void Slow() => Thread.Sleep(X * 100);\n\n        [Benchmark]\n        public void Fast() => Thread.Sleep(X * 50);\n    }\n}"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroOrderManual.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Collections.Immutable;\nusing System.Linq;\nusing System.Threading;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Order;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Running;\n\nnamespace BenchmarkDotNet.Samples\n{\n    [Config(typeof(Config))]\n    [DryJob]\n    [RankColumn]\n    public class IntroOrderManual\n    {\n        private class Config : ManualConfig\n        {\n            public Config() => Orderer = new FastestToSlowestOrderer();\n\n            private class FastestToSlowestOrderer : IOrderer\n            {\n                public IEnumerable<BenchmarkCase> GetExecutionOrder(ImmutableArray<BenchmarkCase> benchmarksCase,\n                    IEnumerable<BenchmarkLogicalGroupRule>? order = null) =>\n                    from benchmark in benchmarksCase\n                    orderby benchmark.Parameters[\"X\"] descending,\n                        benchmark.Descriptor.WorkloadMethodDisplayInfo\n                    select benchmark;\n\n                public IEnumerable<BenchmarkCase> GetSummaryOrder(ImmutableArray<BenchmarkCase> benchmarksCase, Summary summary) =>\n                    from benchmark in benchmarksCase\n                    orderby summary[benchmark]?.ResultStatistics?.Mean\n                    select benchmark;\n\n                public string? GetHighlightGroupKey(BenchmarkCase benchmarkCase) => null;\n\n                public string GetLogicalGroupKey(ImmutableArray<BenchmarkCase> allBenchmarksCases, BenchmarkCase benchmarkCase) =>\n                    benchmarkCase.Job.DisplayInfo + \"_\" + benchmarkCase.Parameters.DisplayInfo;\n\n                public IEnumerable<IGrouping<string, BenchmarkCase>> GetLogicalGroupOrder(IEnumerable<IGrouping<string, BenchmarkCase>> logicalGroups,\n                    IEnumerable<BenchmarkLogicalGroupRule>? order = null) =>\n                    logicalGroups.OrderBy(it => it.Key);\n\n                public bool SeparateLogicalGroups => true;\n            }\n        }\n\n        [Params(1, 2, 3)]\n        public int X { get; set; }\n\n        [Benchmark]\n        public void Fast() => Thread.Sleep(X * 50);\n\n        [Benchmark]\n        public void Slow() => Thread.Sleep(X * 100);\n    }\n}"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroOutliers.cs",
    "content": "﻿using System.Threading;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Jobs;\nusing Perfolizer.Mathematics.OutlierDetection;\n\nnamespace BenchmarkDotNet.Samples\n{\n    [Config(typeof(Config))]\n    public class IntroOutliers\n    {\n        private class Config : ManualConfig\n        {\n            public Config()\n            {\n                var jobBase = Job.Default.WithWarmupCount(0).WithIterationCount(10).WithInvocationCount(1).WithUnrollFactor(1);\n                AddJob(jobBase.WithOutlierMode(OutlierMode.DontRemove).WithId(\"DontRemoveOutliers\"));\n                AddJob(jobBase.WithOutlierMode(OutlierMode.RemoveUpper).WithId(\"RemoveUpperOutliers\"));\n            }\n        }\n\n        private int counter;\n\n        [Benchmark]\n        public void Foo()\n        {\n            counter++;\n            int noise = counter % 10 == 0 ? 500 : 0;\n            Thread.Sleep(100 + noise);\n        }\n    }\n}"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroParams.cs",
    "content": "﻿using System.Threading;\nusing BenchmarkDotNet.Attributes;\n\nnamespace BenchmarkDotNet.Samples\n{\n    public class IntroParams\n    {\n        [Params(100, 200)]\n        public int A { get; set; }\n\n        [Params(10, 20)]\n        public int B { get; set; }\n\n        [Benchmark]\n        public void Benchmark() => Thread.Sleep(A + B + 5);\n    }\n}"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroParamsAllValues.cs",
    "content": "﻿using BenchmarkDotNet.Attributes;\nusing System.Threading;\n\nnamespace BenchmarkDotNet.Samples\n{\n    [DryJob]\n    public class IntroParamsAllValues\n    {\n        public enum CustomEnum\n        {\n            One = 1,\n            Two,\n            Three\n        }\n\n        [ParamsAllValues]\n        public CustomEnum E { get; set; }\n\n        [ParamsAllValues]\n        public bool? B { get; set; }\n\n        [Benchmark]\n        public void Benchmark()\n        {\n            Thread.Sleep(\n                (int)E * 100 +\n                (B == true ? 20 : B == false ? 10 : 0));\n        }\n    }\n}"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroParamsPriority.cs",
    "content": "﻿using System.Threading;\nusing BenchmarkDotNet.Attributes;\n\nnamespace BenchmarkDotNet.Samples\n{\n    public class IntroParamsPriority\n    {\n        [Params(100)]\n        public int A { get; set; }\n\n        [Params(10, Priority = -100)]\n        public int B { get; set; }\n\n        [Benchmark]\n        public void Benchmark() => Thread.Sleep(A + B + 5);\n    }\n}"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroParamsSource.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Threading;\nusing BenchmarkDotNet.Attributes;\n\nnamespace BenchmarkDotNet.Samples\n{\n    public class IntroParamsSource\n    {\n        // property with public setter\n        [ParamsSource(nameof(ValuesForA))]\n        public int A { get; set; }\n\n        // public field\n        [ParamsSource(nameof(ValuesForB))]\n        public int B;\n\n        // public property\n        public IEnumerable<int> ValuesForA => [100, 200];\n\n        // public static method\n        public static IEnumerable<int> ValuesForB() => [10, 20];\n\n        // public field getting its params from a method in another type\n        [ParamsSource(typeof(ParamsValues), nameof(ParamsValues.ValuesForC))]\n        public int C;\n\n        [Benchmark]\n        public void Benchmark() => Thread.Sleep(A + B + C + 5);\n    }\n\n    public static class ParamsValues\n    {\n        public static IEnumerable<int> ValuesForC() => [1000, 2000];\n    }\n}"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroPercentiles.cs",
    "content": "﻿using System;\nusing System.Threading;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Columns;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Engines;\n\nnamespace BenchmarkDotNet.Samples\n{\n    // Using percentiles for adequate timings representation\n    [Config(typeof(Config))]\n    [SimpleJob(RunStrategy.ColdStart, launchCount: 4,\n        warmupCount: 3, iterationCount: 20, id: \"MyJob\")]\n    public class IntroPercentiles\n    {\n        // To share between runs.\n        // DO NOT do this in production code. The System.Random IS NOT thread safe.\n        private static readonly Random Rnd = new Random();\n\n        private class Config : ManualConfig\n        {\n            public Config()\n            {\n                AddColumn(\n                    StatisticColumn.P0,\n                    StatisticColumn.P25,\n                    StatisticColumn.P50,\n                    StatisticColumn.P67,\n                    StatisticColumn.P80,\n                    StatisticColumn.P85,\n                    StatisticColumn.P90,\n                    StatisticColumn.P95,\n                    StatisticColumn.P100);\n            }\n        }\n\n        [Benchmark(Baseline = true)]\n        public void ConstantDelays() => Thread.Sleep(20);\n\n        [Benchmark]\n        public void RandomDelays() => Thread.Sleep(10 + (int) (20 * Rnd.NextDouble()));\n\n        [Benchmark]\n        public void RareDelays()\n        {\n            int rndTime = 10;\n            // Bigger delays for 15% of the runs\n            if (Rnd.NextDouble() > 0.85)\n            {\n                rndTime += 30;\n            }\n\n            Thread.Sleep(rndTime);\n        }\n    }\n}"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroPerfCollectProfiler.cs",
    "content": "using System.IO;\nusing BenchmarkDotNet.Attributes;\n\nnamespace BenchmarkDotNet.Samples\n{\n    [PerfCollectProfiler(performExtraBenchmarksRun: false)]\n    public class IntroPerfCollectProfiler\n    {\n        private readonly string path = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());\n        private readonly string content = new string('a', 100_000);\n\n        [Benchmark]\n        public void WriteAllText() => File.WriteAllText(path, content);\n\n        [GlobalCleanup]\n        public void Delete() => File.Delete(path);\n    }\n}"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroPowerPlan.cs",
    "content": "﻿using BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Jobs;\nusing System;\n\nnamespace BenchmarkDotNet.Samples\n{\n    [Config(typeof(Config))]\n    public class IntroPowerPlan\n    {\n        private class Config : ManualConfig\n        {\n            public Config()\n            {\n                AddJob(Job.MediumRun.WithPowerPlan(new Guid(\"e9a42b02-d5df-448d-aa00-03f14749eb61\")));\n                AddJob(Job.MediumRun.WithPowerPlan(PowerPlan.UltimatePerformance));\n                AddJob(Job.MediumRun.WithPowerPlan(PowerPlan.UserPowerPlan));\n                AddJob(Job.MediumRun.WithPowerPlan(PowerPlan.HighPerformance));\n                AddJob(Job.MediumRun.WithPowerPlan(PowerPlan.Balanced));\n                AddJob(Job.MediumRun.WithPowerPlan(PowerPlan.PowerSaver));\n            }\n        }\n\n        [Benchmark]\n        public int IterationTest()\n        {\n            int j = 0;\n            for (int i = 0; i < short.MaxValue; ++i)\n            {\n                j = i;\n            }\n\n            return j;\n        }\n\n        [Benchmark]\n        public int SplitJoin()\n            => string.Join(\",\", new string[1000]).Split(',').Length;\n    }\n}\n"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroRankColumn.cs",
    "content": "﻿using System.Threading;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Mathematics;\nusing BenchmarkDotNet.Order;\n\nnamespace BenchmarkDotNet.Samples\n{\n    [ShortRunJob]\n    [Orderer(SummaryOrderPolicy.FastestToSlowest)]\n    [RankColumn(NumeralSystem.Arabic)]\n    [RankColumn(NumeralSystem.Roman)]\n    [RankColumn(NumeralSystem.Stars)]\n    public class IntroRankColumn\n    {\n        [Params(1, 2)]\n        public int Factor;\n\n        [Benchmark]\n        public void Foo() => Thread.Sleep(Factor * 100);\n\n        [Benchmark]\n        public void Bar() => Thread.Sleep(Factor * 200);\n    }\n}"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroRatioSD.cs",
    "content": "using System.Threading;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Engines;\nusing Perfolizer.Mathematics.OutlierDetection;\n\nnamespace BenchmarkDotNet.Samples\n{\n    // Don't remove outliers\n    [Outliers(OutlierMode.DontRemove)]\n    // Skip jitting, pilot, warmup; measure 10 iterations\n    [SimpleJob(RunStrategy.Monitoring, iterationCount: 10, invocationCount: 1)]\n    public class IntroRatioSD\n    {\n        private int counter;\n\n        [GlobalSetup]\n        public void Setup() => counter = 0;\n\n        [Benchmark(Baseline = true)]\n        public void Base()\n        {\n            Thread.Sleep(100);\n            if (++counter % 7 == 0)\n                Thread.Sleep(5000); // Emulate outlier\n        }\n\n        [Benchmark]\n        public void Slow() => Thread.Sleep(200);\n\n        [Benchmark]\n        public void Fast() => Thread.Sleep(50);\n    }\n}"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroRatioStyle.cs",
    "content": "using System.Threading;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Columns;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Reports;\n\nnamespace BenchmarkDotNet.Samples\n{\n    [ShortRunJob, Config(typeof(Config))]\n    public class IntroRatioStyle\n    {\n        [Benchmark(Baseline = true)]\n        public void Baseline() => Thread.Sleep(1000);\n\n        [Benchmark]\n        public void Bar() => Thread.Sleep(150);\n\n        [Benchmark]\n        public void Foo() => Thread.Sleep(1150);\n\n        private class Config : ManualConfig\n        {\n            public Config()\n            {\n                SummaryStyle = SummaryStyle.Default.WithRatioStyle(RatioStyle.Trend);\n            }\n        }\n    }\n}"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroSetupCleanupGlobal.cs",
    "content": "﻿using BenchmarkDotNet.Attributes;\n\nnamespace BenchmarkDotNet.Samples\n{\n    public class IntroSetupCleanupGlobal\n    {\n        [Params(10, 100, 1000)]\n        public int N;\n\n        private int[] data = default!;\n\n        [GlobalSetup]\n        public void GlobalSetup()\n        {\n            data = new int[N]; // executed once per each N value\n        }\n\n        [Benchmark]\n        public int Logic()\n        {\n            int res = 0;\n            for (int i = 0; i < N; i++)\n                res += data[i];\n            return res;\n        }\n\n        [GlobalCleanup]\n        public void GlobalCleanup()\n        {\n            // Disposing logic\n        }\n    }\n}"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroSetupCleanupIteration.cs",
    "content": "﻿using System;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Engines;\n\nnamespace BenchmarkDotNet.Samples\n{\n    [SimpleJob(RunStrategy.Monitoring, launchCount: 1,\n        warmupCount: 2, iterationCount: 3)]\n    public class IntroSetupCleanupIteration\n    {\n        private int setupCounter;\n        private int cleanupCounter;\n\n        [IterationSetup]\n        public void IterationSetup()\n            => Console.WriteLine($\"// IterationSetup ({++setupCounter})\");\n\n        [IterationCleanup]\n        public void IterationCleanup()\n            => Console.WriteLine($\"// IterationCleanup ({++cleanupCounter})\");\n\n        [GlobalSetup]\n        public void GlobalSetup()\n            => Console.WriteLine(\"// \" + \"GlobalSetup\");\n\n        [GlobalCleanup]\n        public void GlobalCleanup()\n            => Console.WriteLine(\"// \" + \"GlobalCleanup\");\n\n        [Benchmark]\n        public void Benchmark()\n            => Console.WriteLine(\"// \" + \"Benchmark\");\n    }\n}"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroSetupCleanupTarget.cs",
    "content": "﻿using System;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Engines;\n\nnamespace BenchmarkDotNet.Samples\n{\n    [SimpleJob(RunStrategy.Monitoring, launchCount: 0,\n        warmupCount: 0, iterationCount: 1)]\n    public class IntroSetupCleanupTarget\n    {\n        [GlobalSetup(Target = nameof(BenchmarkA))]\n        public void GlobalSetupA()\n            => Console.WriteLine(\"// \" + \"GlobalSetup A\");\n\n        [Benchmark]\n        public void BenchmarkA()\n            => Console.WriteLine(\"// \" + \"Benchmark A\");\n\n        [GlobalSetup(Targets = new[] { nameof(BenchmarkB), nameof(BenchmarkC) })]\n        public void GlobalSetupB()\n            => Console.WriteLine(\"// \" + \"GlobalSetup B\");\n\n        [Benchmark]\n        public void BenchmarkB()\n            => Console.WriteLine(\"// \" + \"Benchmark B\");\n\n        [Benchmark]\n        public void BenchmarkC()\n            => Console.WriteLine(\"// \" + \"Benchmark C\");\n\n        [Benchmark]\n        public void BenchmarkD()\n            => Console.WriteLine(\"// \" + \"Benchmark D\");\n    }\n}"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroSmokeEmptyBasic.cs",
    "content": "﻿using BenchmarkDotNet.Attributes;\n\nnamespace BenchmarkDotNet.Samples;\n\n[DisassemblyDiagnoser]\npublic class IntroSmokeEmptyBasic\n{\n    [Benchmark] public void Void1() {}\n    [Benchmark] public void Void2() {}\n    [Benchmark] public void Void3() {}\n    [Benchmark] public void Void4() {}\n\n    [Benchmark] public byte Byte1() => 0;\n    [Benchmark] public byte Byte2() => 0;\n    [Benchmark] public byte Byte3() => 0;\n    [Benchmark] public byte Byte4() => 0;\n\n    [Benchmark] public sbyte Sbyte1() => 0;\n    [Benchmark] public sbyte Sbyte2() => 0;\n    [Benchmark] public sbyte Sbyte3() => 0;\n    [Benchmark] public sbyte Sbyte4() => 0;\n\n    [Benchmark] public short Short1() => 0;\n    [Benchmark] public short Short2() => 0;\n    [Benchmark] public short Short3() => 0;\n    [Benchmark] public short Short4() => 0;\n\n    [Benchmark] public ushort Ushort1() => 0;\n    [Benchmark] public ushort Ushort2() => 0;\n    [Benchmark] public ushort Ushort3() => 0;\n    [Benchmark] public ushort Ushort4() => 0;\n\n    [Benchmark] public int Int1() => 0;\n    [Benchmark] public int Int2() => 0;\n    [Benchmark] public int Int3() => 0;\n    [Benchmark] public int Int4() => 0;\n\n    [Benchmark] public uint Uint1() => 0u;\n    [Benchmark] public uint Uint2() => 0u;\n    [Benchmark] public uint Uint3() => 0u;\n    [Benchmark] public uint Uint4() => 0u;\n\n    [Benchmark] public bool Bool1() => false;\n    [Benchmark] public bool Bool2() => false;\n    [Benchmark] public bool Bool3() => false;\n    [Benchmark] public bool Bool4() => false;\n\n    [Benchmark] public char Char1() => 'a';\n    [Benchmark] public char Char2() => 'a';\n    [Benchmark] public char Char3() => 'a';\n    [Benchmark] public char Char4() => 'a';\n\n    [Benchmark] public float Float1() => 0f;\n    [Benchmark] public float Float2() => 0f;\n    [Benchmark] public float Float3() => 0f;\n    [Benchmark] public float Float4() => 0f;\n\n    [Benchmark] public double Double1() => 0d;\n    [Benchmark] public double Double2() => 0d;\n    [Benchmark] public double Double3() => 0d;\n    [Benchmark] public double Double4() => 0d;\n\n    [Benchmark] public long Long1() => 0L;\n    [Benchmark] public long Long2() => 0L;\n    [Benchmark] public long Long3() => 0L;\n    [Benchmark] public long Long4() => 0L;\n\n    [Benchmark] public ulong Ulong1() => 0uL;\n    [Benchmark] public ulong Ulong2() => 0uL;\n    [Benchmark] public ulong Ulong3() => 0uL;\n    [Benchmark] public ulong Ulong4() => 0uL;\n\n    [Benchmark] public string String1() => \"\";\n    [Benchmark] public string String2() => \"\";\n    [Benchmark] public string String3() => \"\";\n    [Benchmark] public string String4() => \"\";\n\n    [Benchmark] public object? Object1() => null;\n    [Benchmark] public object? Object2() => null;\n    [Benchmark] public object? Object3() => null;\n    [Benchmark] public object? Object4() => null;\n}"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroSmokeIncrements.cs",
    "content": "using BenchmarkDotNet.Attributes;\n\nnamespace BenchmarkDotNet.Samples;\n\npublic class IntroSmokeIncrements\n{\n    public int Field;\n\n    [Benchmark]\n    public void Increment01()\n    {\n        Field++;\n    }\n\n    [Benchmark]\n    public void Increment02()\n    {\n        Field++;\n        Field++;\n    }\n\n    [Benchmark]\n    public void Increment03()\n    {\n        Field++;\n        Field++;\n        Field++;\n    }\n\n    [Benchmark]\n    public void Increment04()\n    {\n        Field++;\n        Field++;\n        Field++;\n        Field++;\n    }\n\n    [Benchmark]\n    public void Increment05()\n    {\n        Field++;\n        Field++;\n        Field++;\n        Field++;\n        Field++;\n    }\n\n    [Benchmark]\n    public void Increment06()\n    {\n        Field++;\n        Field++;\n        Field++;\n        Field++;\n        Field++;\n        Field++;\n    }\n\n    [Benchmark]\n    public void Increment07()\n    {\n        Field++;\n        Field++;\n        Field++;\n        Field++;\n        Field++;\n        Field++;\n        Field++;\n    }\n\n    [Benchmark]\n    public void Increment08()\n    {\n        Field++;\n        Field++;\n        Field++;\n        Field++;\n        Field++;\n        Field++;\n        Field++;\n        Field++;\n    }\n\n    [Benchmark]\n    public void Increment09()\n    {\n        Field++;\n        Field++;\n        Field++;\n        Field++;\n        Field++;\n        Field++;\n        Field++;\n        Field++;\n        Field++;\n    }\n\n    [Benchmark]\n    public void Increment10()\n    {\n        Field++;\n        Field++;\n        Field++;\n        Field++;\n        Field++;\n        Field++;\n        Field++;\n        Field++;\n        Field++;\n        Field++;\n    }\n\n    [Benchmark]\n    public void Increment20()\n    {\n        Field++;\n        Field++;\n        Field++;\n        Field++;\n        Field++;\n        Field++;\n        Field++;\n        Field++;\n        Field++;\n        Field++;\n        Field++;\n        Field++;\n        Field++;\n        Field++;\n        Field++;\n        Field++;\n        Field++;\n        Field++;\n        Field++;\n        Field++;\n    }\n}"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroSmokeStringBuilder.cs",
    "content": "﻿using BenchmarkDotNet.Attributes;\nusing System.Text;\n\nnamespace BenchmarkDotNet.Samples\n{\n    [MemoryDiagnoser(false)]\n    public class IntroSmokeStringBuilder\n    {\n        [Benchmark]\n        [Arguments(1)]\n        [Arguments(1_000)]\n        public StringBuilder Append_Strings(int repeat)\n        {\n            StringBuilder builder = new StringBuilder();\n\n            // strings are not sorted by length to mimic real input\n            for (int i = 0; i < repeat; i++)\n            {\n                builder.Append(\"12345\");\n                builder.Append(\"1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMN\");\n                builder.Append(\"1234567890abcdefghijklmnopqrstuvwxy\");\n                builder.Append(\"1234567890\");\n                builder.Append(\"1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHI\");\n                builder.Append(\"1234567890abcde\");\n                builder.Append(\"1234567890abcdefghijklmnopqrstuvwxyzABCD\");\n                builder.Append(\"1234567890abcdefghijklmnopqrst\");\n                builder.Append(\"1234567890abcdefghij\");\n                builder.Append(\"1234567890abcdefghijklmno\");\n            }\n\n            return builder;\n        }\n    }\n}"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroSmokeValueTypes.cs",
    "content": "﻿using System;\nusing System.Threading.Tasks;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Environments;\n\nnamespace BenchmarkDotNet.Samples;\n\n[MemoryDiagnoser, DisassemblyDiagnoser]\npublic class IntroSmokeValueTypes\n{\n    [Benchmark] public Jit ReturnEnum() => Jit.RyuJit;\n\n    [Benchmark] public DateTime ReturnDateTime() => new DateTime();\n\n    [Benchmark] public DateTime? ReturnNullableDateTime() => new DateTime();\n    [Benchmark] public int? ReturnNullableInt() => 0;\n\n    public struct StructWithReferencesOnly { public object _ref; }\n    [Benchmark] public StructWithReferencesOnly ReturnStructWithReferencesOnly() => new StructWithReferencesOnly();\n\n    public struct EmptyStruct { }\n    [Benchmark] public EmptyStruct ReturnEmptyStruct() => new EmptyStruct();\n\n    [Benchmark] public ValueTuple<int> ReturnGenericStructOfValueType() => new ValueTuple<int>(0);\n    [Benchmark] public ValueTuple<object?> ReturnGenericStructOfReferenceType() => new ValueTuple<object?>(null);\n\n    [Benchmark] public ValueTask<int> ReturnValueTaskOfValueType() => new ValueTask<int>(0);\n    [Benchmark] public ValueTask<object?> ReturnValueTaskOfReferenceType() => new ValueTask<object?>(result: null);\n\n    [Benchmark] public byte ReturnByte() => 0;\n    public struct Byte1 { public byte _1; }\n    [Benchmark] public Byte1 ReturnByte1() => new Byte1();\n    public struct Byte2 { public byte _1, _2; }\n    [Benchmark] public Byte2 ReturnByte2() => new Byte2();\n    public struct Byte3 { public byte _1, _2, _3; }\n    [Benchmark] public Byte3 ReturnByte3() => new Byte3();\n    public struct Byte4 { public byte _1, _2, _3, _4; }\n    [Benchmark] public Byte4 ReturnByte4() => new Byte4();\n\n    [Benchmark] public short ReturnShort() => 0;\n    public struct Short1 { public short _1; }\n    [Benchmark] public Short1 ReturnShort1() => new Short1();\n    public struct Short2 { public short _1, _2; }\n    [Benchmark] public Short2 ReturnShort2() => new Short2();\n    public struct Short3 { public short _1, _2, _3; }\n    [Benchmark] public Short3 ReturnShort3() => new Short3();\n    public struct Short4 { public short _1, _2, _3, _4; }\n    [Benchmark] public Short4 ReturnShort4() => new Short4();\n\n    [Benchmark] public int ReturnInt() => 0;\n    public struct Int1 { public int _1; }\n    [Benchmark] public Int1 ReturnInt1() => new Int1();\n    public struct Int2 { public int _1, _2; }\n    [Benchmark] public Int2 ReturnInt2() => new Int2();\n    public struct Int3 { public int _1, _2, _3; }\n    [Benchmark] public Int3 ReturnInt3() => new Int3();\n    public struct Int4 { public int _1, _2, _3, _4; }\n    [Benchmark] public Int4 ReturnInt4() => new Int4();\n\n    [Benchmark] public long ReturnLong() => 0;\n    public struct Long1 { public long _1; }\n    [Benchmark] public Long1 ReturnLong1() => new Long1();\n    public struct Long2 { public long _1, _2; }\n    [Benchmark] public Long2 ReturnLong2() => new Long2();\n    public struct Long3 { public long _1, _2, _3; }\n    [Benchmark] public Long3 ReturnLong3() => new Long3();\n    public struct Long4 { public long _1, _2, _3, _4; }\n    [Benchmark] public Long4 ReturnLong4() => new Long4();\n}\n// ReSharper restore InconsistentNaming"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroStaThread.cs",
    "content": "﻿using System.Threading;\nusing BenchmarkDotNet.Attributes;\n\nnamespace BenchmarkDotNet.Samples\n{\n    public class IntroStaThread\n    {\n        [Benchmark, System.STAThread]\n        public void CheckForSTA()\n        {\n            if (Thread.CurrentThread.GetApartmentState() != ApartmentState.STA)\n            {\n                throw new ThreadStateException(\n                    \"The current threads apartment state is not STA\");\n            }\n        }\n    }\n}"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroStatisticalTesting.cs",
    "content": "using System.Threading;\nusing BenchmarkDotNet.Attributes;\n\nnamespace BenchmarkDotNet.Samples\n{\n    [StatisticalTestColumn(\"500us\")]\n    [StatisticalTestColumn(\"3%\")]\n    [SimpleJob(warmupCount: 0, iterationCount: 5)]\n    public class IntroStatisticalTesting\n    {\n        [Benchmark] public void Sleep50() => Thread.Sleep(50);\n        [Benchmark] public void Sleep97() => Thread.Sleep(97);\n        [Benchmark] public void Sleep99() => Thread.Sleep(99);\n        [Benchmark(Baseline = true)] public void Sleep100() => Thread.Sleep(100);\n        [Benchmark] public void Sleep101() => Thread.Sleep(101);\n        [Benchmark] public void Sleep103() => Thread.Sleep(103);\n        [Benchmark] public void Sleep150() => Thread.Sleep(150);\n    }\n}"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroStatisticsColumns.cs",
    "content": "﻿using System;\nusing System.Security.Cryptography;\nusing BenchmarkDotNet.Attributes;\n\nnamespace BenchmarkDotNet.Samples\n{\n    [MediumRunJob, SkewnessColumn, KurtosisColumn]\n    public class IntroStatisticsColumns\n    {\n        private const int N = 10000;\n        private readonly byte[] data;\n\n        private readonly MD5 md5 = MD5.Create();\n        private readonly SHA256 sha256 = SHA256.Create();\n\n        public IntroStatisticsColumns()\n        {\n            data = new byte[N];\n            new Random(42).NextBytes(data);\n        }\n\n        [Benchmark(Baseline = true)]\n        public byte[] Md5A() => md5.ComputeHash(data);\n\n        [Benchmark]\n        public byte[] Md5B() => md5.ComputeHash(data);\n\n        [Benchmark]\n        public byte[] Sha256() => sha256.ComputeHash(data);\n    }\n}"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroStopOnFirstError.cs",
    "content": "﻿using System;\nusing BenchmarkDotNet.Attributes;\n\nnamespace BenchmarkDotNet.Samples\n{\n    [StopOnFirstError]\n    public class IntroStopOnFirstError\n    {\n        [Benchmark(Baseline = true)]\n        public int FirstMethod() => throw new Exception(\"Example exception.\");\n\n        [Benchmark]\n        public int SecondMethod() => 1;\n    }\n}"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroSummaryStyle.cs",
    "content": "using System.Globalization;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Reports;\nusing Perfolizer.Horology;\nusing Perfolizer.Metrology;\n\nnamespace BenchmarkDotNet.Samples\n{\n    [Config(typeof(Config))]\n    public class IntroSummaryStyle\n    {\n        private class Config : ManualConfig\n        {\n            public Config()\n            {\n                // Configure the summary style here\n                var summaryStyle = new SummaryStyle\n                (\n                    cultureInfo: CultureInfo.InvariantCulture,\n                    printUnitsInHeader: true,\n                    printUnitsInContent: false,\n                    sizeUnit: SizeUnit.KB,\n                    timeUnit: TimeUnit.Nanosecond,\n                    maxParameterColumnWidth: 20\n\n                );\n\n                WithSummaryStyle(summaryStyle);\n            }\n        }\n\n        [Params(10, 100)]\n        public int N;\n\n        [Benchmark]\n        public void Sleep() => System.Threading.Thread.Sleep(N);\n    }\n}"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroTagColumn.cs",
    "content": "﻿using System.Threading;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Columns;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Jobs;\n\nnamespace BenchmarkDotNet.Samples\n{\n    // You can add custom tags per each method using Columns\n    [Config(typeof(Config))]\n    public class IntroTagColumn\n    {\n        private class Config : ManualConfig\n        {\n            public Config()\n            {\n                AddJob(Job.Dry);\n                AddColumn(new TagColumn(\"Kind\", name => name.Substring(0, 3)));\n                AddColumn(new TagColumn(\"Number\", name => name.Substring(3)));\n            }\n        }\n\n        [Benchmark]\n        public void Foo1() => Thread.Sleep(10);\n\n        [Benchmark]\n        public void Foo12() => Thread.Sleep(10);\n\n        [Benchmark]\n        public void Bar3() => Thread.Sleep(10);\n\n        [Benchmark]\n        public void Bar34() => Thread.Sleep(10);\n    }\n}\n"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroTailcall.cs",
    "content": "﻿using BenchmarkDotNet.Attributes;\n\nnamespace BenchmarkDotNet.Samples\n{\n    [Diagnostics.Windows.Configs.TailCallDiagnoser]\n    [LegacyJitX86Job, LegacyJitX64Job, RyuJitX64Job]\n    public class IntroTailcall\n    {\n        [Benchmark]\n        public long Calc()\n            => FactorialWithoutTailing(7) - FactorialWithTailing(7);\n\n        private static long FactorialWithoutTailing(int depth)\n            => depth == 0 ? 1 : depth * FactorialWithoutTailing(depth - 1);\n\n        private static long FactorialWithTailing(int pos, int depth)\n            => pos == 0 ? depth : FactorialWithTailing(pos - 1, depth * pos);\n\n        private static long FactorialWithTailing(int depth)\n            => FactorialWithTailing(depth - 1, depth);\n    }\n}\n"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroThreadingDiagnoser.cs",
    "content": "﻿using BenchmarkDotNet.Attributes;\nusing System.Threading;\n\nnamespace BenchmarkDotNet.Samples\n{\n    [ThreadingDiagnoser] // ENABLE the diagnoser\n    public class IntroThreadingDiagnoser\n    {\n        [Benchmark]\n        public void CompleteOneWorkItem()\n        {\n            ManualResetEvent done = new ManualResetEvent(initialState: false);\n\n            ThreadPool.QueueUserWorkItem(m => (m as ManualResetEvent)?.Set(), done);\n\n            done.WaitOne();\n        }\n    }\n}\n"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroUnicode.cs",
    "content": "﻿using System.Diagnostics;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Running;\n\nnamespace BenchmarkDotNet.Samples\n{\n    // *** Attribute Style ***\n    [UnicodeConsoleLogger]\n    public class IntroUnicode\n    {\n        [Benchmark]\n        public long Foo()\n        {\n            long waitUntil = Stopwatch.GetTimestamp() + 1000;\n            while (Stopwatch.GetTimestamp() < waitUntil) { }\n            return waitUntil;\n        }\n    }\n\n    // *** Object Style ***\n    [Config(typeof(Config))]\n    public class IntroUnicodeObjectStyle\n    {\n        private class Config : ManualConfig\n        {\n            public Config() => AddLogger(ConsoleLogger.Unicode);\n        }\n\n        [Benchmark]\n        public long Foo()\n        {\n            long waitUntil = Stopwatch.GetTimestamp() + 1000;\n            while (Stopwatch.GetTimestamp() < waitUntil) { }\n            return waitUntil;\n        }\n    }\n\n    // *** Fluent Config ***\n    public class IntroUnicodeFluentConfig\n    {\n        public static void Run()\n        {\n            BenchmarkRunner.Run<IntroUnicodeFluentConfig>(\n                DefaultConfig.Instance\n                    .AddLogger(ConsoleLogger.Unicode));\n        }\n\n        [Benchmark]\n        public long Foo()\n        {\n            long waitUntil = Stopwatch.GetTimestamp() + 1000;\n            while (Stopwatch.GetTimestamp() < waitUntil) { }\n            return waitUntil;\n        }\n    }\n}\n"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroVisualStudioDiagnoser.cs",
    "content": "using System;\nusing BenchmarkDotNet.Attributes;\nusing Microsoft.VSDiagnostics;\n\nnamespace BenchmarkDotNet.Samples\n{\n    // Enables profiling with the CPU Usage tool\n    // See: https://learn.microsoft.com/visualstudio/profiling/profiling-with-benchmark-dotnet\n    [CPUUsageDiagnoser]\n    public class IntroVisualStudioProfiler\n    {\n        private readonly Random rand = new Random(42);\n\n        [Benchmark]\n        public void BurnCPU()\n        {\n            for (int i = 0; i < 100000; ++i)\n            {\n                rand.Next(1, 100);\n            }\n        }\n    }\n}"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroWakeLock.cs",
    "content": "﻿using BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Configs;\nusing System;\nusing System.Threading;\n\n// *** Attribute Style applied to Assembly ***\n[assembly: WakeLock(WakeLockType.System)]\n\nnamespace BenchmarkDotNet.Samples;\n\n// *** Attribute Style ***\n[WakeLock(WakeLockType.Display)]\npublic class IntroWakeLock\n{\n    [Benchmark]\n    public void LongRunning() => Thread.Sleep(TimeSpan.FromSeconds(10));\n}\n\n// *** Object Style ***\n[Config(typeof(Config))]\npublic class IntroWakeLockObjectStyle\n{\n    private class Config : ManualConfig\n    {\n        public Config() => WakeLock = WakeLockType.System;\n    }\n\n    [Benchmark]\n    public void LongRunning() => Thread.Sleep(TimeSpan.FromSeconds(10));\n}\n"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/IntroWasm.cs",
    "content": "using BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Toolchains.DotNetCli;\nusing BenchmarkDotNet.Toolchains.MonoWasm;\n\nnamespace BenchmarkDotNet.Samples\n{\n    // *** Command Line Arguments ***\n    public class IntroWasmCmdConfig\n    {\n        // Example:\n        // --runtimes wasmnet8.0\n        // --cli /path/to/dotnet (optional)\n        // --wasmEngine v8 (optional)\n        // --wasmArgs \"--expose_wasm\" (optional)\n        // --wasmDataDir /path/to/data (optional)\n        public static void Run(string[] args) => BenchmarkSwitcher.FromAssembly(typeof(IntroWasmCmdConfig).Assembly).Run(args);\n\n        [Benchmark]\n        public void Foo()\n        {\n            // Benchmark body\n        }\n    }\n\n    // *** Fluent Config ***\n    public class IntroWasmFluentConfig\n    {\n        public static void Run()\n        {\n            // Optional: set this to use a custom `dotnet` (for example, a local dotnet/runtime build).\n            const string cliPath = \"\";\n\n            WasmRuntime runtime = new WasmRuntime(msBuildMoniker: \"net8.0\", RuntimeMoniker.WasmNet80, \"Wasm .net8.0\", false, \"v8\");\n            NetCoreAppSettings netCoreAppSettings = new NetCoreAppSettings(\n                targetFrameworkMoniker: \"net8.0\", runtimeFrameworkVersion: \"\", name: \"Wasm\",\n                customDotNetCliPath: cliPath);\n            var toolChain = WasmToolchain.From(netCoreAppSettings);\n\n            BenchmarkRunner.Run<IntroWasmFluentConfig>(DefaultConfig.Instance\n                .AddJob(Job.ShortRun.WithRuntime(runtime).WithToolchain(toolChain)));\n        }\n\n        [Benchmark]\n        public void Foo()\n        {\n            // Benchmark body\n        }\n    }\n}\n"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/Program.cs",
    "content": "﻿using BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Exporters;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Running;\nusing System;\nusing System.Linq;\n\nnamespace BenchmarkDotNet.Samples;\n\npublic class Program\n{\n    public static int Main(string[] args)\n    {\n#if DEBUG\n        ConsoleLogger.Default.WriteLineWarning(\"Benchmark is executed with DEBUG configuration.\");\n        ConsoleLogger.Default.WriteLine();\n#endif\n\n        if (args.Length != 0)\n        {\n            ConsoleLogger.Default.WriteLine($\"Start benchmarks with args: {string.Join(\" \", args)}\");\n            ConsoleLogger.Default.WriteLine();\n        }\n\n        IConfig? config = GetConfig(ref args);\n\n        var summaries = BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly)\n                                         .Run(args, config)\n                                         .ToArray();\n\n        if (summaries.HasError())\n            return 1;\n\n        return 0;\n    }\n\n    private static IConfig? GetConfig(ref string[] args)\n    {\n#if !DEBUG\n        return null; // `DefaultConfig.Instance` is used.\n#else\n        bool isInProcess = args.Contains(\"--inProcess\");\n        if (isInProcess)\n            args = args.Where(x => x != \"--inProcess\").ToArray();\n\n        DebugConfig config = isInProcess\n            ? new DebugInProcessConfig()\n            : new DebugBuildConfig();\n\n        return config.AddAnalyser(DefaultConfig.Instance.GetAnalysers().ToArray())\n                     .AddExporter(MarkdownExporter.Default)\n                     .AddValidator(DefaultConfig.Instance.GetValidators().ToArray())\n                     .WithArtifactsPath(DefaultConfig.Instance.ArtifactsPath!);\n#endif\n    }\n}\n"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/Properties/AssemblyInfo.cs",
    "content": "﻿using System.Runtime.InteropServices;\n\n[assembly: Guid(\"6f2232a9-0d0c-46cf-b08c-f6e28ab612e3\")]"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples/Properties/launchSettings.json",
    "content": "{\n  \"profiles\": {\n    \"Default\": {\n      \"commandName\": \"Project\",\n      \"commandLineArgs\": \"\",\n      \"environmentVariables\": {\n      }\n    },\n    \"Run IntroBasic Benchmarks\": {\n      \"commandName\": \"Project\",\n      \"commandLineArgs\": \"--filter *IntroBasic*\",\n      \"environmentVariables\": {\n      }\n    },\n    \"Run IntroBasic Benchmarks with --inProcess\": {\n      \"commandName\": \"Project\",\n      \"commandLineArgs\": \"--filter *IntroBasic* --inProcess\",\n      \"environmentVariables\": {\n      }\n    },\n    \"--list\": {\n      \"commandName\": \"Project\",\n      \"commandLineArgs\": \"--list\"\n    },\n    \"--info\": {\n      \"commandName\": \"Project\",\n      \"commandLineArgs\": \"--info\"\n    },\n    \"--help\": {\n      \"commandName\": \"Project\",\n      \"commandLineArgs\": \"--help\"\n    },\n    \"--version\": {\n      \"commandName\": \"Project\",\n      \"commandLineArgs\": \"--version\"\n    }\n  }\n}\n"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples.FSharp/BenchmarkDotNet.Samples.FSharp.fsproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n  <Import Project=\"..\\..\\build\\common.props\" />\n  <PropertyGroup>\n    <OutputType>Exe</OutputType>\n    <TargetFrameworks>net462;net8.0</TargetFrameworks>\n    <GenerateProgramFile>false</GenerateProgramFile>\n    <!-- Disable parallel tests between TargetFrameworks -->\n    <TestTfmsInParallel>false</TestTfmsInParallel>\n  </PropertyGroup>\n  <ItemGroup>\n    <Compile Include=\"Program.fs\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ProjectReference Include=\"..\\..\\src\\BenchmarkDotNet\\BenchmarkDotNet.csproj\" />\n    <ProjectReference Include=\"..\\..\\src\\BenchmarkDotNet.TestAdapter\\BenchmarkDotNet.TestAdapter.csproj\" />\n  </ItemGroup>\n  \n  <ItemGroup Condition=\" '$(TargetFrameworkIdentifier)' == '.NETFramework' \">\n    <ProjectReference Include=\"..\\..\\src\\BenchmarkDotNet.Diagnostics.Windows\\BenchmarkDotNet.Diagnostics.Windows.csproj\" />\n  </ItemGroup>\n  \n  <ItemGroup>\n    <PackageReference Update=\"FSharp.Core\" Version=\"10.0.103\" />\n    <PackageReference Update=\"System.ValueTuple\" Version=\"4.6.2\" />\n    <PackageReference Include=\"Microsoft.NET.Test.Sdk\" Version=\"18.0.1\" />\n  </ItemGroup>\n\n  <Import Project=\"..\\..\\build\\common.targets\" />\n</Project>\n"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples.FSharp/Program.fs",
    "content": "module Program\n\nopen System\nopen System.IO\nopen System.Collections.Concurrent\nopen BenchmarkDotNet.Attributes\nopen BenchmarkDotNet.Running\n\nlet getStrings len = Array.init len (fun _ -> Path.GetRandomFileName())\n\nlet lookup arr (dict:ConcurrentDictionary<string,bool>) =\n    arr |> Array.iteri(fun idx elm -> \n        let mutable b = dict.[elm]\n        b <- dict.[arr.[0]])\n\n\ntype StringKeyComparison () =\n    let mutable arr : string [] = [||]\n    let dict1 = ConcurrentDictionary<_,_>()\n    let dict2 = ConcurrentDictionary<_,_>(StringComparer.Ordinal)\n\n    [<Params (100, 500, 1000, 2000)>] \n    member val public DictSize = 0 with get, set\n\n    [<GlobalSetup>]\n    member self.GlobalSetupData() =\n        dict1.Clear(); dict2.Clear()\n        arr <- getStrings self.DictSize\n        arr |> Array.iter (fun x -> dict1.[x] <- true ; dict2.[x] <- true)\n\n    [<Benchmark>]\n    member self.StandardLookup () = lookup arr dict1\n\n    [<Benchmark>]\n    member self.OrdinalLookup () = lookup arr dict2\n\n#if NETFRAMEWORK\n[<BenchmarkDotNet.Diagnostics.Windows.Configs.TailCallDiagnoser>]\n#endif\ntype TailCallDetector () =\n    \n    let rec factorial n =\n            match n with\n            | 0 | 1 -> 1\n            | _ -> n * factorial(n-1)\n            \n    let factorial1 n =\n        let rec loop i acc =\n            match i with\n            | 0 | 1 -> acc\n            | _ -> loop (i-1) (acc * i)\n        loop n 1\n        \n    let factorial2 n =\n        let rec tailCall n f =\n            if n <= 1 then\n                f()\n            else\n                tailCall (n - 1) (fun () -> n * f())\n \n        tailCall n (fun () -> 1)\n\n    [<Params (7)>] \n    member val public facRank = 0 with get, set\n            \n    [<Benchmark>]\n    member self.test () =\n       factorial self.facRank\n    \n    [<Benchmark>]\n    member self.test1 () =\n       factorial1 self.facRank\n    \n    [<Benchmark>]\n    member self.test2 () =\n       factorial2 self.facRank\n       \nlet defaultSwitch () = BenchmarkSwitcher [|typeof<StringKeyComparison>; typeof<TailCallDetector>|]\n\n[<EntryPoint>]\nlet Main args =\n    let summary = defaultSwitch().Run args\n    0\n"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples.Maui/App.xaml",
    "content": "﻿<?xml version = \"1.0\" encoding = \"UTF-8\" ?>\n<Application xmlns=\"http://schemas.microsoft.com/dotnet/2021/maui\"\n             xmlns:x=\"http://schemas.microsoft.com/winfx/2009/xaml\"\n             xmlns:local=\"clr-namespace:BenchmarkDotNet.Samples.Maui\"\n             x:Class=\"BenchmarkDotNet.Samples.Maui.App\">\n    <Application.Resources>\n        <ResourceDictionary>\n            <ResourceDictionary.MergedDictionaries>\n                <ResourceDictionary Source=\"Resources/Styles/Colors.xaml\" />\n                <ResourceDictionary Source=\"Resources/Styles/Styles.xaml\" />\n            </ResourceDictionary.MergedDictionaries>\n        </ResourceDictionary>\n    </Application.Resources>\n</Application>\n"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples.Maui/App.xaml.cs",
    "content": "﻿using Microsoft.Extensions.DependencyInjection;\n\nnamespace BenchmarkDotNet.Samples.Maui;\n\npublic partial class App : Application\n{\n    public App()\n    {\n        InitializeComponent();\n    }\n\n    protected override Window CreateWindow(IActivationState? activationState)\n    {\n        return new Window(new AppShell());\n    }\n}"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples.Maui/AppShell.xaml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<Shell\n    x:Class=\"BenchmarkDotNet.Samples.Maui.AppShell\"\n    xmlns=\"http://schemas.microsoft.com/dotnet/2021/maui\"\n    xmlns:x=\"http://schemas.microsoft.com/winfx/2009/xaml\"\n    xmlns:local=\"clr-namespace:BenchmarkDotNet.Samples.Maui\"\n    Title=\"BenchmarkDotNet Samples\">\n\n    <ShellContent\n        Title=\"Benchmarks\"\n        ContentTemplate=\"{DataTemplate local:MainPage}\"\n        Route=\"MainPage\" />\n\n</Shell>\n"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples.Maui/AppShell.xaml.cs",
    "content": "﻿namespace BenchmarkDotNet.Samples.Maui;\n\npublic partial class AppShell : Shell\n{\n    public AppShell()\n    {\n        InitializeComponent();\n    }\n}\n"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples.Maui/BenchmarkDotNet.Samples.Maui.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\t<Import Project=\"..\\..\\build\\common.props\" />\n\n\t<PropertyGroup>\n\t\t<TargetFrameworks>net10.0-android;net10.0-ios;net10.0-maccatalyst</TargetFrameworks>\n\t\t<TargetFrameworks Condition=\"$([MSBuild]::IsOSPlatform('windows'))\">$(TargetFrameworks);net10.0-windows10.0.19041.0</TargetFrameworks>\n\n\t\t<!-- Note for MacCatalyst:\n\t\tThe default runtime is maccatalyst-x64, except in Release config, in which case the default is maccatalyst-x64;maccatalyst-arm64.\n\t\tWhen specifying both architectures, use the plural <RuntimeIdentifiers> instead of the singular <RuntimeIdentifier>.\n\t\tThe Mac App Store will NOT accept apps with ONLY maccatalyst-arm64 indicated;\n\t\teither BOTH runtimes must be indicated or ONLY macatalyst-x64. -->\n\t\t<!-- For example: <RuntimeIdentifiers>maccatalyst-x64;maccatalyst-arm64</RuntimeIdentifiers> -->\n\n\t\t<OutputType>Exe</OutputType>\n\t\t<RootNamespace>BenchmarkDotNet.Samples.Maui</RootNamespace>\n\t\t<UseMaui>true</UseMaui>\n\t\t<SingleProject>true</SingleProject>\n\t\t<ImplicitUsings>enable</ImplicitUsings>\n\t\t<Nullable>enable</Nullable>\n\n\t\t<!-- Display name -->\n\t\t<ApplicationTitle>BenchmarkDotNet Samples</ApplicationTitle>\n\n\t\t<!-- App Identifier -->\n\t\t<ApplicationId>com.benchmarkdotnet.samples</ApplicationId>\n\n\t\t<!-- Versions -->\n\t\t<ApplicationDisplayVersion>1.0</ApplicationDisplayVersion>\n\t\t<ApplicationVersion>1</ApplicationVersion>\n\n\t\t<!-- To develop, package, and publish an app to the Microsoft Store, see: https://aka.ms/MauiTemplateUnpackaged -->\n\t\t<WindowsPackageType>None</WindowsPackageType>\n\n\t\t<SupportedOSPlatformVersion Condition=\"$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'\">15.0</SupportedOSPlatformVersion>\n\t\t<SupportedOSPlatformVersion Condition=\"$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst'\">15.0</SupportedOSPlatformVersion>\n\t\t<SupportedOSPlatformVersion Condition=\"$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'android'\">21.0</SupportedOSPlatformVersion>\n\t\t<SupportedOSPlatformVersion Condition=\"$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'\">10.0.17763.0</SupportedOSPlatformVersion>\n\t\t<TargetPlatformMinVersion Condition=\"$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'\">10.0.17763.0</TargetPlatformMinVersion>\n\n\t\t<!-- Disable strong naming - inherited from build\\common.props -->\n\t\t<SignAssembly>false</SignAssembly>\n\t</PropertyGroup>\n\n\t<ItemGroup>\n\t\t<!-- App Icon -->\n\t\t<MauiIcon Include=\"Resources\\AppIcon\\appicon.svg\" ForegroundFile=\"Resources\\AppIcon\\appiconfg.svg\" Color=\"#512BD4\" />\n\n\t\t<!-- Splash Screen -->\n\t\t<MauiSplashScreen Include=\"Resources\\Splash\\splash.svg\" Color=\"#512BD4\" BaseSize=\"128,128\" />\n\n\t\t<!-- Custom Fonts -->\n\t\t<MauiFont Include=\"Resources\\Fonts\\*\" />\n\t</ItemGroup>\n\n\t<ItemGroup>\n\t\t<Compile Include=\"..\\BenchmarkDotNet.Samples\\IntroBasic.cs\" Link=\"Benchmarks\\IntroBasic.cs\" />\n\t</ItemGroup>\n\n\t<ItemGroup>\n\t\t<PackageReference Include=\"Microsoft.Maui.Controls\" Version=\"$(MauiVersion)\" />\n\t\t<PackageReference Include=\"Microsoft.Maui.Essentials\" Version=\"$(MauiVersion)\" />\n\t\t<PackageReference Include=\"Microsoft.Extensions.Logging.Debug\" Version=\"10.0.0\" />\n\t\t<PackageReference Include=\"BenchmarkDotNet.Weaver\" Version=\"$(VersionPrefix)-$(VersionSuffix)$(WeaverVersionSuffix)\" />\n\t</ItemGroup>\n\n\t<ItemGroup>\n\t\t<ProjectReference Include=\"..\\..\\src\\BenchmarkDotNet\\BenchmarkDotNet.csproj\" />\n\t</ItemGroup>\n\n\t<Import Project=\"..\\..\\build\\common.targets\" />\n</Project>\n"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples.Maui/MainPage.xaml",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<ContentPage xmlns=\"http://schemas.microsoft.com/dotnet/2021/maui\"\n             xmlns:x=\"http://schemas.microsoft.com/winfx/2009/xaml\"\n             x:Class=\"BenchmarkDotNet.Samples.Maui.MainPage\">\n    <ContentPage.Padding>\n        <OnPlatform x:TypeArguments=\"Thickness\">\n            <On Platform=\"iOS\" Value=\"0,44,0,0\" />\n        </OnPlatform>\n    </ContentPage.Padding>\n    <Grid RowSpacing=\"0\">\n        <Grid.RowDefinitions>\n            <RowDefinition Height=\"Auto\" />\n            <RowDefinition Height=\"*\" />\n        </Grid.RowDefinitions>\n        <Button\n            x:Name=\"Run\"\n            Text=\"Run\"\n            Margin=\"10,10,10,0\"\n            Clicked=\"Button_Clicked\" />\n        <ScrollView Orientation=\"Both\" Grid.Row=\"1\">\n            <Label\n                x:Name=\"Summary\"\n                Grid.Row=\"1\"\n                Padding=\"10\">\n                <Label.FontFamily>\n                    <OnPlatform x:TypeArguments=\"x:String\">\n                        <On Platform=\"Android\" Value=\"monospace\" />\n                        <On Platform=\"iOS\" Value=\"Courier\" />\n                        <On Platform=\"WinUI\" Value=\"Consolas\" />\n                        <On Platform=\"MacCatalyst\" Value=\"Courier\" />\n                    </OnPlatform>\n                </Label.FontFamily>\n            </Label>\n        </ScrollView>\n        <ActivityIndicator\n            x:Name=\"Indicator\"\n            Grid.RowSpan=\"2\"\n            Color=\"DarkGray\"\n            HorizontalOptions=\"Center\"\n            VerticalOptions=\"Center\" />\n    </Grid>\n</ContentPage>\n"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples.Maui/MainPage.xaml.cs",
    "content": "﻿using BenchmarkDotNet.Analysers;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Exporters;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Running;\n\nnamespace BenchmarkDotNet.Samples.Maui;\n\npublic partial class MainPage : ContentPage\n{\n    public MainPage()\n    {\n        InitializeComponent();\n    }\n\n    private async void Button_Clicked(object? sender, EventArgs e)\n    {\n        SetIsRunning(true);\n        try\n        {\n            var logger = new AccumulationLogger();\n            await Task.Run(() =>\n            {\n                var config = default(IConfig);\n#if DEBUG\n                config = new DebugInProcessConfig();\n#endif\n                var summary = BenchmarkRunner.Run<IntroBasic>(config);\n                MarkdownExporter.Console.ExportToLog(summary, logger);\n                ConclusionHelper.Print(logger,\n                        summary.BenchmarksCases\n                               .SelectMany(benchmark => benchmark.Config.GetCompositeAnalyser().Analyse(summary))\n                               .Distinct()\n                               .ToList());\n            });\n            Summary.Text = logger.GetLog();\n        }\n        catch (Exception exc)\n        {\n            await DisplayAlertAsync(\"Error\", exc.Message, \"Ok\");\n        }\n        finally\n        {\n            SetIsRunning(false);\n        }\n    }\n\n    private void SetIsRunning(bool isRunning)\n    {\n        Indicator.IsRunning = isRunning;\n        Run.IsVisible =\n            Summary.IsVisible = !isRunning;\n    }\n}\n"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples.Maui/MauiProgram.cs",
    "content": "﻿using Microsoft.Extensions.Logging;\n\nnamespace BenchmarkDotNet.Samples.Maui;\n\npublic static class MauiProgram\n{\n    public static MauiApp CreateMauiApp()\n    {\n        var builder = MauiApp.CreateBuilder();\n        builder\n            .UseMauiApp<App>()\n            .ConfigureFonts(fonts =>\n            {\n                fonts.AddFont(\"OpenSans-Regular.ttf\", \"OpenSansRegular\");\n                fonts.AddFont(\"OpenSans-Semibold.ttf\", \"OpenSansSemibold\");\n            });\n\n#if DEBUG\n        builder.Logging.AddDebug();\n#endif\n\n        return builder.Build();\n    }\n}\n"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples.Maui/Platforms/Android/AndroidManifest.xml",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\t<application android:allowBackup=\"true\" android:icon=\"@mipmap/appicon\" android:roundIcon=\"@mipmap/appicon_round\" android:supportsRtl=\"true\"></application>\n\t<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\" />\n\t<uses-permission android:name=\"android.permission.INTERNET\" />\n</manifest>"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples.Maui/Platforms/Android/MainActivity.cs",
    "content": "﻿using Android.App;\nusing Android.Content.PM;\nusing Android.OS;\n\nnamespace BenchmarkDotNet.Samples.Maui;\n\n[Activity(Theme = \"@style/Maui.SplashTheme\", MainLauncher = true, LaunchMode = LaunchMode.SingleTop, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize | ConfigChanges.Density)]\npublic class MainActivity : MauiAppCompatActivity\n{\n}\n"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples.Maui/Platforms/Android/MainApplication.cs",
    "content": "﻿using Android.App;\nusing Android.Runtime;\n\nnamespace BenchmarkDotNet.Samples.Maui;\n\n[Application]\npublic class MainApplication : MauiApplication\n{\n    public MainApplication(IntPtr handle, JniHandleOwnership ownership)\n        : base(handle, ownership)\n    {\n    }\n\n    protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();\n}\n"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples.Maui/Platforms/Android/Resources/values/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"colorPrimary\">#512BD4</color>\n    <color name=\"colorPrimaryDark\">#2B0B98</color>\n    <color name=\"colorAccent\">#2B0B98</color>\n</resources>"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples.Maui/Platforms/MacCatalyst/AppDelegate.cs",
    "content": "﻿using Foundation;\n\nnamespace BenchmarkDotNet.Samples.Maui;\n\n[Register(\"AppDelegate\")]\npublic class AppDelegate : MauiUIApplicationDelegate\n{\n    protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();\n}\n"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples.Maui/Platforms/MacCatalyst/Entitlements.plist",
    "content": "﻿<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n    <!-- See https://aka.ms/maui-publish-app-store#add-entitlements for more information about adding entitlements.-->\n    <dict>\n        <!-- App Sandbox must be enabled to distribute a MacCatalyst app through the Mac App Store. -->\n        <key>com.apple.security.app-sandbox</key>\n        <true/>\n        <!-- When App Sandbox is enabled, this value is required to open outgoing network connections. -->\n        <key>com.apple.security.network.client</key>\n        <true/>\n    </dict>\n</plist>\n\n"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples.Maui/Platforms/MacCatalyst/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n    <!-- The Mac App Store requires you specify if the app uses encryption. -->\n    <!-- Please consult https://developer.apple.com/documentation/bundleresources/information_property_list/itsappusesnonexemptencryption -->\n    <!-- <key>ITSAppUsesNonExemptEncryption</key> -->\n    <!-- Please indicate <true/> or <false/> here. -->\n\n    <!-- Specify the category for your app here. -->\n    <!-- Please consult https://developer.apple.com/documentation/bundleresources/information_property_list/lsapplicationcategorytype -->\n    <!-- <key>LSApplicationCategoryType</key> -->\n    <!-- <string>public.app-category.YOUR-CATEGORY-HERE</string> -->\n\t<key>UIDeviceFamily</key>\n\t<array>\n\t\t<integer>2</integer>\n\t</array>\n\t<key>LSApplicationCategoryType</key>\n\t<string>public.app-category.lifestyle</string>\n\t<key>UIRequiredDeviceCapabilities</key>\n\t<array>\n\t\t<string>arm64</string>\n\t</array>\n\t<key>UISupportedInterfaceOrientations</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n\t</array>\n\t<key>UISupportedInterfaceOrientations~ipad</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t\t<string>UIInterfaceOrientationPortraitUpsideDown</string>\n\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n\t</array>\n\t<key>XSAppIconAssets</key>\n\t<string>Assets.xcassets/appicon.appiconset</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples.Maui/Platforms/MacCatalyst/Program.cs",
    "content": "﻿using ObjCRuntime;\nusing UIKit;\n\nnamespace BenchmarkDotNet.Samples.Maui;\n\npublic class Program\n{\n    // This is the main entry point of the application.\n    public static void Main(string[] args)\n    {\n        // if you want to use a different Application Delegate class from \"AppDelegate\"\n        // you can specify it here.\n        UIApplication.Main(args, null, typeof(AppDelegate));\n    }\n}\n"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples.Maui/Platforms/Windows/App.xaml",
    "content": "﻿<maui:MauiWinUIApplication\n    x:Class=\"BenchmarkDotNet.Samples.Maui.WinUI.App\"\n    xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n    xmlns:maui=\"using:Microsoft.Maui\"\n    xmlns:local=\"using:BenchmarkDotNet.Samples.Maui.WinUI\">\n\n</maui:MauiWinUIApplication>\n"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples.Maui/Platforms/Windows/App.xaml.cs",
    "content": "﻿using Microsoft.UI.Xaml;\n\n// To learn more about WinUI, the WinUI project structure,\n// and more about our project templates, see: http://aka.ms/winui-project-info.\n\nnamespace BenchmarkDotNet.Samples.Maui.WinUI;\n\n/// <summary>\n/// Provides application-specific behavior to supplement the default Application class.\n/// </summary>\npublic partial class App : MauiWinUIApplication\n{\n    /// <summary>\n    /// Initializes the singleton application object.  This is the first line of authored code\n    /// executed, and as such is the logical equivalent of main() or WinMain().\n    /// </summary>\n    public App()\n    {\n        this.InitializeComponent();\n    }\n\n    protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();\n}\n"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples.Maui/Platforms/Windows/Package.appxmanifest",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Package\n  xmlns=\"http://schemas.microsoft.com/appx/manifest/foundation/windows10\"\n  xmlns:uap=\"http://schemas.microsoft.com/appx/manifest/uap/windows10\"\n  xmlns:mp=\"http://schemas.microsoft.com/appx/2014/phone/manifest\"\n  xmlns:rescap=\"http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities\"\n  IgnorableNamespaces=\"uap rescap\">\n\n  <Identity Name=\"maui-package-name-placeholder\" Publisher=\"CN=User Name\" Version=\"0.0.0.0\" />\n\n  <mp:PhoneIdentity PhoneProductId=\"B4D6C1AB-7284-4C5B-9592-632E598B65D9\" PhonePublisherId=\"00000000-0000-0000-0000-000000000000\"/>\n\n  <Properties>\n    <DisplayName>$placeholder$</DisplayName>\n    <PublisherDisplayName>User Name</PublisherDisplayName>\n    <Logo>$placeholder$.png</Logo>\n  </Properties>\n\n  <Dependencies>\n    <TargetDeviceFamily Name=\"Windows.Universal\" MinVersion=\"10.0.17763.0\" MaxVersionTested=\"10.0.19041.0\" />\n    <TargetDeviceFamily Name=\"Windows.Desktop\" MinVersion=\"10.0.17763.0\" MaxVersionTested=\"10.0.19041.0\" />\n  </Dependencies>\n\n  <Resources>\n    <Resource Language=\"x-generate\" />\n  </Resources>\n\n  <Applications>\n    <Application Id=\"App\" Executable=\"$targetnametoken$.exe\" EntryPoint=\"$targetentrypoint$\">\n      <uap:VisualElements\n        DisplayName=\"$placeholder$\"\n        Description=\"$placeholder$\"\n        Square150x150Logo=\"$placeholder$.png\"\n        Square44x44Logo=\"$placeholder$.png\"\n        BackgroundColor=\"transparent\">\n        <uap:DefaultTile Square71x71Logo=\"$placeholder$.png\" Wide310x150Logo=\"$placeholder$.png\" Square310x310Logo=\"$placeholder$.png\" />\n        <uap:SplashScreen Image=\"$placeholder$.png\" />\n      </uap:VisualElements>\n    </Application>\n  </Applications>\n\n  <Capabilities>\n    <rescap:Capability Name=\"runFullTrust\" />\n  </Capabilities>\n\n</Package>\n"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples.Maui/Platforms/Windows/app.manifest",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<assembly manifestVersion=\"1.0\" xmlns=\"urn:schemas-microsoft-com:asm.v1\">\n  <assemblyIdentity version=\"1.0.0.0\" name=\"BenchmarkDotNet.Samples.Maui.WinUI.app\"/>\n\n  <application xmlns=\"urn:schemas-microsoft-com:asm.v3\">\n    <windowsSettings>\n      <!-- The combination of below two tags have the following effect:\n           1) Per-Monitor for >= Windows 10 Anniversary Update\n           2) System < Windows 10 Anniversary Update\n      -->\n      <dpiAware xmlns=\"http://schemas.microsoft.com/SMI/2005/WindowsSettings\">true/PM</dpiAware>\n      <dpiAwareness xmlns=\"http://schemas.microsoft.com/SMI/2016/WindowsSettings\">PerMonitorV2, PerMonitor</dpiAwareness>\n\n      <longPathAware xmlns=\"http://schemas.microsoft.com/SMI/2016/WindowsSettings\">true</longPathAware>\n    </windowsSettings>\n  </application>\n</assembly>\n"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples.Maui/Platforms/iOS/AppDelegate.cs",
    "content": "﻿using Foundation;\n\nnamespace BenchmarkDotNet.Samples.Maui;\n\n[Register(\"AppDelegate\")]\npublic class AppDelegate : MauiUIApplicationDelegate\n{\n    protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();\n}\n"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples.Maui/Platforms/iOS/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>LSRequiresIPhoneOS</key>\n\t<true/>\n\t<key>UIDeviceFamily</key>\n\t<array>\n\t\t<integer>1</integer>\n\t\t<integer>2</integer>\n\t</array>\n\t<key>UIRequiredDeviceCapabilities</key>\n\t<array>\n\t\t<string>arm64</string>\n\t</array>\n\t<key>UISupportedInterfaceOrientations</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n\t</array>\n\t<key>UISupportedInterfaceOrientations~ipad</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t\t<string>UIInterfaceOrientationPortraitUpsideDown</string>\n\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n\t</array>\n\t<key>XSAppIconAssets</key>\n\t<string>Assets.xcassets/appicon.appiconset</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples.Maui/Platforms/iOS/Program.cs",
    "content": "﻿using ObjCRuntime;\nusing UIKit;\n\nnamespace BenchmarkDotNet.Samples.Maui;\n\npublic class Program\n{\n    // This is the main entry point of the application.\n    public static void Main(string[] args)\n    {\n        // if you want to use a different Application Delegate class from \"AppDelegate\"\n        // you can specify it here.\n        UIApplication.Main(args, null, typeof(AppDelegate));\n    }\n}\n"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples.Maui/Platforms/iOS/Resources/PrivacyInfo.xcprivacy",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\nThis is the minimum required version of the Apple Privacy Manifest for .NET MAUI apps.\nThe contents below are needed because of APIs that are used in the .NET framework and .NET MAUI SDK.\n\nYou are responsible for adding extra entries as needed for your application.\n\nMore information: https://aka.ms/maui-privacy-manifest\n-->\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n    <key>NSPrivacyAccessedAPITypes</key>\n    <array>\n        <dict>\n            <key>NSPrivacyAccessedAPIType</key>\n            <string>NSPrivacyAccessedAPICategoryFileTimestamp</string>\n            <key>NSPrivacyAccessedAPITypeReasons</key>\n            <array>\n                <string>C617.1</string>\n            </array>\n        </dict>\n        <dict>\n            <key>NSPrivacyAccessedAPIType</key>\n            <string>NSPrivacyAccessedAPICategorySystemBootTime</string>\n            <key>NSPrivacyAccessedAPITypeReasons</key>\n            <array>\n                <string>35F9.1</string>\n            </array>\n        </dict>\n        <dict>\n            <key>NSPrivacyAccessedAPIType</key>\n            <string>NSPrivacyAccessedAPICategoryDiskSpace</string>\n            <key>NSPrivacyAccessedAPITypeReasons</key>\n            <array>\n                <string>E174.1</string>\n            </array>\n        </dict>\n        <!--\n            The entry below is only needed when you're using the Preferences API in your app.\n        <dict>\n            <key>NSPrivacyAccessedAPIType</key>\n            <string>NSPrivacyAccessedAPICategoryUserDefaults</string>\n            <key>NSPrivacyAccessedAPITypeReasons</key>\n            <array>\n                <string>CA92.1</string>\n            </array>\n        </dict> -->\n    </array>\n</dict>\n</plist>\n"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples.Maui/Properties/launchSettings.json",
    "content": "{\n  \"profiles\": {\n    \"Windows Machine\": {\n      \"commandName\": \"Project\",\n      \"nativeDebugging\": false\n    }\n  }\n}"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples.Maui/Resources/Styles/Colors.xaml",
    "content": "﻿<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<ResourceDictionary \n    xmlns=\"http://schemas.microsoft.com/dotnet/2021/maui\"\n    xmlns:x=\"http://schemas.microsoft.com/winfx/2009/xaml\">\n\n    <!-- Note: For Android please see also Platforms\\Android\\Resources\\values\\colors.xml -->\n\n    <Color x:Key=\"Primary\">#512BD4</Color>\n    <Color x:Key=\"PrimaryDark\">#ac99ea</Color>\n    <Color x:Key=\"PrimaryDarkText\">#242424</Color>\n    <Color x:Key=\"Secondary\">#DFD8F7</Color>\n    <Color x:Key=\"SecondaryDarkText\">#9880e5</Color>\n    <Color x:Key=\"Tertiary\">#2B0B98</Color>\n\n    <Color x:Key=\"White\">White</Color>\n    <Color x:Key=\"Black\">Black</Color>\n    <Color x:Key=\"Magenta\">#D600AA</Color>\n    <Color x:Key=\"MidnightBlue\">#190649</Color>\n    <Color x:Key=\"OffBlack\">#1f1f1f</Color>\n\n    <Color x:Key=\"Gray100\">#E1E1E1</Color>\n    <Color x:Key=\"Gray200\">#C8C8C8</Color>\n    <Color x:Key=\"Gray300\">#ACACAC</Color>\n    <Color x:Key=\"Gray400\">#919191</Color>\n    <Color x:Key=\"Gray500\">#6E6E6E</Color>\n    <Color x:Key=\"Gray600\">#404040</Color>\n    <Color x:Key=\"Gray900\">#212121</Color>\n    <Color x:Key=\"Gray950\">#141414</Color>\n\n    <SolidColorBrush x:Key=\"PrimaryBrush\" Color=\"{StaticResource Primary}\"/>\n    <SolidColorBrush x:Key=\"SecondaryBrush\" Color=\"{StaticResource Secondary}\"/>\n    <SolidColorBrush x:Key=\"TertiaryBrush\" Color=\"{StaticResource Tertiary}\"/>\n    <SolidColorBrush x:Key=\"WhiteBrush\" Color=\"{StaticResource White}\"/>\n    <SolidColorBrush x:Key=\"BlackBrush\" Color=\"{StaticResource Black}\"/>\n\n    <SolidColorBrush x:Key=\"Gray100Brush\" Color=\"{StaticResource Gray100}\"/>\n    <SolidColorBrush x:Key=\"Gray200Brush\" Color=\"{StaticResource Gray200}\"/>\n    <SolidColorBrush x:Key=\"Gray300Brush\" Color=\"{StaticResource Gray300}\"/>\n    <SolidColorBrush x:Key=\"Gray400Brush\" Color=\"{StaticResource Gray400}\"/>\n    <SolidColorBrush x:Key=\"Gray500Brush\" Color=\"{StaticResource Gray500}\"/>\n    <SolidColorBrush x:Key=\"Gray600Brush\" Color=\"{StaticResource Gray600}\"/>\n    <SolidColorBrush x:Key=\"Gray900Brush\" Color=\"{StaticResource Gray900}\"/>\n    <SolidColorBrush x:Key=\"Gray950Brush\" Color=\"{StaticResource Gray950}\"/>\n</ResourceDictionary>"
  },
  {
    "path": "samples/BenchmarkDotNet.Samples.Maui/Resources/Styles/Styles.xaml",
    "content": "﻿<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<ResourceDictionary \n    xmlns=\"http://schemas.microsoft.com/dotnet/2021/maui\"\n    xmlns:x=\"http://schemas.microsoft.com/winfx/2009/xaml\">\n\n    <Style TargetType=\"ActivityIndicator\">\n        <Setter Property=\"Color\" Value=\"{AppThemeBinding Light={StaticResource Primary}, Dark={StaticResource White}}\" />\n    </Style>\n\n    <Style TargetType=\"IndicatorView\">\n        <Setter Property=\"IndicatorColor\" Value=\"{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource Gray500}}\"/>\n        <Setter Property=\"SelectedIndicatorColor\" Value=\"{AppThemeBinding Light={StaticResource Gray950}, Dark={StaticResource Gray100}}\"/>\n    </Style>\n\n    <Style TargetType=\"Border\">\n        <Setter Property=\"Stroke\" Value=\"{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource Gray500}}\" />\n        <Setter Property=\"StrokeShape\" Value=\"Rectangle\"/>\n        <Setter Property=\"StrokeThickness\" Value=\"1\"/>\n    </Style>\n\n    <Style TargetType=\"BoxView\">\n        <Setter Property=\"BackgroundColor\" Value=\"{AppThemeBinding Light={StaticResource Gray950}, Dark={StaticResource Gray200}}\" />\n    </Style>\n\n    <Style TargetType=\"Button\">\n        <Setter Property=\"TextColor\" Value=\"{AppThemeBinding Light={StaticResource White}, Dark={StaticResource PrimaryDarkText}}\" />\n        <Setter Property=\"BackgroundColor\" Value=\"{AppThemeBinding Light={StaticResource Primary}, Dark={StaticResource PrimaryDark}}\" />\n        <Setter Property=\"FontFamily\" Value=\"OpenSansRegular\"/>\n        <Setter Property=\"FontSize\" Value=\"14\"/>\n        <Setter Property=\"BorderWidth\" Value=\"0\"/>\n        <Setter Property=\"CornerRadius\" Value=\"8\"/>\n        <Setter Property=\"Padding\" Value=\"14,10\"/>\n        <Setter Property=\"MinimumHeightRequest\" Value=\"44\"/>\n        <Setter Property=\"MinimumWidthRequest\" Value=\"44\"/>\n        <Setter Property=\"VisualStateManager.VisualStateGroups\">\n            <VisualStateGroupList>\n                <VisualStateGroup x:Name=\"CommonStates\">\n                    <VisualState x:Name=\"Normal\" />\n                    <VisualState x:Name=\"Disabled\">\n                        <VisualState.Setters>\n                            <Setter Property=\"TextColor\" Value=\"{AppThemeBinding Light={StaticResource Gray950}, Dark={StaticResource Gray200}}\" />\n                            <Setter Property=\"BackgroundColor\" Value=\"{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource Gray600}}\" />\n                        </VisualState.Setters>\n                    </VisualState>\n                    <VisualState x:Name=\"PointerOver\" />\n                </VisualStateGroup>\n            </VisualStateGroupList>\n        </Setter>\n    </Style>\n\n    <Style TargetType=\"CheckBox\">\n        <Setter Property=\"Color\" Value=\"{AppThemeBinding Light={StaticResource Primary}, Dark={StaticResource White}}\" />\n        <Setter Property=\"MinimumHeightRequest\" Value=\"44\"/>\n        <Setter Property=\"MinimumWidthRequest\" Value=\"44\"/>\n        <Setter Property=\"VisualStateManager.VisualStateGroups\">\n            <VisualStateGroupList>\n                <VisualStateGroup x:Name=\"CommonStates\">\n                    <VisualState x:Name=\"Normal\" />\n                    <VisualState x:Name=\"Disabled\">\n                        <VisualState.Setters>\n                            <Setter Property=\"Color\" Value=\"{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}\" />\n                        </VisualState.Setters>\n                    </VisualState>\n                </VisualStateGroup>\n            </VisualStateGroupList>\n        </Setter>\n    </Style>\n\n    <Style TargetType=\"DatePicker\">\n        <Setter Property=\"TextColor\" Value=\"{AppThemeBinding Light={StaticResource Gray900}, Dark={StaticResource White}}\" />\n        <Setter Property=\"BackgroundColor\" Value=\"Transparent\" />\n        <Setter Property=\"FontFamily\" Value=\"OpenSansRegular\"/>\n        <Setter Property=\"FontSize\" Value=\"14\"/>\n        <Setter Property=\"MinimumHeightRequest\" Value=\"44\"/>\n        <Setter Property=\"MinimumWidthRequest\" Value=\"44\"/>\n        <Setter Property=\"VisualStateManager.VisualStateGroups\">\n            <VisualStateGroupList>\n                <VisualStateGroup x:Name=\"CommonStates\">\n                    <VisualState x:Name=\"Normal\" />\n                    <VisualState x:Name=\"Disabled\">\n                        <VisualState.Setters>\n                            <Setter Property=\"TextColor\" Value=\"{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource Gray500}}\" />\n                        </VisualState.Setters>\n                    </VisualState>\n                </VisualStateGroup>\n            </VisualStateGroupList>\n        </Setter>\n    </Style>\n\n    <Style TargetType=\"Editor\">\n        <Setter Property=\"TextColor\" Value=\"{AppThemeBinding Light={StaticResource Black}, Dark={StaticResource White}}\" />\n        <Setter Property=\"BackgroundColor\" Value=\"Transparent\" />\n        <Setter Property=\"FontFamily\" Value=\"OpenSansRegular\"/>\n        <Setter Property=\"FontSize\" Value=\"14\" />\n        <Setter Property=\"PlaceholderColor\" Value=\"{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource Gray500}}\" />\n        <Setter Property=\"MinimumHeightRequest\" Value=\"44\"/>\n        <Setter Property=\"MinimumWidthRequest\" Value=\"44\"/>\n        <Setter Property=\"VisualStateManager.VisualStateGroups\">\n            <VisualStateGroupList>\n                <VisualStateGroup x:Name=\"CommonStates\">\n                    <VisualState x:Name=\"Normal\" />\n                    <VisualState x:Name=\"Disabled\">\n                        <VisualState.Setters>\n                            <Setter Property=\"TextColor\" Value=\"{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}\" />\n                        </VisualState.Setters>\n                    </VisualState>\n                </VisualStateGroup>\n            </VisualStateGroupList>\n        </Setter>\n    </Style>\n\n    <Style TargetType=\"Entry\">\n        <Setter Property=\"TextColor\" Value=\"{AppThemeBinding Light={StaticResource Black}, Dark={StaticResource White}}\" />\n        <Setter Property=\"BackgroundColor\" Value=\"Transparent\" />\n        <Setter Property=\"FontFamily\" Value=\"OpenSansRegular\"/>\n        <Setter Property=\"FontSize\" Value=\"14\" />\n        <Setter Property=\"PlaceholderColor\" Value=\"{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource Gray500}}\" />\n        <Setter Property=\"MinimumHeightRequest\" Value=\"44\"/>\n        <Setter Property=\"MinimumWidthRequest\" Value=\"44\"/>\n        <Setter Property=\"VisualStateManager.VisualStateGroups\">\n            <VisualStateGroupList>\n                <VisualStateGroup x:Name=\"CommonStates\">\n                    <VisualState x:Name=\"Normal\" />\n                    <VisualState x:Name=\"Disabled\">\n                        <VisualState.Setters>\n                            <Setter Property=\"TextColor\" Value=\"{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}\" />\n                        </VisualState.Setters>\n                    </VisualState>\n                </VisualStateGroup>\n            </VisualStateGroupList>\n        </Setter>\n    </Style>\n\n    <Style TargetType=\"ImageButton\">\n        <Setter Property=\"Opacity\" Value=\"1\" />\n        <Setter Property=\"BorderColor\" Value=\"Transparent\"/>\n        <Setter Property=\"BorderWidth\" Value=\"0\"/>\n        <Setter Property=\"CornerRadius\" Value=\"0\"/>\n        <Setter Property=\"MinimumHeightRequest\" Value=\"44\"/>\n        <Setter Property=\"MinimumWidthRequest\" Value=\"44\"/>\n        <Setter Property=\"VisualStateManager.VisualStateGroups\">\n            <VisualStateGroupList>\n                <VisualStateGroup x:Name=\"CommonStates\">\n                    <VisualState x:Name=\"Normal\" />\n                    <VisualState x:Name=\"Disabled\">\n                        <VisualState.Setters>\n                            <Setter Property=\"Opacity\" Value=\"0.5\" />\n                        </VisualState.Setters>\n                    </VisualState>\n                    <VisualState x:Name=\"PointerOver\" />\n                </VisualStateGroup>\n            </VisualStateGroupList>\n        </Setter>\n    </Style>\n\n    <Style TargetType=\"Label\">\n        <Setter Property=\"TextColor\" Value=\"{AppThemeBinding Light={StaticResource Black}, Dark={StaticResource White}}\" />\n        <Setter Property=\"BackgroundColor\" Value=\"Transparent\" />\n        <Setter Property=\"FontFamily\" Value=\"OpenSansRegular\" />\n        <Setter Property=\"FontSize\" Value=\"14\" />\n        <Setter Property=\"VisualStateManager.VisualStateGroups\">\n            <VisualStateGroupList>\n                <VisualStateGroup x:Name=\"CommonStates\">\n                    <VisualState x:Name=\"Normal\" />\n                    <VisualState x:Name=\"Disabled\">\n                        <VisualState.Setters>\n                            <Setter Property=\"TextColor\" Value=\"{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}\" />\n                        </VisualState.Setters>\n                    </VisualState>\n                </VisualStateGroup>\n            </VisualStateGroupList>\n        </Setter>\n    </Style>\n\n    <Style TargetType=\"Label\" x:Key=\"Headline\">\n        <Setter Property=\"TextColor\" Value=\"{AppThemeBinding Light={StaticResource MidnightBlue}, Dark={StaticResource White}}\" />\n        <Setter Property=\"FontSize\" Value=\"32\" />\n        <Setter Property=\"HorizontalOptions\" Value=\"Center\" />\n        <Setter Property=\"HorizontalTextAlignment\" Value=\"Center\" />\n    </Style>\n\n    <Style TargetType=\"Label\" x:Key=\"SubHeadline\">\n        <Setter Property=\"TextColor\" Value=\"{AppThemeBinding Light={StaticResource MidnightBlue}, Dark={StaticResource White}}\" />\n        <Setter Property=\"FontSize\" Value=\"24\" />\n        <Setter Property=\"HorizontalOptions\" Value=\"Center\" />\n        <Setter Property=\"HorizontalTextAlignment\" Value=\"Center\" />\n    </Style>\n\n    <Style TargetType=\"Picker\">\n        <Setter Property=\"TextColor\" Value=\"{AppThemeBinding Light={StaticResource Gray900}, Dark={StaticResource White}}\" />\n        <Setter Property=\"TitleColor\" Value=\"{AppThemeBinding Light={StaticResource Gray900}, Dark={StaticResource Gray200}}\" />\n        <Setter Property=\"BackgroundColor\" Value=\"Transparent\" />\n        <Setter Property=\"FontFamily\" Value=\"OpenSansRegular\"/>\n        <Setter Property=\"FontSize\" Value=\"14\" />\n        <Setter Property=\"MinimumHeightRequest\" Value=\"44\"/>\n        <Setter Property=\"MinimumWidthRequest\" Value=\"44\"/>\n        <Setter Property=\"VisualStateManager.VisualStateGroups\">\n            <VisualStateGroupList>\n                <VisualStateGroup x:Name=\"CommonStates\">\n                    <VisualState x:Name=\"Normal\" />\n                    <VisualState x:Name=\"Disabled\">\n                        <VisualState.Setters>\n                            <Setter Property=\"TextColor\" Value=\"{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}\" />\n                            <Setter Property=\"TitleColor\" Value=\"{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}\" />\n                        </VisualState.Setters>\n                    </VisualState>\n                </VisualStateGroup>\n            </VisualStateGroupList>\n        </Setter>\n    </Style>\n\n    <Style TargetType=\"ProgressBar\">\n        <Setter Property=\"ProgressColor\" Value=\"{AppThemeBinding Light={StaticResource Primary}, Dark={StaticResource White}}\" />\n        <Setter Property=\"VisualStateManager.VisualStateGroups\">\n            <VisualStateGroupList>\n                <VisualStateGroup x:Name=\"CommonStates\">\n                    <VisualState x:Name=\"Normal\" />\n                    <VisualState x:Name=\"Disabled\">\n                        <VisualState.Setters>\n                            <Setter Property=\"ProgressColor\" Value=\"{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}\" />\n                        </VisualState.Setters>\n                    </VisualState>\n                </VisualStateGroup>\n            </VisualStateGroupList>\n        </Setter>\n    </Style>\n\n    <Style TargetType=\"RadioButton\">\n        <Setter Property=\"BackgroundColor\" Value=\"Transparent\"/>\n        <Setter Property=\"TextColor\" Value=\"{AppThemeBinding Light={StaticResource Black}, Dark={StaticResource White}}\" />\n        <Setter Property=\"FontFamily\" Value=\"OpenSansRegular\"/>\n        <Setter Property=\"FontSize\" Value=\"14\"/>\n        <Setter Property=\"MinimumHeightRequest\" Value=\"44\"/>\n        <Setter Property=\"MinimumWidthRequest\" Value=\"44\"/>\n        <Setter Property=\"VisualStateManager.VisualStateGroups\">\n            <VisualStateGroupList>\n                <VisualStateGroup x:Name=\"CommonStates\">\n                    <VisualState x:Name=\"Normal\" />\n                    <VisualState x:Name=\"Disabled\">\n                        <VisualState.Setters>\n                            <Setter Property=\"TextColor\" Value=\"{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}\" />\n                        </VisualState.Setters>\n                    </VisualState>\n                </VisualStateGroup>\n            </VisualStateGroupList>\n        </Setter>\n    </Style>\n\n    <Style TargetType=\"RefreshView\">\n        <Setter Property=\"RefreshColor\" Value=\"{AppThemeBinding Light={StaticResource Gray900}, Dark={StaticResource Gray200}}\" />\n    </Style>\n\n    <Style TargetType=\"SearchBar\">\n        <Setter Property=\"TextColor\" Value=\"{AppThemeBinding Light={StaticResource Gray900}, Dark={StaticResource White}}\" />\n        <Setter Property=\"PlaceholderColor\" Value=\"{StaticResource Gray500}\" />\n        <Setter Property=\"CancelButtonColor\" Value=\"{StaticResource Gray500}\" />\n        <Setter Property=\"BackgroundColor\" Value=\"Transparent\" />\n        <Setter Property=\"FontFamily\" Value=\"OpenSansRegular\" />\n        <Setter Property=\"FontSize\" Value=\"14\" />\n        <Setter Property=\"MinimumHeightRequest\" Value=\"44\"/>\n        <Setter Property=\"MinimumWidthRequest\" Value=\"44\"/>\n        <Setter Property=\"VisualStateManager.VisualStateGroups\">\n            <VisualStateGroupList>\n                <VisualStateGroup x:Name=\"CommonStates\">\n                    <VisualState x:Name=\"Normal\" />\n                    <VisualState x:Name=\"Disabled\">\n                        <VisualState.Setters>\n                            <Setter Property=\"TextColor\" Value=\"{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}\" />\n                            <Setter Property=\"PlaceholderColor\" Value=\"{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}\" />\n                        </VisualState.Setters>\n                    </VisualState>\n                </VisualStateGroup>\n            </VisualStateGroupList>\n        </Setter>\n    </Style>\n\n    <Style TargetType=\"SearchHandler\">\n        <Setter Property=\"TextColor\" Value=\"{AppThemeBinding Light={StaticResource Gray900}, Dark={StaticResource White}}\" />\n        <Setter Property=\"PlaceholderColor\" Value=\"{StaticResource Gray500}\" />\n        <Setter Property=\"BackgroundColor\" Value=\"Transparent\" />\n        <Setter Property=\"FontFamily\" Value=\"OpenSansRegular\" />\n        <Setter Property=\"FontSize\" Value=\"14\" />\n        <Setter Property=\"VisualStateManager.VisualStateGroups\">\n            <VisualStateGroupList>\n                <VisualStateGroup x:Name=\"CommonStates\">\n                    <VisualState x:Name=\"Normal\" />\n                    <VisualState x:Name=\"Disabled\">\n                        <VisualState.Setters>\n                            <Setter Property=\"TextColor\" Value=\"{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}\" />\n                            <Setter Property=\"PlaceholderColor\" Value=\"{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}\" />\n                        </VisualState.Setters>\n                    </VisualState>\n                </VisualStateGroup>\n            </VisualStateGroupList>\n        </Setter>\n    </Style>\n\n    <Style TargetType=\"Shadow\">\n        <Setter Property=\"Radius\" Value=\"15\" />\n        <Setter Property=\"Opacity\" Value=\"0.5\" />\n        <Setter Property=\"Brush\" Value=\"{AppThemeBinding Light={StaticResource White}, Dark={StaticResource White}}\" />\n        <Setter Property=\"Offset\" Value=\"10,10\" />\n    </Style>\n\n    <Style TargetType=\"Slider\">\n        <Setter Property=\"MinimumTrackColor\" Value=\"{AppThemeBinding Light={StaticResource Primary}, Dark={StaticResource White}}\" />\n        <Setter Property=\"MaximumTrackColor\" Value=\"{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource Gray600}}\" />\n        <Setter Property=\"ThumbColor\" Value=\"{AppThemeBinding Light={StaticResource Primary}, Dark={StaticResource White}}\" />\n        <Setter Property=\"VisualStateManager.VisualStateGroups\">\n            <VisualStateGroupList>\n                <VisualStateGroup x:Name=\"CommonStates\">\n                    <VisualState x:Name=\"Normal\" />\n                    <VisualState x:Name=\"Disabled\">\n                        <VisualState.Setters>\n                            <Setter Property=\"MinimumTrackColor\" Value=\"{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}\"/>\n                            <Setter Property=\"MaximumTrackColor\" Value=\"{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}\"/>\n                            <Setter Property=\"ThumbColor\" Value=\"{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}\"/>\n                        </VisualState.Setters>\n                    </VisualState>\n                </VisualStateGroup>\n            </VisualStateGroupList>\n        </Setter>\n    </Style>\n\n    <Style TargetType=\"SwipeItem\">\n        <Setter Property=\"BackgroundColor\" Value=\"{AppThemeBinding Light={StaticResource White}, Dark={StaticResource Black}}\" />\n    </Style>\n\n    <Style TargetType=\"Switch\">\n        <Setter Property=\"OnColor\" Value=\"{AppThemeBinding Light={StaticResource Primary}, Dark={StaticResource White}}\" />\n        <Setter Property=\"ThumbColor\" Value=\"{StaticResource White}\" />\n        <Setter Property=\"VisualStateManager.VisualStateGroups\">\n            <VisualStateGroupList>\n                <VisualStateGroup x:Name=\"CommonStates\">\n                    <VisualState x:Name=\"Normal\" />\n                    <VisualState x:Name=\"Disabled\">\n                        <VisualState.Setters>\n                            <Setter Property=\"OnColor\" Value=\"{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}\" />\n                            <Setter Property=\"ThumbColor\" Value=\"{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}\" />\n                        </VisualState.Setters>\n                    </VisualState>\n                    <VisualState x:Name=\"On\">\n                        <VisualState.Setters>\n                            <Setter Property=\"OnColor\" Value=\"{AppThemeBinding Light={StaticResource Secondary}, Dark={StaticResource Gray200}}\" />\n                            <Setter Property=\"ThumbColor\" Value=\"{AppThemeBinding Light={StaticResource Primary}, Dark={StaticResource White}}\" />\n                        </VisualState.Setters>\n                    </VisualState>\n                    <VisualState x:Name=\"Off\">\n                        <VisualState.Setters>\n                            <Setter Property=\"ThumbColor\" Value=\"{AppThemeBinding Light={StaticResource Gray400}, Dark={StaticResource Gray500}}\" />\n                        </VisualState.Setters>\n                    </VisualState>\n                </VisualStateGroup>\n            </VisualStateGroupList>\n        </Setter>\n    </Style>\n\n    <Style TargetType=\"TimePicker\">\n        <Setter Property=\"TextColor\" Value=\"{AppThemeBinding Light={StaticResource Gray900}, Dark={StaticResource White}}\" />\n        <Setter Property=\"BackgroundColor\" Value=\"Transparent\"/>\n        <Setter Property=\"FontFamily\" Value=\"OpenSansRegular\"/>\n        <Setter Property=\"FontSize\" Value=\"14\"/>\n        <Setter Property=\"MinimumHeightRequest\" Value=\"44\"/>\n        <Setter Property=\"MinimumWidthRequest\" Value=\"44\"/>\n        <Setter Property=\"VisualStateManager.VisualStateGroups\">\n            <VisualStateGroupList>\n                <VisualStateGroup x:Name=\"CommonStates\">\n                    <VisualState x:Name=\"Normal\" />\n                    <VisualState x:Name=\"Disabled\">\n                        <VisualState.Setters>\n                            <Setter Property=\"TextColor\" Value=\"{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}\" />\n                        </VisualState.Setters>\n                    </VisualState>\n                </VisualStateGroup>\n            </VisualStateGroupList>\n        </Setter>\n    </Style>\n  \n    <!--\n    <Style TargetType=\"TitleBar\">\n        <Setter Property=\"MinimumHeightRequest\" Value=\"32\"/>\n        <Setter Property=\"VisualStateManager.VisualStateGroups\">\n            <VisualStateGroupList>\n                <VisualStateGroup x:Name=\"TitleActiveStates\">\n                    <VisualState x:Name=\"TitleBarTitleActive\">\n                        <VisualState.Setters>\n                            <Setter Property=\"BackgroundColor\" Value=\"Transparent\" />\n                            <Setter Property=\"ForegroundColor\" Value=\"{AppThemeBinding Light={StaticResource Black}, Dark={StaticResource White}}\" />\n                        </VisualState.Setters>\n                    </VisualState>\n                    <VisualState x:Name=\"TitleBarTitleInactive\">\n                        <VisualState.Setters>\n                            <Setter Property=\"BackgroundColor\" Value=\"{AppThemeBinding Light={StaticResource White}, Dark={StaticResource Black}}\" />\n                            <Setter Property=\"ForegroundColor\" Value=\"{AppThemeBinding Light={StaticResource Gray400}, Dark={StaticResource Gray500}}\" />\n                        </VisualState.Setters>\n                    </VisualState>\n                </VisualStateGroup>\n            </VisualStateGroupList>\n        </Setter>\n    </Style>\n    -->\n\n    <Style TargetType=\"Page\" ApplyToDerivedTypes=\"True\">\n        <Setter Property=\"Padding\" Value=\"0\"/>\n        <Setter Property=\"BackgroundColor\" Value=\"{AppThemeBinding Light={StaticResource White}, Dark={StaticResource OffBlack}}\" />\n    </Style>\n\n    <Style TargetType=\"Shell\" ApplyToDerivedTypes=\"True\">\n        <Setter Property=\"Shell.BackgroundColor\" Value=\"{AppThemeBinding Light={StaticResource White}, Dark={StaticResource OffBlack}}\" />\n        <Setter Property=\"Shell.ForegroundColor\" Value=\"{AppThemeBinding Light={StaticResource Black}, Dark={StaticResource SecondaryDarkText}}\" />\n        <Setter Property=\"Shell.TitleColor\" Value=\"{AppThemeBinding Light={StaticResource Black}, Dark={StaticResource SecondaryDarkText}}\" />\n        <Setter Property=\"Shell.DisabledColor\" Value=\"{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource Gray950}}\" />\n        <Setter Property=\"Shell.UnselectedColor\" Value=\"{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource Gray200}}\" />\n        <Setter Property=\"Shell.NavBarHasShadow\" Value=\"False\" />\n        <Setter Property=\"Shell.TabBarBackgroundColor\" Value=\"{AppThemeBinding Light={StaticResource White}, Dark={StaticResource Black}}\" />\n        <Setter Property=\"Shell.TabBarForegroundColor\" Value=\"{AppThemeBinding Light={StaticResource Magenta}, Dark={StaticResource White}}\" />\n        <Setter Property=\"Shell.TabBarTitleColor\" Value=\"{AppThemeBinding Light={StaticResource Magenta}, Dark={StaticResource White}}\" />\n        <Setter Property=\"Shell.TabBarUnselectedColor\" Value=\"{AppThemeBinding Light={StaticResource Gray900}, Dark={StaticResource Gray200}}\" />\n    </Style>\n\n    <Style TargetType=\"NavigationPage\">\n        <Setter Property=\"BarBackgroundColor\" Value=\"{AppThemeBinding Light={StaticResource White}, Dark={StaticResource OffBlack}}\" />\n        <Setter Property=\"BarTextColor\" Value=\"{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource White}}\" />\n        <Setter Property=\"IconColor\" Value=\"{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource White}}\" />\n    </Style>\n\n    <Style TargetType=\"TabbedPage\">\n        <Setter Property=\"BarBackgroundColor\" Value=\"{AppThemeBinding Light={StaticResource White}, Dark={StaticResource Gray950}}\" />\n        <Setter Property=\"BarTextColor\" Value=\"{AppThemeBinding Light={StaticResource Magenta}, Dark={StaticResource White}}\" />\n        <Setter Property=\"UnselectedTabColor\" Value=\"{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource Gray950}}\" />\n        <Setter Property=\"SelectedTabColor\" Value=\"{AppThemeBinding Light={StaticResource Gray950}, Dark={StaticResource Gray200}}\" />\n    </Style>\n\n</ResourceDictionary>\n"
  },
  {
    "path": "samples/Directory.Build.props",
    "content": "<Project>\n  <PropertyGroup>\n    <GenerateDocumentationFile>false</GenerateDocumentationFile>\n    <IsPackable>false</IsPackable>\n  </PropertyGroup>\n</Project>\n"
  },
  {
    "path": "src/BenchmarkDotNet/Analysers/AnalyserBase.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Linq;\nusing BenchmarkDotNet.Reports;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Analysers\n{\n    public abstract class AnalyserBase : IAnalyser\n    {\n        public abstract string Id { get; }\n\n        public IEnumerable<Conclusion> Analyse(Summary summary)\n        {\n            foreach (var conclusion in AnalyseSummary(summary))\n                yield return conclusion;\n            foreach (var report in summary.Reports)\n                foreach (var conclusion in AnalyseReport(report, summary))\n                    yield return conclusion;\n        }\n\n        [PublicAPI] protected virtual IEnumerable<Conclusion> AnalyseSummary(Summary summary) => [];\n        [PublicAPI] protected virtual IEnumerable<Conclusion> AnalyseReport(BenchmarkReport report, Summary summary) => [];\n\n        protected Conclusion CreateHint(string message, BenchmarkReport? report = null, bool mergeable = true)\n            => Conclusion.CreateHint(Id, message, report, mergeable);\n        protected Conclusion CreateWarning(string message, BenchmarkReport? report = null, bool mergeable = true)\n            => Conclusion.CreateWarning(Id, message, report, mergeable);\n        protected Conclusion CreateError(string message, BenchmarkReport? report = null, bool mergeable = true)\n            => Conclusion.CreateError(Id, message, report, mergeable);\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Analysers/BaselineCustomAnalyzer.cs",
    "content": "﻿using BenchmarkDotNet.Columns;\nusing BenchmarkDotNet.Reports;\nusing System.Collections.Generic;\nusing System.Linq;\nusing BenchmarkDotNet.Extensions;\n\nnamespace BenchmarkDotNet.Analysers\n{\n    public class BaselineCustomAnalyzer : AnalyserBase\n    {\n        public static readonly IAnalyser Default = new BaselineCustomAnalyzer();\n\n        public override string Id => nameof(BaselineCustomAnalyzer);\n\n        protected override IEnumerable<Conclusion> AnalyseSummary(Summary summary)\n        {\n            var columns = summary.GetColumns().Where(t => t.GetType().IsSubclassOf(typeof(BaselineCustomColumn)))\n                                              .Select(t => t.ColumnName)\n                                              .Distinct()\n                                              .ToArray();\n            if (columns.IsEmpty())\n                yield break;\n\n            var columnNames = string.Join(\", \", columns);\n\n            foreach (var benchmarkCase in summary.BenchmarksCases)\n            {\n                string? logicalGroupKey = summary.GetLogicalGroupKey(benchmarkCase);\n                var baseline = summary.GetBaseline(logicalGroupKey);\n                if (BaselineCustomColumn.ResultsAreInvalid(summary, benchmarkCase, baseline) == false)\n                    continue;\n\n                var message = \"A question mark '?' symbol indicates that it was not possible to compute the \" +\n                                $\"({columnNames}) column(s) because the baseline or benchmark could not be found, or \" +\n                                $\"the baseline value is too close to zero.\";\n\n                yield return Conclusion.CreateWarning(Id, message);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Analysers/CompositeAnalyser.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Collections.Immutable;\nusing System.Linq;\nusing BenchmarkDotNet.Reports;\n\nnamespace BenchmarkDotNet.Analysers\n{\n    public class CompositeAnalyser : IAnalyser\n    {\n        private readonly ImmutableHashSet<IAnalyser> analysers;\n\n        public CompositeAnalyser(ImmutableHashSet<IAnalyser> analysers) => this.analysers = analysers;\n\n        public string Id => nameof(CompositeAnalyser);\n\n        public IEnumerable<Conclusion> Analyse(Summary summary)\n            => analysers.SelectMany(analyser => analyser.Analyse(summary));\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Analysers/Conclusion.cs",
    "content": "﻿using System;\nusing BenchmarkDotNet.Reports;\n\nnamespace BenchmarkDotNet.Analysers\n{\n    // TODO: Find a better name\n    public sealed class Conclusion : IEquatable<Conclusion>\n    {\n        public string AnalyserId { get; }\n\n        public ConclusionKind Kind { get; }\n\n        public bool Mergeable { get; }\n\n        public string Message { get; }\n\n        public BenchmarkReport? Report { get; }\n\n        private Conclusion(string analyserId,\n                           ConclusionKind kind,\n                           string message,\n                           BenchmarkReport? report,\n                           bool mergeable)\n        {\n            AnalyserId = analyserId;\n            Kind = kind;\n            Message = message;\n            Report = report;\n            Mergeable = mergeable;\n        }\n\n        public static Conclusion CreateHint(string analyserId, string message, BenchmarkReport? report = null, bool mergeable = true)\n            => new Conclusion(analyserId, ConclusionKind.Hint, message, report, mergeable);\n\n        public static Conclusion CreateWarning(string analyserId, string message, BenchmarkReport? report = null, bool mergeable = true)\n            => new Conclusion(analyserId, ConclusionKind.Warning, message, report, mergeable);\n\n        public static Conclusion CreateError(string analyserId, string message, BenchmarkReport? report = null, bool mergeable = true)\n            => new Conclusion(analyserId, ConclusionKind.Error, message, report, mergeable);\n\n        public bool Equals(Conclusion? other)\n        {\n            if (ReferenceEquals(null, other))\n                return false;\n            if (ReferenceEquals(this, other))\n                return true;\n            if (!Mergeable && !other.Mergeable)\n                return string.Equals(AnalyserId, other.AnalyserId) && Kind == other.Kind && string.Equals(Report?.ToString(), other.Report?.ToString());\n            return string.Equals(AnalyserId, other.AnalyserId) && Kind == other.Kind && string.Equals(Message, other.Message);\n        }\n\n        public override bool Equals(object? obj)\n        {\n            if (ReferenceEquals(null, obj))\n                return false;\n            if (ReferenceEquals(this, obj))\n                return true;\n            return obj is Conclusion conclusion && Equals(conclusion);\n        }\n\n        public override int GetHashCode()\n        {\n            return Mergeable\n                ? HashCode.Combine(AnalyserId, Kind, Message)\n                : HashCode.Combine(AnalyserId, Kind, Report?.ToString());\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Analysers/ConclusionHelper.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing BenchmarkDotNet.Loggers;\n\nnamespace BenchmarkDotNet.Analysers\n{\n    public static class ConclusionHelper\n    {\n        public static void Print(ILogger logger, IEnumerable<Conclusion> conclusions)\n        {\n            PrintFiltered(conclusions, ConclusionKind.Error, \"Errors\", logger.WriteLineError);\n            PrintFiltered(conclusions, ConclusionKind.Warning, \"Warnings\", logger.WriteLineWarning);\n            PrintFiltered(conclusions, ConclusionKind.Hint, \"Hints\", logger.WriteLineHint);\n        }\n\n        private static void PrintFiltered(IEnumerable<Conclusion> conclusions, ConclusionKind kind, string title, Action<string> printLine)\n        {\n            var filtered = conclusions.Where(c => c.Kind == kind).ToArray();\n            if (filtered.Any())\n            {\n                printLine(\"\");\n                printLine($\"// * {title} *\");\n                foreach (var group in filtered.GroupBy(c => c.AnalyserId))\n                {\n                    printLine($\"{group.Key}\");\n                    var values = group.ToList();\n                    int maxTitleWidth = values.Max(c => GetTitle(c).Length);\n                    foreach (var conclusion in values)\n                        printLine(\"  \" + GetTitle(conclusion).PadRight(maxTitleWidth, ' ') + \" -> \" + conclusion.Message);\n                }\n            }\n        }\n\n        private static string GetTitle(Conclusion conclusion)\n        {\n            if (conclusion.Report == null)\n                return \"Summary\";\n            var b = conclusion.Report?.BenchmarkCase;\n            return b != null ? $\"{b.Descriptor.DisplayInfo}: {b.Job.Id}\" : \"[Summary]\";\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Analysers/ConclusionKind.cs",
    "content": "﻿namespace BenchmarkDotNet.Analysers\n{\n    public enum ConclusionKind\n    {\n        Error, Warning, Hint\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Analysers/EnvironmentAnalyser.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Linq;\nusing System.Reflection;\nusing System.Text;\n\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Portability;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Toolchains.InProcess.Emit;\nusing BenchmarkDotNet.Toolchains.InProcess.NoEmit;\n\nnamespace BenchmarkDotNet.Analysers\n{\n    public class EnvironmentAnalyser : AnalyserBase\n    {\n        public override string Id => \"Environment\";\n        public static readonly IAnalyser Default = new EnvironmentAnalyser();\n\n        private EnvironmentAnalyser()\n        {\n        }\n\n        protected override IEnumerable<Conclusion> AnalyseReport(BenchmarkReport report, Summary summary)\n        {\n            if (report.BenchmarkCase.Descriptor.Type.GetTypeInfo().Assembly.IsJitOptimizationDisabled().IsTrue())\n                yield return CreateWarning(\"Benchmark was built without optimization enabled (most probably a DEBUG configuration). Please, build it in RELEASE.\", report);\n        }\n\n        protected override IEnumerable<Conclusion> AnalyseSummary(Summary summary)\n        {\n            if (summary.HostEnvironmentInfo.HasAttachedDebugger)\n                yield return CreateWarning(\"Benchmark was executed with attached debugger\");\n\n            bool unexpectedExit = summary.Reports.SelectMany(x => x.ExecuteResults).Any(x => x.ExitCode != 0);\n            if (unexpectedExit)\n            {\n                var avProducts = summary.HostEnvironmentInfo.AntivirusProducts.Value;\n                if (avProducts.Any())\n                    yield return CreateWarning(CreateWarningAboutAntivirus(avProducts));\n            }\n\n            var vmHypervisor = summary.HostEnvironmentInfo.VirtualMachineHypervisor.Value;\n            if (vmHypervisor != null)\n            {\n                yield return CreateWarning($\"Benchmark was executed on the virtual machine with {vmHypervisor.Name} hypervisor. \" +\n                                           \"Virtualization can affect the measurement result.\");\n            }\n        }\n\n        private static string CreateWarningAboutAntivirus(ICollection<Antivirus> avProducts)\n        {\n            var sb = new StringBuilder(\"Detected error exit code from one of the benchmarks. \" +\n                                       \"It might be caused by following antivirus software:\");\n            sb.AppendLine();\n\n            foreach (var av in avProducts)\n                sb.AppendLine($\"        - {av}\");\n\n            sb.AppendLine($\"Use {nameof(InProcessEmitToolchain)} or {nameof(InProcessNoEmitToolchain)} to avoid new process creation.\");\n\n            return sb.ToString();\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Analysers/HideColumnsAnalyser.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Linq;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Reports;\n\nnamespace BenchmarkDotNet.Analysers\n{\n    public class HideColumnsAnalyser : AnalyserBase\n    {\n        public static readonly IAnalyser Default = new HideColumnsAnalyser();\n\n        public override string Id => nameof(HideColumnsAnalyser);\n\n        protected override IEnumerable<Conclusion> AnalyseSummary(Summary summary)\n        {\n            var hiddenColumns = summary.GetTable(summary.Style).Columns.Where(c => c.WasHidden).ToArray();\n\n            if (hiddenColumns.IsEmpty())\n                yield break;\n\n            var columnNames = string.Join(\", \", hiddenColumns.Select(c => c.OriginalColumn.ColumnName));\n\n            var message = $\"Hidden columns: {columnNames}\";\n            yield return CreateHint(message);\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Analysers/IAnalyser.cs",
    "content": "﻿using System.Collections.Generic;\nusing BenchmarkDotNet.Reports;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Analysers\n{\n    public interface IAnalyser\n    {\n        [PublicAPI] string Id { get; }\n        [PublicAPI] IEnumerable<Conclusion> Analyse(Summary summary);\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Analysers/MinIterationTimeAnalyser.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Linq;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Reports;\nusing Perfolizer.Horology;\n\nnamespace BenchmarkDotNet.Analysers\n{\n    public class MinIterationTimeAnalyser : AnalyserBase\n    {\n        private static readonly TimeInterval MinSufficientIterationTime = 100 * TimeInterval.Millisecond;\n\n        public override string Id => \"MinIterationTime\";\n        public static readonly IAnalyser Default = new MinIterationTimeAnalyser();\n\n        private MinIterationTimeAnalyser()\n        {\n        }\n\n        protected override IEnumerable<Conclusion> AnalyseReport(BenchmarkReport report, Summary summary)\n        {\n            var target = report.AllMeasurements.Where(m => m.Is(IterationMode.Workload, IterationStage.Actual)).ToArray();\n            if (target.IsEmpty())\n                yield break;\n            var minActualIterationTime = TimeInterval.FromNanoseconds(target.Min(m => m.Nanoseconds));\n            if (minActualIterationTime < MinSufficientIterationTime)\n                yield return CreateWarning($\"The minimum observed iteration time is {minActualIterationTime} which is very small. It's recommended to increase it to at least {MinSufficientIterationTime} using more operations.\", report);\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Analysers/MultimodalDistributionAnalyzer.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Globalization;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Reports;\nusing Perfolizer.Mathematics.Multimodality;\n\nnamespace BenchmarkDotNet.Analysers\n{\n    public class MultimodalDistributionAnalyzer : AnalyserBase\n    {\n        public static readonly IAnalyser Default = new MultimodalDistributionAnalyzer();\n\n        private MultimodalDistributionAnalyzer() { }\n\n        public override string Id => \"MultimodalDistribution\";\n\n        protected override IEnumerable<Conclusion> AnalyseReport(BenchmarkReport report, Summary summary)\n        {\n            var statistics = report.ResultStatistics;\n            if (statistics == null || statistics.N < EngineResolver.DefaultMinWorkloadIterationCount)\n                yield break;\n\n            double mValue = MValueCalculator.Calculate(statistics.Sample.Values);\n            if (mValue > 4.2)\n                yield return Create(\"is multimodal\", mValue, report, summary.GetCultureInfo());\n            else if (mValue > 3.2)\n                yield return Create(\"is bimodal\", mValue, report, summary.GetCultureInfo());\n            else if (mValue > 2.8)\n                yield return Create(\"can have several modes\", mValue, report, summary.GetCultureInfo());\n        }\n\n        private Conclusion Create(string kind, double mValue, BenchmarkReport? report, CultureInfo cultureInfo)\n            => CreateWarning($\"It seems that the distribution {kind} (mValue = {mValue.ToString(\"0.##\", cultureInfo)})\", report);\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Analysers/OutliersAnalyser.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Globalization;\nusing System.Linq;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Helpers;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Reports;\nusing JetBrains.Annotations;\nusing Perfolizer.Horology;\n\nnamespace BenchmarkDotNet.Analysers\n{\n    public class OutliersAnalyser : AnalyserBase\n    {\n        public override string Id => \"Outliers\";\n        public static readonly IAnalyser Default = new OutliersAnalyser();\n\n        private OutliersAnalyser() { }\n\n        protected override IEnumerable<Conclusion> AnalyseReport(BenchmarkReport report, Summary summary)\n        {\n            var workloadActual = report.AllMeasurements.Where(m => m.Is(IterationMode.Workload, IterationStage.Actual)).ToArray();\n            if (workloadActual.IsEmpty())\n                yield break;\n            var outlierMode = report.BenchmarkCase.Job.ResolveValue(AccuracyMode.OutlierModeCharacteristic, EngineResolver.Instance); // TODO: improve\n            var statistics = workloadActual.GetStatistics();\n            var allOutliers = statistics.AllOutliers;\n            var actualOutliers = statistics.GetActualOutliers(outlierMode);\n\n            var cultureInfo = summary.GetCultureInfo();\n            if (allOutliers.Any())\n                yield return CreateHint(GetMessage(actualOutliers, allOutliers, statistics.LowerOutliers, statistics.UpperOutliers, cultureInfo), report);\n        }\n\n        /// <summary>\n        /// Returns a nice message which can be displayed in the summary.\n        /// </summary>\n        /// <param name=\"actualOutliers\">Actual outliers which were removed from the statistics</param>\n        /// <param name=\"allOutliers\">All outliers which present in the distribution (lower and upper)</param>\n        /// <param name=\"lowerOutliers\">All lower outliers</param>\n        /// <param name=\"upperOutliers\">All upper outliers</param>\n        /// <param name=\"cultureInfo\">CultureInfo</param>\n        /// <returns>The message</returns>\n        [PublicAPI, Pure]\n        public static string GetMessage(double[] actualOutliers, double[] allOutliers, double[] lowerOutliers, double[] upperOutliers, CultureInfo cultureInfo)\n        {\n            if (allOutliers.Length == 0)\n                return string.Empty;\n\n            string Format(int n, string verb)\n            {\n                string words = n == 1 ? \"outlier  was \" : \"outliers were\";\n                return $\"{n} {words} {verb}\";\n            }\n\n            var rangeMessages = new List<string?> { GetRangeMessage(lowerOutliers), GetRangeMessage(upperOutliers) };\n            rangeMessages.RemoveAll(string.IsNullOrEmpty);\n            string rangeMessage = rangeMessages.Any()\n                ? \" (\" + string.Join(\", \", rangeMessages) + \")\"\n                : string.Empty;\n\n            if (actualOutliers.Length == allOutliers.Length)\n                return Format(actualOutliers.Length, \"removed\") + rangeMessage;\n            if (actualOutliers.Length == 0)\n                return Format(allOutliers.Length, \"detected\") + rangeMessage;\n            return Format(actualOutliers.Length, \"removed\") + \", \" + Format(allOutliers.Length, \"detected\") + rangeMessage;\n        }\n\n        private static string? GetRangeMessage(double[] values)\n        {\n            string Format(double value) => TimeInterval.FromNanoseconds(value).ToDefaultString(\"N2\");\n\n            return values.Length switch\n            {\n                0 => null,\n                1 => Format(values.First()),\n                2 => Format(values.Min()) + \", \" + Format(values.Max()),\n                _ => Format(values.Min()) + \"..\" + Format(values.Max())\n            };\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Analysers/RuntimeErrorAnalyser.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Linq;\nusing BenchmarkDotNet.Reports;\n\nnamespace BenchmarkDotNet.Analysers\n{\n    public class RuntimeErrorAnalyser : AnalyserBase\n    {\n        public override string Id => \"RuntimeError\";\n        public static readonly IAnalyser Default = new RuntimeErrorAnalyser();\n\n        private RuntimeErrorAnalyser()\n        {\n        }\n\n        protected override IEnumerable<Conclusion> AnalyseReport(BenchmarkReport report, Summary summary)\n        {\n            foreach (string error in report.ExecuteResults.SelectMany(r => r.Errors))\n                yield return CreateError(error, report);\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Analysers/ZeroMeasurementAnalyser.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Linq;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Reports;\nusing Perfolizer.Horology;\n\nnamespace BenchmarkDotNet.Analysers\n{\n    public class ZeroMeasurementAnalyser : AnalyserBase\n    {\n        public override string Id => \"ZeroMeasurement\";\n\n        public static readonly IAnalyser Default = new ZeroMeasurementAnalyser();\n\n        private static readonly TimeInterval FallbackCpuResolutionValue = TimeInterval.FromNanoseconds(0.2d);\n\n        private ZeroMeasurementAnalyser() { }\n\n        protected override IEnumerable<Conclusion> AnalyseReport(BenchmarkReport report, Summary summary)\n        {\n            var currentFrequency = summary.HostEnvironmentInfo.Cpu.Value.MaxFrequency();\n            if (!currentFrequency.HasValue || currentFrequency <= 0)\n                currentFrequency = FallbackCpuResolutionValue.ToFrequency();\n\n            var entire = report.AllMeasurements;\n            var overheadMeasurements = entire.Where(m => m.Is(IterationMode.Overhead, IterationStage.Actual)).ToArray();\n            var workloadMeasurements = entire.Where(m => m.Is(IterationMode.Workload, IterationStage.Actual)).ToArray();\n            if (workloadMeasurements.IsEmpty())\n                yield break;\n\n            var workloadSample = workloadMeasurements.GetStatistics().Sample;\n            var threshold = currentFrequency.Value.ToResolution().Nanoseconds / 2;\n\n            var zeroMeasurement = overheadMeasurements.Any()\n                ? ZeroMeasurementHelper.AreIndistinguishable(workloadSample, overheadMeasurements.GetStatistics().Sample)\n                : ZeroMeasurementHelper.IsNegligible(workloadSample, threshold);\n\n            if (zeroMeasurement)\n                yield return CreateWarning(\"The method duration is indistinguishable from the empty method duration\",\n                    report, false);\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Analysers/ZeroMeasurementHelper.cs",
    "content": "using BenchmarkDotNet.Mathematics;\nusing Perfolizer;\nusing Perfolizer.Horology;\nusing Perfolizer.Mathematics.Common;\nusing Perfolizer.Mathematics.GenericEstimators;\nusing Perfolizer.Mathematics.SignificanceTesting;\nusing Perfolizer.Mathematics.SignificanceTesting.MannWhitney;\nusing Perfolizer.Metrology;\nusing Pragmastat;\nusing Pragmastat.Estimators;\n\nnamespace BenchmarkDotNet.Analysers\n{\n    internal static class ZeroMeasurementHelper\n    {\n        public static bool IsNegligible(Sample results, double threshold) => CenterEstimator.Instance.Estimate(results) < threshold;\n        public static bool IsNoticeable(Sample results, double threshold) => !IsNegligible(results, threshold);\n\n        public static bool AreIndistinguishable(double[] workload, double[] overhead, Threshold? threshold = null)\n        {\n            var workloadSample = new Sample(workload, TimeUnit.Nanosecond);\n            var overheadSample = new Sample(overhead, TimeUnit.Nanosecond);\n            return AreIndistinguishable(workloadSample, overheadSample, threshold);\n        }\n\n        public static bool AreIndistinguishable(Sample workload, Sample overhead, Threshold? threshold = null)\n        {\n            threshold ??= MathHelper.DefaultThreshold;\n            var tost = new SimpleEquivalenceTest(MannWhitneyTest.Instance);\n            if (workload.Size == 1 || overhead.Size == 1)\n                return false;\n            return tost.Perform(workload, overhead, threshold, SignificanceLevel.P1E5) == ComparisonResult.Indistinguishable;\n        }\n\n        public static bool AreDistinguishable(double[] workload, double[] overhead, Threshold? threshold = null) =>\n            !AreIndistinguishable(workload, overhead, threshold);\n\n        public static bool AreDistinguishable(Sample workload, Sample overhead, Threshold? threshold = null) =>\n            !AreIndistinguishable(workload, overhead, threshold);\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/ArtifactsPathAttribute.cs",
    "content": "﻿using System;\nusing BenchmarkDotNet.Configs;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    [PublicAPI]\n    [AttributeUsage(AttributeTargets.Class)]\n    public class ArtifactsPathAttribute : Attribute, IConfigSource\n    {\n        public string Value { get; }\n        public IConfig Config { get; }\n\n        public ArtifactsPathAttribute(string value)\n        {\n            Value = value;\n            Config = ManualConfig.CreateEmpty().WithArtifactsPath(value);\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/CategoryDiscovererAttribute.cs",
    "content": "using System;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Running;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    [AttributeUsage(AttributeTargets.Class)]\n    public class CategoryDiscovererAttribute : Attribute, IConfigSource\n    {\n        public CategoryDiscovererAttribute(bool inherit = true)\n        {\n            Config = ManualConfig.CreateEmpty().WithCategoryDiscoverer(new DefaultCategoryDiscoverer(inherit));\n        }\n\n        public IConfig Config { get; }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Columns/AllStatisticsColumnAttribute.cs",
    "content": "﻿using BenchmarkDotNet.Columns;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    [PublicAPI]\n    public class AllStatisticsColumnAttribute : ColumnConfigBaseAttribute\n    {\n        public AllStatisticsColumnAttribute() : base(StatisticColumn.AllStatistics)\n        {\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Columns/BaselineColumnAttribute.cs",
    "content": "﻿using BenchmarkDotNet.Columns;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    public class BaselineColumnAttribute : ColumnConfigBaseAttribute\n    {\n        public BaselineColumnAttribute() : base(BaselineColumn.Default) { }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Columns/CategoriesColumnAttribute.cs",
    "content": "using BenchmarkDotNet.Columns;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    public class CategoriesColumnAttribute : ColumnConfigBaseAttribute\n    {\n        public CategoriesColumnAttribute() : base(CategoriesColumn.Default) { }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Columns/ColumnConfigBaseAttribute.cs",
    "content": "﻿using System;\nusing BenchmarkDotNet.Columns;\nusing BenchmarkDotNet.Configs;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Assembly)]\n    public abstract class ColumnConfigBaseAttribute : Attribute, IConfigSource\n    {\n        // CLS-Compliant Code requires a constructor without an array in the argument list\n        [PublicAPI]\n        protected ColumnConfigBaseAttribute()\n        {\n            Config = ManualConfig.CreateEmpty();\n        }\n\n        protected ColumnConfigBaseAttribute(params IColumn[] columns)\n        {\n            Config = ManualConfig.CreateEmpty().AddColumn(columns);\n        }\n\n        public IConfig Config { get; }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Columns/ConfidenceIntervalErrorColumnAttribute.cs",
    "content": "﻿using BenchmarkDotNet.Columns;\nusing JetBrains.Annotations;\nusing Perfolizer.Mathematics.Common;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    [PublicAPI]\n    public class ConfidenceIntervalErrorColumnAttribute : ColumnConfigBaseAttribute\n    {\n        public ConfidenceIntervalErrorColumnAttribute() : base(StatisticColumn.CiError(ConfidenceLevel.L999)) { }\n        public ConfidenceIntervalErrorColumnAttribute(ConfidenceLevel level) : base(StatisticColumn.CiError(level)) { }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Columns/IterationsColumnAttribute.cs",
    "content": "﻿using BenchmarkDotNet.Columns;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    [PublicAPI]\n    public class IterationsColumnAttribute : ColumnConfigBaseAttribute\n    {\n        public IterationsColumnAttribute() : base(StatisticColumn.Iterations) { }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Columns/KurtosisColumnAttribute.cs",
    "content": "﻿using BenchmarkDotNet.Columns;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    public class KurtosisColumnAttribute : ColumnConfigBaseAttribute\n    {\n        public KurtosisColumnAttribute() : base(StatisticColumn.Kurtosis)\n        {\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Columns/LogicalGroupColumnAttribute.cs",
    "content": "﻿using BenchmarkDotNet.Columns;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    public class LogicalGroupColumnAttribute : ColumnConfigBaseAttribute\n    {\n        public LogicalGroupColumnAttribute() : base(LogicalGroupColumn.Default) { }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Columns/MValueColumnAttribute.cs",
    "content": "﻿using BenchmarkDotNet.Columns;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    /// <summary>\n    /// Prints mvalue.\n    /// See http://www.brendangregg.com/FrequencyTrails/modes.html\n    /// </summary>\n    [PublicAPI]\n    public class MValueColumnAttribute: ColumnConfigBaseAttribute\n    {\n        public MValueColumnAttribute() : base(StatisticColumn.MValue)\n        {\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Columns/MaxColumnAttribute.cs",
    "content": "﻿using BenchmarkDotNet.Columns;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    public class MaxColumnAttribute : ColumnConfigBaseAttribute\n    {\n        public MaxColumnAttribute() : base(StatisticColumn.Max)\n        {\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Columns/MeanColumnAttribute.cs",
    "content": "﻿using BenchmarkDotNet.Columns;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    public class MeanColumnAttribute : ColumnConfigBaseAttribute\n    {\n        public MeanColumnAttribute() : base(StatisticColumn.Mean)\n        {\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Columns/MedianColumnAttribute.cs",
    "content": "﻿using BenchmarkDotNet.Columns;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    public class MedianColumnAttribute : ColumnConfigBaseAttribute\n    {\n        public MedianColumnAttribute() : base(StatisticColumn.Median)\n        {\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Columns/MinColumnAttribute.cs",
    "content": "﻿using BenchmarkDotNet.Columns;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    public class MinColumnAttribute : ColumnConfigBaseAttribute\n    {\n        public MinColumnAttribute() : base(StatisticColumn.Min)\n        {\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Columns/NamespaceColumnAttribute.cs",
    "content": "﻿using BenchmarkDotNet.Columns;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    /// <summary>\n    /// Add a column with the target method namespace.\n    /// </summary>\n    [PublicAPI]\n    public class NamespaceColumnAttribute : ColumnConfigBaseAttribute\n    {\n        public NamespaceColumnAttribute() : base(TargetMethodColumn.Namespace)\n        {\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Columns/OperationsPerSecondAttribute.cs",
    "content": "using BenchmarkDotNet.Columns;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    public class OperationsPerSecondAttribute : ColumnConfigBaseAttribute\n    {\n        public OperationsPerSecondAttribute() : base(StatisticColumn.OperationsPerSecond) { }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Columns/Q1ColumnAttribute.cs",
    "content": "﻿using BenchmarkDotNet.Columns;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    public class Q1ColumnAttribute : ColumnConfigBaseAttribute\n    {\n        public Q1ColumnAttribute() : base(StatisticColumn.Q1)\n        {\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Columns/Q3ColumnAttribute.cs",
    "content": "using BenchmarkDotNet.Columns;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    public class Q3ColumnAttribute : ColumnConfigBaseAttribute\n    {\n        public Q3ColumnAttribute() : base(StatisticColumn.Q3)\n        {\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Columns/RankColumnAttribute.cs",
    "content": "﻿using System;\nusing BenchmarkDotNet.Columns;\nusing BenchmarkDotNet.Mathematics;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Assembly, AllowMultiple = true)]\n    public class RankColumnAttribute : ColumnConfigBaseAttribute\n    {\n        public RankColumnAttribute(NumeralSystem system = NumeralSystem.Arabic) : base(new RankColumn(system))\n        {\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Columns/SkewnessColumnAttribute.cs",
    "content": "﻿using BenchmarkDotNet.Columns;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    public class SkewnessColumnAttribute : ColumnConfigBaseAttribute\n    {\n        public SkewnessColumnAttribute() : base(StatisticColumn.Skewness)\n        {\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Columns/StdDevColumnAttribute.cs",
    "content": "﻿using BenchmarkDotNet.Columns;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    [PublicAPI]\n    public class StdDevColumnAttribute : ColumnConfigBaseAttribute\n    {\n        public StdDevColumnAttribute() : base(StatisticColumn.StdDev)\n        {\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Columns/StdErrorColumnAttribute.cs",
    "content": "﻿using BenchmarkDotNet.Columns;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    [PublicAPI]\n    public class StdErrorColumnAttribute() : ColumnConfigBaseAttribute(StatisticColumn.StdErr) { }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Columns/WelchTTestPValueColumnAttribute.cs",
    "content": "﻿using System;\nusing BenchmarkDotNet.Columns;\nusing JetBrains.Annotations;\nusing Perfolizer.Mathematics.Common;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    [PublicAPI]\n    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Assembly, AllowMultiple = true)]\n    public class StatisticalTestColumnAttribute : ColumnConfigBaseAttribute\n    {\n        public StatisticalTestColumnAttribute() : base(StatisticalTestColumn.Create(\"10%\", null)) { }\n\n        public StatisticalTestColumnAttribute(string threshold) : base(StatisticalTestColumn.Create(threshold, null)) { }\n\n        public StatisticalTestColumnAttribute(string threshold, SignificanceLevel significanceLevel)\n            : base(StatisticalTestColumn.Create(threshold, significanceLevel)) { }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/ConfigAttribute.cs",
    "content": "﻿using System;\nusing BenchmarkDotNet.Configs;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Assembly)]\n    public class ConfigAttribute : Attribute, IConfigSource\n    {\n        public IConfig Config { get; }\n\n        public ConfigAttribute(Type type) => Config = (IConfig)Activator.CreateInstance(type)!;\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/DisassemblyDiagnoserAttribute.cs",
    "content": "using System;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Diagnosers;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    [AttributeUsage(AttributeTargets.Class)]\n    public class DisassemblyDiagnoserAttribute : Attribute, IConfigSource\n    {\n        /// <param name=\"maxDepth\">Includes called methods to given level. 1 by default, indexed from 1. To print just the benchmark set it to 0.</param>\n        /// <param name=\"syntax\">The disassembly syntax. MASM is the default.</param>\n        /// <param name=\"printSource\">C#|F#|VB source code will be printed. False by default.</param>\n        /// <param name=\"printInstructionAddresses\">Print instruction addresses. False by default</param>\n        /// <param name=\"exportGithubMarkdown\">Exports to GitHub markdown. True by default.</param>\n        /// <param name=\"exportHtml\">Exports to HTML with clickable links. False by default.</param>\n        /// <param name=\"exportCombinedDisassemblyReport\">Exports all benchmarks to a single HTML report. Makes it easy to compare different runtimes or methods (each becomes a column in HTML table).</param>\n        /// <param name=\"exportDiff\">Exports a diff of the assembly code to the Github markdown format. False by default.</param>\n        /// <param name=\"filters\">Glob patterns applied to full method signatures by the the disassembler.</param>\n        /// <param name=\"runInHost\">\n        /// If <see langword=\"true\"/>, disassembly will be ran in the host process; otherwise it will be ran in the benchmark process.\n        /// Requires host and benchmark processes to target the same platform (must have the same bit-ness) for CoreCLR.\n        /// </param>\n        public DisassemblyDiagnoserAttribute(\n            int maxDepth = 1,\n            DisassemblySyntax syntax = DisassemblySyntax.Masm,\n            bool printSource = false,\n            bool printInstructionAddresses = false,\n            bool exportGithubMarkdown = true,\n            bool exportHtml = false,\n            bool exportCombinedDisassemblyReport = false,\n            bool exportDiff = false,\n            bool runInHost = false,\n            params string[] filters)\n        {\n            Config = ManualConfig.CreateEmpty().AddDiagnoser(\n                new DisassemblyDiagnoser(\n                    new DisassemblyDiagnoserConfig(\n                        maxDepth: maxDepth,\n                        syntax: syntax,\n                        filters: filters,\n                        printSource: printSource,\n                        printInstructionAddresses: printInstructionAddresses,\n                        exportGithubMarkdown: exportGithubMarkdown,\n                        exportHtml: exportHtml,\n                        exportCombinedDisassemblyReport: exportCombinedDisassemblyReport,\n                        exportDiff: exportDiff,\n                        runInHost: runInHost)));\n        }\n\n        // CLS-Compliant Code requires a constructor without an array in the argument list\n        protected DisassemblyDiagnoserAttribute()\n        {\n            Config = ManualConfig.CreateEmpty().AddDiagnoser(\n                new DisassemblyDiagnoser(\n                    new DisassemblyDiagnoserConfig()));\n        }\n\n        public IConfig Config { get; }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/EventPipeProfilerAttribute.cs",
    "content": "using System;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Diagnosers;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    [AttributeUsage(AttributeTargets.Class)]\n    public class EventPipeProfilerAttribute : Attribute, IConfigSource\n    {\n        public IConfig Config { get; }\n\n        public EventPipeProfilerAttribute(EventPipeProfile profile)\n        {\n            Config = ManualConfig.CreateEmpty().AddDiagnoser(new EventPipeProfiler(profile));\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/ExceptionDiagnoserAttribute.cs",
    "content": "﻿using BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Diagnosers;\nusing System;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    [AttributeUsage(AttributeTargets.Class)]\n    public class ExceptionDiagnoserAttribute : Attribute, IConfigSource\n    {\n        public IConfig Config { get; }\n\n        /// <param name=\"displayExceptionsIfZeroValue\">Display Exceptions column. True by default.</param>\n        public ExceptionDiagnoserAttribute(bool displayExceptionsIfZeroValue = true)\n        {\n            Config = ManualConfig.CreateEmpty().AddDiagnoser(new ExceptionDiagnoser(new ExceptionDiagnoserConfig(displayExceptionsIfZeroValue)));\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/ExceptionDiagnoserConfig.cs",
    "content": "﻿using JetBrains.Annotations;\nusing System;\nusing System.Collections.Generic;\nusing System.Text;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    public class ExceptionDiagnoserConfig\n    {\n        /// <param name=\"displayExceptionsIfZeroValue\">Determines whether the Exceptions column is displayed when its value is not calculated. True by default.</param>\n\n        [PublicAPI]\n        public ExceptionDiagnoserConfig(bool displayExceptionsIfZeroValue = true)\n        {\n            DisplayExceptionsIfZeroValue = displayExceptionsIfZeroValue;\n        }\n\n        public bool DisplayExceptionsIfZeroValue { get; }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Exporters/AsciiDocExporterAttribute.cs",
    "content": "﻿using BenchmarkDotNet.Exporters;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    public class AsciiDocExporterAttribute : ExporterConfigBaseAttribute\n    {\n        public AsciiDocExporterAttribute() : base(DefaultExporters.AsciiDoc)\n        {\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Exporters/CsvExporterAttribute.cs",
    "content": "﻿using BenchmarkDotNet.Exporters.Csv;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    public class CsvExporterAttribute : ExporterConfigBaseAttribute\n    {\n        public CsvExporterAttribute(CsvSeparator separator = CsvSeparator.CurrentCulture) : base(new CsvExporter(separator))\n        {\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Exporters/CsvMeasurementsExporterAttribute.cs",
    "content": "﻿using BenchmarkDotNet.Exporters.Csv;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    public class CsvMeasurementsExporterAttribute : ExporterConfigBaseAttribute\n    {\n        public CsvMeasurementsExporterAttribute(CsvSeparator separator = CsvSeparator.CurrentCulture) : base(new CsvMeasurementsExporter(separator))\n        {\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Exporters/ExporterConfigBaseAttribute.cs",
    "content": "﻿using System;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Exporters;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Assembly)]\n    public class ExporterConfigBaseAttribute : Attribute, IConfigSource\n    {\n        // CLS-Compliant Code requires a constructor without an array in the argument list\n        [PublicAPI]\n        protected ExporterConfigBaseAttribute()\n        {\n            Config = ManualConfig.CreateEmpty();\n        }\n\n        protected ExporterConfigBaseAttribute(params IExporter[] exporters)\n        {\n            Config = ManualConfig.CreateEmpty().AddExporter(exporters);\n        }\n\n        public IConfig Config { get; }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Exporters/HtmlExporterAttribute.cs",
    "content": "﻿using BenchmarkDotNet.Exporters;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    public class HtmlExporterAttribute : ExporterConfigBaseAttribute\n    {\n        public HtmlExporterAttribute() : base(DefaultExporters.Html)\n        {\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Exporters/JsonExporterAttribute.cs",
    "content": "﻿using System;\nusing BenchmarkDotNet.Exporters;\nusing BenchmarkDotNet.Exporters.Json;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Assembly, AllowMultiple = true)]\n    public class JsonExporterAttribute : ExporterConfigBaseAttribute\n    {\n        private JsonExporterAttribute(IExporter exporter) : base(exporter)\n        {\n        }\n\n        public JsonExporterAttribute(string fileNameSuffix = \"\", bool indentJson = false, bool excludeMeasurements = false)\n            : this(new JsonExporter(fileNameSuffix, indentJson, excludeMeasurements))\n        {\n        }\n\n        public class BriefAttribute : JsonExporterAttribute\n        {\n            public BriefAttribute() : base(JsonExporter.Brief)\n            {\n            }\n        }\n\n        public class Full : JsonExporterAttribute\n        {\n            public Full() : base(JsonExporter.Full)\n            {\n            }\n        }\n\n        public class BriefCompressed : JsonExporterAttribute\n        {\n            public BriefCompressed() : base(JsonExporter.BriefCompressed)\n            {\n            }\n        }\n\n        public class FullCompressed : JsonExporterAttribute\n        {\n            public FullCompressed() : base(JsonExporter.FullCompressed)\n            {\n            }\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Exporters/MarkdownExporterAttribute.cs",
    "content": "﻿using BenchmarkDotNet.Exporters;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    // TODO: Find a better way to introduce dialects in the attribute\n    [PublicAPI]\n    public class MarkdownExporterAttribute : ExporterConfigBaseAttribute\n    {\n        public MarkdownExporterAttribute() : base(MarkdownExporter.Default)\n        {\n        }\n\n        public class Default : ExporterConfigBaseAttribute\n        {\n            public Default() : base(MarkdownExporter.Default)\n            {\n            }\n        }\n\n        public class GitHub : ExporterConfigBaseAttribute\n        {\n            public GitHub() : base(MarkdownExporter.GitHub)\n            {\n            }\n        }\n\n        public class StackOverflow : ExporterConfigBaseAttribute\n        {\n            public StackOverflow() : base(MarkdownExporter.StackOverflow)\n            {\n            }\n        }\n\n        public class Atlassian : ExporterConfigBaseAttribute\n        {\n            public Atlassian() : base(MarkdownExporter.Atlassian)\n            {\n            }\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Exporters/OpenMetricsExporterAttribute.cs",
    "content": "﻿using BenchmarkDotNet.Exporters;\nusing BenchmarkDotNet.Exporters.OpenMetrics;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    [PublicAPI]\n    public class OpenMetricsExporterAttribute : ExporterConfigBaseAttribute\n    {\n        public OpenMetricsExporterAttribute() : base(OpenMetricsExporter.Default)\n        {\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Exporters/PerfonarExporterAttribute.cs",
    "content": "using System;\nusing BenchmarkDotNet.Exporters;\n\nnamespace BenchmarkDotNet.Attributes;\n\n/// <summary>\n/// IMPORTANT: Not fully implemented yet\n/// </summary>\n[AttributeUsage(AttributeTargets.Class | AttributeTargets.Assembly, AllowMultiple = true)]\ninternal class PerfonarExporterAttribute() : ExporterConfigBaseAttribute(new PerfonarJsonExporter(), new PerfonarMdExporter());"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Exporters/PlainExporterAttribute.cs",
    "content": "﻿using BenchmarkDotNet.Exporters;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    public class PlainExporterAttribute : ExporterConfigBaseAttribute\n    {\n        public PlainExporterAttribute() : base(DefaultExporters.Plain)\n        {\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Exporters/RPlotExporterAttribute.cs",
    "content": "using BenchmarkDotNet.Exporters;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    public class RPlotExporterAttribute : ExporterConfigBaseAttribute\n    {\n        public RPlotExporterAttribute() : base(DefaultExporters.RPlot)\n        {\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Exporters/XmlExporterAttribute.cs",
    "content": "﻿using System;\nusing BenchmarkDotNet.Exporters;\nusing BenchmarkDotNet.Exporters.Xml;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Assembly, AllowMultiple = true)]\n    public class XmlExporterAttribute : ExporterConfigBaseAttribute\n    {\n        private XmlExporterAttribute(IExporter exporter) : base(exporter)\n        {\n        }\n\n        public XmlExporterAttribute(string fileNameSuffix = \"\", bool indentXml = false, bool excludeMeasurements = false)\n            : this(new XmlExporter(fileNameSuffix, indentXml, excludeMeasurements))\n        {\n        }\n\n        public class Brief : XmlExporterAttribute\n        {\n            public Brief() : base(XmlExporter.Brief)\n            {\n            }\n        }\n\n        public class Full : XmlExporterAttribute\n        {\n            public Full() : base(XmlExporter.Full)\n            {\n            }\n        }\n\n        public class BriefCompressed : XmlExporterAttribute\n        {\n            public BriefCompressed() : base(XmlExporter.BriefCompressed)\n            {\n            }\n        }\n\n        public class FullCompressed : XmlExporterAttribute\n        {\n            public FullCompressed() : base(XmlExporter.FullCompressed)\n            {\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Filters/AllCategoriesFilterAttribute.cs",
    "content": "using BenchmarkDotNet.Filters;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    [PublicAPI]\n    public class AllCategoriesFilterAttribute : FilterConfigBaseAttribute\n    {\n        // CLS-Compliant Code requires a constructor without an array in the argument list\n        public AllCategoriesFilterAttribute() { }\n\n        public AllCategoriesFilterAttribute(params string[] targetCategories) : base(new AllCategoriesFilter(targetCategories)) { }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Filters/AnyCategoriesFilterAttribute.cs",
    "content": "using BenchmarkDotNet.Filters;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    public class AnyCategoriesFilterAttribute : FilterConfigBaseAttribute\n    {\n        // CLS-Compliant Code requires a constructor without an array in the argument list\n        [PublicAPI]\n        public AnyCategoriesFilterAttribute() { }\n\n        public AnyCategoriesFilterAttribute(params string[] targetCategories) : base(new AnyCategoriesFilter(targetCategories)) { }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Filters/AotFilterAttribute.cs",
    "content": "﻿using BenchmarkDotNet.Filters;\n\nnamespace BenchmarkDotNet.Attributes.Filters\n{\n    public class AotFilterAttribute : FilterConfigBaseAttribute\n    {\n        public AotFilterAttribute(string? reason = null)\n            : base(new SimpleFilter(benchmark => !benchmark.GetRuntime().IsAOT))\n        {\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Filters/FilterConfigBaseAttribute.cs",
    "content": "using System;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Filters;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Assembly)]\n    public abstract class FilterConfigBaseAttribute : Attribute, IConfigSource\n    {\n        // CLS-Compliant Code requires a constructor without an array in the argument list\n        protected FilterConfigBaseAttribute()\n        {\n            Config = ManualConfig.CreateEmpty();\n        }\n\n        protected FilterConfigBaseAttribute(params IFilter[] filters)\n        {\n            Config = ManualConfig.CreateEmpty().AddFilter(filters);\n        }\n\n        public IConfig Config { get; }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Filters/OperatingSystemsArchitectureFilterAttribute.cs",
    "content": "﻿using System.Linq;\nusing BenchmarkDotNet.Filters;\nusing JetBrains.Annotations;\nusing System.Runtime.InteropServices;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    [PublicAPI]\n    public class OperatingSystemsArchitectureFilterAttribute : FilterConfigBaseAttribute\n    {\n        // CLS-Compliant Code requires a constructor without an array in the argument list\n        public OperatingSystemsArchitectureFilterAttribute() { }\n\n        /// <param name=\"allowed\">if set to true, the architectures are enabled, if set to false, disabled</param>\n        /// <param name=\"architectures\">the architecture(s) for which the filter should be applied</param>\n        public OperatingSystemsArchitectureFilterAttribute(bool allowed, params Architecture[] architectures)\n            : base(new SimpleFilter(_ =>\n            {\n                return allowed\n                    ? architectures.Any(architecture => RuntimeInformation.OSArchitecture == architecture)\n                    : architectures.All(architecture => RuntimeInformation.OSArchitecture != architecture);\n            }))\n        {\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Filters/OperatingSystemsFilterAttribute.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing BenchmarkDotNet.Filters;\nusing JetBrains.Annotations;\nusing System.Runtime.InteropServices;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    public enum OS : byte\n    {\n        Windows,\n        Linux,\n        macOS,\n        /// <summary>\n        /// WebAssembly\n        /// </summary>\n        Browser\n    }\n\n    [PublicAPI]\n    public class OperatingSystemsFilterAttribute : FilterConfigBaseAttribute\n    {\n        private static readonly OSPlatform browser = OSPlatform.Create(\"BROWSER\");\n\n        // CLS-Compliant Code requires a constructor without an array in the argument list\n        public OperatingSystemsFilterAttribute() { }\n\n        /// <param name=\"allowed\">if set to true, the OSes belonging to platforms are enabled, if set to false, disabled</param>\n        /// <param name=\"platforms\">the platform(s) for which the filter should be applied</param>\n        public OperatingSystemsFilterAttribute(bool allowed, params OS[] platforms)\n            : base(new SimpleFilter(_ =>\n            {\n                return allowed\n                    ? platforms.Any(platform => RuntimeInformation.IsOSPlatform(Map(platform)))\n                    : platforms.All(platform => !RuntimeInformation.IsOSPlatform(Map(platform)));\n            }))\n        {\n        }\n\n        // OSPlatform is a struct so it can not be used as attribute argument and this is why we use PlatformID enum\n        private static OSPlatform Map(OS platform)\n        {\n            switch (platform)\n            {\n                case OS.Windows:\n                    return OSPlatform.Windows;\n                case OS.Linux:\n                    return OSPlatform.Linux;\n                case OS.macOS:\n                    return OSPlatform.OSX;\n                case OS.Browser:\n                    return browser;\n                default:\n                    throw new NotSupportedException($\"Platform {platform} is not supported\");\n            }\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/GroupBenchmarksByAttribute.cs",
    "content": "﻿using System;\nusing BenchmarkDotNet.Configs;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    [PublicAPI]\n    [AttributeUsage(AttributeTargets.Class)]\n    public class GroupBenchmarksByAttribute: Attribute, IConfigSource\n    {\n        public IConfig Config { get; }\n\n        // CLS-Compliant Code requires a constructor without an array in the argument list\n        protected GroupBenchmarksByAttribute()\n        {\n            Config = ManualConfig.CreateEmpty();\n        }\n\n        public GroupBenchmarksByAttribute(params BenchmarkLogicalGroupRule[] rules)\n        {\n            Config = ManualConfig.CreateEmpty().AddLogicalGroupRules(rules);\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/HardwareCountersAttribute.cs",
    "content": "using System;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Diagnosers;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Assembly)]\n    public class HardwareCountersAttribute : Attribute, IConfigSource\n    {\n        // CLS-Compliant Code requires a constructor without an array in the argument list\n        [PublicAPI]\n        protected HardwareCountersAttribute()\n        {\n            Config = ManualConfig.CreateEmpty();\n        }\n\n        public HardwareCountersAttribute(params HardwareCounter[] counters)\n        {\n            Config = ManualConfig.CreateEmpty().AddHardwareCounters(counters);\n        }\n\n        public IConfig Config { get; }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/HideColumnsAttribute.cs",
    "content": "﻿using System;\nusing BenchmarkDotNet.Configs;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    [PublicAPI]\n    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Assembly, AllowMultiple = true)]\n    public class HideColumnsAttribute : Attribute, IConfigSource\n    {\n        public IConfig Config { get; }\n\n        // CLS-Compliant Code requires a constructor without an array in the argument list\n        protected HideColumnsAttribute() => Config = ManualConfig.CreateEmpty();\n\n        public HideColumnsAttribute(params string[] names) => Config = ManualConfig.CreateEmpty().HideColumns(names);\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Jobs/DryJobAttribute.cs",
    "content": "﻿using BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Jobs;\nusing System;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Assembly, AllowMultiple = true)]\n    public class DryJobAttribute : JobConfigBaseAttribute\n    {\n        public DryJobAttribute() : base(Job.Dry)\n        {\n        }\n\n        /// <summary>\n        /// defines a new Dry Job that targets specified Framework\n        /// </summary>\n        /// <param name=\"runtimeMoniker\">Target Framework to test.</param>\n        public DryJobAttribute(RuntimeMoniker runtimeMoniker)\n            : base(GetJob(Job.Dry, runtimeMoniker, null, null))\n        {\n        }\n\n        /// <summary>\n        /// defines a new Dry Job that targets specified Framework, JIT and Platform\n        /// </summary>\n        /// <param name=\"runtimeMoniker\">Target Framework to test.</param>\n        /// <param name=\"jit\">Jit to test.</param>\n        /// <param name=\"platform\">Platform to test.</param>\n        public DryJobAttribute(RuntimeMoniker runtimeMoniker, Jit jit, Platform platform)\n            : base(GetJob(Job.Dry, runtimeMoniker, jit, platform))\n        {\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Jobs/InProcessAttribute.cs",
    "content": "using BenchmarkDotNet.Characteristics;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Portability;\nusing BenchmarkDotNet.Toolchains;\nusing BenchmarkDotNet.Toolchains.InProcess.Emit;\nusing BenchmarkDotNet.Toolchains.InProcess.NoEmit;\nusing System;\n\nnamespace BenchmarkDotNet.Attributes;\n\npublic enum InProcessToolchainType\n{\n    Auto,\n    Emit,\n    NoEmit,\n}\n\n[AttributeUsage(AttributeTargets.Class | AttributeTargets.Assembly)]\npublic class InProcessAttribute(\n    InProcessToolchainType toolchainType = InProcessToolchainType.Auto,\n    bool executeOnSeparateThread = true)\n    : JobConfigBaseAttribute(GetJob(toolchainType, executeOnSeparateThread))\n{\n    private static Job GetJob(InProcessToolchainType toolchainType, bool executeOnSeparateThread)\n        => GetJob(Job.Default, toolchainType, executeOnSeparateThread);\n\n    internal static Job GetJob(Job baseJob, InProcessToolchainType toolchainType, bool executeOnSeparateThread)\n    {\n        if (toolchainType == InProcessToolchainType.Auto)\n        {\n            toolchainType = RuntimeInformation.IsAot\n                ? InProcessToolchainType.NoEmit\n                : InProcessToolchainType.Emit;\n        }\n\n        IToolchain toolchain = toolchainType switch\n        {\n            InProcessToolchainType.Emit => new InProcessEmitToolchain(new() { ExecuteOnSeparateThread = executeOnSeparateThread }),\n            InProcessToolchainType.NoEmit => new InProcessNoEmitToolchain(new() { ExecuteOnSeparateThread = executeOnSeparateThread }),\n            _ => throw new ArgumentOutOfRangeException(nameof(toolchainType))\n        };\n\n        var job = baseJob.WithToolchain(toolchain);\n        if (!job.HasValue(CharacteristicObject.IdCharacteristic))\n            job = job.WithId(\"InProcess\");\n\n        return job.Freeze();\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Jobs/JobConfigbaseAttribute.cs",
    "content": "﻿using System;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Jobs;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Assembly)]\n    public class JobConfigBaseAttribute : Attribute, IConfigSource\n    {\n        // CLS-Compliant Code requires a constructor which use only CLS-compliant types\n        [PublicAPI]\n        public JobConfigBaseAttribute() => Config = ManualConfig.CreateEmpty();\n\n        protected JobConfigBaseAttribute(Job job) => Config = ManualConfig.CreateEmpty().AddJob(job);\n\n        public IConfig Config { get; }\n\n        protected static Job GetJob(Job sourceJob, RuntimeMoniker runtimeMoniker, Jit? jit, Platform? platform)\n        {\n            var runtime = runtimeMoniker.GetRuntime();\n            var baseJob = sourceJob.WithRuntime(runtime).WithId($\"{sourceJob.Id}-{runtime.Name}\");\n            var id = baseJob.Id;\n\n            if (jit.HasValue)\n            {\n                baseJob = baseJob.WithJit(jit.Value);\n                id += \"-\" + jit.Value;\n            }\n\n            if (platform.HasValue)\n            {\n                baseJob = baseJob.WithPlatform(platform.Value);\n                id += \"-\" + platform.Value;\n            }\n\n            return baseJob.WithId(id).Freeze();\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Jobs/LegacyJitX64JobAttribute.cs",
    "content": "using System;\nusing BenchmarkDotNet.Jobs;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Assembly)]\n    public class LegacyJitX64JobAttribute : JobConfigBaseAttribute\n    {\n        public LegacyJitX64JobAttribute() : base(Job.LegacyJitX64)\n        {\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Jobs/LegacyJitX86JobAttribute.cs",
    "content": "﻿using System;\nusing BenchmarkDotNet.Jobs;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Assembly)]\n    public class LegacyJitX86JobAttribute : JobConfigBaseAttribute\n    {\n        public LegacyJitX86JobAttribute() : base(Job.LegacyJitX86)\n        {\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Jobs/LongRunJobAttribute.cs",
    "content": "﻿using System;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Jobs;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Assembly, AllowMultiple = true)]\n    public class LongRunJobAttribute : JobConfigBaseAttribute\n    {\n        public LongRunJobAttribute() : base(Job.LongRun)\n        {\n        }\n\n        /// <summary>\n        /// defines a new LongRun Job that targets specified Framework\n        /// </summary>\n        /// <param name=\"runtimeMoniker\">Target Framework to test.</param>\n        public LongRunJobAttribute(RuntimeMoniker runtimeMoniker)\n            : base(GetJob(Job.LongRun, runtimeMoniker, null, null))\n        {\n        }\n\n        /// <summary>\n        /// defines a new LongRun Job that targets specified Framework, JIT and Platform\n        /// </summary>\n        /// <param name=\"runtimeMoniker\">Target Framework to test.</param>\n        /// <param name=\"jit\">Jit to test.</param>\n        /// <param name=\"platform\">Platform to test.</param>\n        public LongRunJobAttribute(RuntimeMoniker runtimeMoniker, Jit jit, Platform platform)\n            : base(GetJob(Job.LongRun, runtimeMoniker, jit, platform))\n        {\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Jobs/MediumRunJobAttribute.cs",
    "content": "﻿using System;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Jobs;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Assembly, AllowMultiple = true)]\n    public class MediumRunJobAttribute : JobConfigBaseAttribute\n    {\n        public MediumRunJobAttribute() : base(Job.MediumRun)\n        {\n        }\n\n        /// <summary>\n        /// defines a new MediumRun Job that targets specified Framework\n        /// </summary>\n        /// <param name=\"runtimeMoniker\">Target Framework to test.</param>\n        public MediumRunJobAttribute(RuntimeMoniker runtimeMoniker)\n            : base(GetJob(Job.MediumRun, runtimeMoniker, null, null))\n        {\n        }\n\n        /// <summary>\n        /// defines a new MediumRun Job that targets specified Framework, JIT and Platform\n        /// </summary>\n        /// <param name=\"runtimeMoniker\">Target Framework to test.</param>\n        /// <param name=\"jit\">Jit to test.</param>\n        /// <param name=\"platform\">Platform to test.</param>\n        public MediumRunJobAttribute(RuntimeMoniker runtimeMoniker, Jit jit, Platform platform)\n            : base(GetJob(Job.MediumRun, runtimeMoniker, jit, platform))\n        {\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Jobs/MonoJobAttribute.cs",
    "content": "﻿using System;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Jobs;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Assembly, AllowMultiple = true)]\n    public class MonoJobAttribute : JobConfigBaseAttribute\n    {\n        public MonoJobAttribute(bool baseline = false) : base(Job.Default.WithRuntime(MonoRuntime.Default).WithBaseline(baseline))\n        {\n        }\n\n        public MonoJobAttribute(RuntimeMoniker runtimeMoniker, bool baseline = false) : base(Job.Default.WithRuntime(runtimeMoniker.GetRuntime()).WithBaseline(baseline))\n        {\n        }\n\n        public MonoJobAttribute(string name, string path, bool baseline = false)\n            : base(new Job(name, new EnvironmentMode(new MonoRuntime(name, path)).Freeze()).WithBaseline(baseline).Freeze())\n        {\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Jobs/RyuJitX64JobAttribute.cs",
    "content": "﻿using System;\nusing BenchmarkDotNet.Jobs;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Assembly)]\n    public class RyuJitX64JobAttribute : JobConfigBaseAttribute\n    {\n        public RyuJitX64JobAttribute() : base(Job.RyuJitX64)\n        {\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Jobs/RyuJitX86JobAttribute.cs",
    "content": "﻿using System;\nusing BenchmarkDotNet.Jobs;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    [PublicAPI]\n    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Assembly)]\n    public class RyuJitX86JobAttribute : JobConfigBaseAttribute\n    {\n        public RyuJitX86JobAttribute() : base(Job.RyuJitX86)\n        {\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Jobs/ShortRunJobAttribute.cs",
    "content": "﻿using System;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Jobs;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Assembly, AllowMultiple = true)]\n    public class ShortRunJobAttribute: JobConfigBaseAttribute\n    {\n        public ShortRunJobAttribute() : base(Job.ShortRun)\n        {\n        }\n\n        /// <summary>\n        /// defines a new ShortRun Job that targets specified Framework\n        /// </summary>\n        /// <param name=\"runtimeMoniker\">Target Framework to test.</param>\n        public ShortRunJobAttribute(RuntimeMoniker runtimeMoniker)\n            : base(GetJob(Job.ShortRun, runtimeMoniker, null, null))\n        {\n        }\n\n        /// <summary>\n        /// defines a new ShortRun Job that targets specified Framework, JIT and Platform\n        /// </summary>\n        /// <param name=\"runtimeMoniker\">Target Framework to test.</param>\n        /// <param name=\"jit\">Jit to test.</param>\n        /// <param name=\"platform\">Platform to test.</param>\n        public ShortRunJobAttribute(RuntimeMoniker runtimeMoniker, Jit jit, Platform platform)\n            : base(GetJob(Job.ShortRun, runtimeMoniker, jit, platform))\n        {\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Jobs/SimpleJobAttribute.cs",
    "content": "﻿using System;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Jobs;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Assembly, AllowMultiple = true)]\n    public class SimpleJobAttribute : JobConfigBaseAttribute\n    {\n        private const int DefaultValue = -1;\n\n        [PublicAPI]\n        public SimpleJobAttribute(\n            int launchCount = DefaultValue,\n            int warmupCount = DefaultValue,\n            int iterationCount = DefaultValue,\n            int invocationCount = DefaultValue,\n            string id = \"\",\n            bool baseline = false\n        ) : base(CreateJob(id, launchCount, warmupCount, iterationCount, invocationCount, null, baseline)) { }\n\n        [PublicAPI]\n        public SimpleJobAttribute(\n            RunStrategy runStrategy,\n            int launchCount = DefaultValue,\n            int warmupCount = DefaultValue,\n            int iterationCount = DefaultValue,\n            int invocationCount = DefaultValue,\n            string id = \"\",\n            bool baseline = false\n        ) : base(CreateJob(id, launchCount, warmupCount, iterationCount, invocationCount, runStrategy, baseline)) { }\n\n        [PublicAPI]\n        public SimpleJobAttribute(\n            RuntimeMoniker runtimeMoniker,\n            int launchCount = DefaultValue,\n            int warmupCount = DefaultValue,\n            int iterationCount = DefaultValue,\n            int invocationCount = DefaultValue,\n            string id = \"\",\n            bool baseline = false\n        ) : base(CreateJob(id, launchCount, warmupCount, iterationCount, invocationCount, null, baseline, runtimeMoniker)) { }\n\n        [PublicAPI]\n        public SimpleJobAttribute(\n            RunStrategy runStrategy,\n            RuntimeMoniker runtimeMoniker,\n            int launchCount = DefaultValue,\n            int warmupCount = DefaultValue,\n            int iterationCount = DefaultValue,\n            int invocationCount = DefaultValue,\n            string id = \"\",\n            bool baseline = false\n        ) : base(CreateJob(id, launchCount, warmupCount, iterationCount, invocationCount, runStrategy, baseline, runtimeMoniker)) { }\n\n        private static Job CreateJob(string id, int launchCount, int warmupCount, int iterationCount, int invocationCount, RunStrategy? runStrategy,\n            bool baseline, RuntimeMoniker runtimeMoniker = RuntimeMoniker.HostProcess)\n        {\n            var job = new Job(id);\n            int manualValuesCount = 0;\n\n            if (launchCount != DefaultValue)\n            {\n                job.Run.LaunchCount = launchCount;\n                manualValuesCount++;\n            }\n\n            if (warmupCount != DefaultValue)\n            {\n                job.Run.WarmupCount = warmupCount;\n                manualValuesCount++;\n            }\n\n            if (iterationCount != DefaultValue)\n            {\n                job.Run.IterationCount = iterationCount;\n                manualValuesCount++;\n            }\n            if (invocationCount != DefaultValue)\n            {\n                job.Run.InvocationCount = invocationCount;\n                manualValuesCount++;\n\n                int unrollFactor = job.Run.ResolveValue(RunMode.UnrollFactorCharacteristic, EnvironmentResolver.Instance);\n                if (invocationCount % unrollFactor != 0)\n                {\n                    job.Run.UnrollFactor = 1;\n                    manualValuesCount++;\n                }\n            }\n\n            if (runStrategy != null)\n            {\n                job.Run.RunStrategy = runStrategy.Value;\n                manualValuesCount++;\n            }\n\n            if (baseline)\n                job.Meta.Baseline = true;\n\n            if (runtimeMoniker != RuntimeMoniker.HostProcess)\n            {\n                job.Environment.Runtime = runtimeMoniker.GetRuntime();\n                manualValuesCount++;\n            }\n\n            if (id == null && manualValuesCount == 1 && runtimeMoniker != RuntimeMoniker.HostProcess)\n                job = job.WithId(runtimeMoniker.GetRuntime().Name);\n\n            return job.Freeze();\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Jobs/VeryLongRunJobAttribute.cs",
    "content": "﻿using System;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Jobs;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    [PublicAPI]\n    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Assembly, AllowMultiple = true)]\n    public class VeryLongRunJobAttribute : JobConfigBaseAttribute\n    {\n        public VeryLongRunJobAttribute() : base(Job.VeryLongRun)\n        {\n        }\n\n        /// <summary>\n        /// defines a new VeryLongRun Job that targets specified Framework\n        /// </summary>\n        /// <param name=\"runtimeMoniker\">Target Framework to test.</param>\n        public VeryLongRunJobAttribute(RuntimeMoniker runtimeMoniker)\n            : base(GetJob(Job.VeryLongRun, runtimeMoniker, null, null))\n        {\n        }\n\n        /// <summary>\n        /// defines a new VeryLongRun Job that targets specified Framework, JIT and Platform\n        /// </summary>\n        /// <param name=\"runtimeMoniker\">Target Framework to test.</param>\n        /// <param name=\"jit\">Jit to test.</param>\n        /// <param name=\"platform\">Platform to test.</param>\n        public VeryLongRunJobAttribute(RuntimeMoniker runtimeMoniker, Jit jit, Platform platform)\n            : base(GetJob(Job.VeryLongRun, runtimeMoniker, jit, platform))\n        {\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/KeepBenchmarkFilesAttribute.cs",
    "content": "﻿using System;\nusing BenchmarkDotNet.Configs;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    /// <summary>\n    /// determines if all auto-generated files should be kept or removed after running the benchmarks\n    /// </summary>\n    [PublicAPI]\n    [AttributeUsage(AttributeTargets.Class)]\n    public class KeepBenchmarkFilesAttribute : Attribute, IConfigSource\n    {\n        public IConfig Config { get; }\n\n        public KeepBenchmarkFilesAttribute(bool value = true)\n        {\n            Config = ManualConfig.CreateEmpty().WithOption(ConfigOptions.KeepBenchmarkFiles, value);\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/MemoryDiagnoserAttribute.cs",
    "content": "using System;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Diagnosers;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    [AttributeUsage(AttributeTargets.Class)]\n    public class MemoryDiagnoserAttribute : Attribute, IConfigSource\n    {\n        public IConfig Config { get; }\n\n        /// <param name=\"displayGenColumns\">Display Garbage Collections per Generation columns (Gen 0, Gen 1, Gen 2). True by default.</param>\n        public MemoryDiagnoserAttribute(bool displayGenColumns = true)\n        {\n            Config = ManualConfig.CreateEmpty().AddDiagnoser(new MemoryDiagnoser(new MemoryDiagnoserConfig(displayGenColumns)));\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Mutators/EvaluateOverheadAttribute.cs",
    "content": "﻿using System;\nusing BenchmarkDotNet.Jobs;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    /// <summary>\n    /// Specifies if the overhead should be evaluated (Idle runs) and it's average value subtracted from every result.\n    /// True by default, very important for nano-benchmarks.\n    /// </summary>\n    [PublicAPI]\n    [Obsolete(\"Overhead evaluation affects the accuracy of benchmark results. This will be removed soon.\")]\n    public class EvaluateOverheadAttribute : JobMutatorConfigBaseAttribute\n    {\n        public EvaluateOverheadAttribute(bool value = true) : base(Job.Default.WithEvaluateOverhead(value))\n        {\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Mutators/GcConcurrentAttribute.cs",
    "content": "﻿using BenchmarkDotNet.Jobs;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    /// <summary>\n    /// Specifies whether the common language runtime runs garbage collection on a separate thread.\n    /// <value>false: Does not run garbage collection concurrently.</value>\n    /// <value>true: Runs garbage collection concurrently. This is the default.</value>\n    /// </summary>\n    [PublicAPI]\n    public class GcConcurrentAttribute : JobMutatorConfigBaseAttribute\n    {\n        public GcConcurrentAttribute(bool value = true) : base(Job.Default.WithGcConcurrent(value))\n        {\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Mutators/GcForceAttribute.cs",
    "content": "﻿using BenchmarkDotNet.Jobs;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    /// <summary>\n    /// Specifies whether the BenchmarkDotNet's benchmark runner forces full garbage collection after each benchmark invocation\n    /// <value>false: Does not force garbage collection.</value>\n    /// <value>true: Forces full garbage collection after each benchmark invocation. This is the default.</value>\n    /// </summary>\n    [PublicAPI]\n    public class GcForceAttribute : JobMutatorConfigBaseAttribute\n    {\n        public GcForceAttribute(bool value = true) : base(Job.Default.WithGcForce(value))\n        {\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Mutators/GcServerAttribute.cs",
    "content": "﻿using BenchmarkDotNet.Jobs;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    /// <summary>\n    /// Specifies whether the common language runtime runs server garbage collection.\n    /// <value>false: Does not run server garbage collection. This is the default.</value>\n    /// <value>true: Runs server garbage collection.</value>\n    /// </summary>\n    [PublicAPI]\n    public class GcServerAttribute : JobMutatorConfigBaseAttribute\n    {\n        public GcServerAttribute(bool value = false) : base(Job.Default.WithGcServer(value))\n        {\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Mutators/InnerIterationCountAttribute.cs",
    "content": "﻿using BenchmarkDotNet.Jobs;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    /// <summary>\n    /// Invocation count in a single iteration.\n    /// Does exactly the same as InvocationCountAttribute, added to make porting from xunit-performance to BenchmarkDotNet easier\n    /// </summary>\n    [PublicAPI]\n    public class InnerIterationCountAttribute : JobMutatorConfigBaseAttribute\n    {\n        public InnerIterationCountAttribute(int invocationCount)\n            : base(Job.Default\n                .WithInvocationCount(invocationCount)\n                .WithUnrollFactor(1)) // it's for xunit-performance porting purpose, where the idea of unroll factor did not exist\n        {\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Mutators/InvocationCountAttribute.cs",
    "content": "﻿using BenchmarkDotNet.Jobs;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    /// <summary>\n    /// Invocation count in a single iteration.\n    /// If specified, <see cref=\"RunMode.IterationTime\"/> will be ignored.\n    /// If specified, it must be a multiple of <see cref=\"RunMode.UnrollFactor\"/>.\n    /// </summary>\n    [PublicAPI]\n    public class InvocationCountAttribute : JobMutatorConfigBaseAttribute\n    {\n        public InvocationCountAttribute(int invocationCount, int unrollFactor = 1)\n            : base(Job.Default\n                .WithInvocationCount(invocationCount)\n                .WithUnrollFactor(unrollFactor))\n        {\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Mutators/IterationCountAttribute.cs",
    "content": "﻿using BenchmarkDotNet.Jobs;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    /// <summary>\n    /// How many target iterations should be performed\n    /// If specified, <see cref=\"RunMode.MinIterationCount\"/> will be ignored.\n    /// If specified, <see cref=\"RunMode.MaxIterationCount\"/> will be ignored.\n    /// </summary>\n    [PublicAPI]\n    public class IterationCountAttribute : JobMutatorConfigBaseAttribute\n    {\n        public IterationCountAttribute(int targetIterationCount) : base(Job.Default.WithIterationCount(targetIterationCount))\n        {\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Mutators/IterationTimeAttribute.cs",
    "content": "﻿using BenchmarkDotNet.Jobs;\nusing JetBrains.Annotations;\nusing Perfolizer.Horology;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    /// <summary>\n    /// Desired time of execution of an iteration. Used by Pilot stage to estimate the number of invocations per iteration.\n    /// The default value is 500 milliseconds.\n    /// </summary>\n    [PublicAPI]\n    public class IterationTimeAttribute : JobMutatorConfigBaseAttribute\n    {\n        public IterationTimeAttribute(double milliseconds) : base(Job.Default.WithIterationTime(TimeInterval.FromMilliseconds(milliseconds)))\n        {\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Mutators/JobMutatorConfigBaseAttribute.cs",
    "content": "﻿using System;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Jobs;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)] // users must not be able to define given mutator attribute more than once per type\n    public class JobMutatorConfigBaseAttribute : Attribute, IConfigSource\n    {\n        // CLS-Compliant Code requires a constructor which use only CLS-compliant types\n        [PublicAPI]\n        public JobMutatorConfigBaseAttribute() => Config = ManualConfig.CreateEmpty();\n\n        protected JobMutatorConfigBaseAttribute(Job job) => Config = ManualConfig.CreateEmpty().AddJob(job.AsMutator());\n\n        public IConfig Config { get; }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Mutators/MaxAbsoluteErrorAttribute.cs",
    "content": "﻿using BenchmarkDotNet.Jobs;\nusing JetBrains.Annotations;\nusing Perfolizer.Horology;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    /// <summary>\n    /// Maximum acceptable error for a benchmark (by default, BenchmarkDotNet continue iterations until the actual error is less than the specified error).\n    /// Doesn't have a default value.\n    /// <remarks>If <see cref=\"AccuracyMode.MaxRelativeError\"/> is also provided, the smallest value is used as stop criteria.</remarks>\n    /// </summary>\n    [PublicAPI]\n    public class MaxAbsoluteErrorAttribute : JobMutatorConfigBaseAttribute\n    {\n        public MaxAbsoluteErrorAttribute(double nanoseconds) : base(Job.Default.WithMaxAbsoluteError(TimeInterval.FromNanoseconds(nanoseconds)))\n        {\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Mutators/MaxIterationCountAttribute.cs",
    "content": "﻿using BenchmarkDotNet.Analysers;\nusing BenchmarkDotNet.Jobs;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    /// <summary>\n    /// Maximum count of target iterations that should be performed\n    /// The default value is 100\n    /// <remarks>If you set this value to below 15, then <see cref=\"MultimodalDistributionAnalyzer\"/>  is not going to work</remarks>\n    /// </summary>\n    public class MaxIterationCountAttribute : JobMutatorConfigBaseAttribute\n    {\n        public MaxIterationCountAttribute(int maxTargetIterationCount) : base(Job.Default.WithMaxIterationCount(maxTargetIterationCount))\n        {\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Mutators/MaxRelativeErrorAttribute.cs",
    "content": "﻿using BenchmarkDotNet.Jobs;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    /// <summary>\n    /// Maximum acceptable error for a benchmark (by default, BenchmarkDotNet continue iterations until the actual error is less than the specified error).\n    /// The default value is 0.02.\n    /// <remarks>If <see cref=\"AccuracyMode.MaxAbsoluteError\"/> is also provided, the smallest value is used as stop criteria.</remarks>\n    /// </summary>\n    [PublicAPI]\n    public class MaxRelativeErrorAttribute : JobMutatorConfigBaseAttribute\n    {\n        public MaxRelativeErrorAttribute(double maxRelativeError) : base(Job.Default.WithMaxRelativeError(maxRelativeError))\n        {\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Mutators/MaxWarmupCountAttribute.cs",
    "content": "﻿using BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Jobs;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    /// <summary>\n    /// Maximum count of warmup iterations that should be performed\n    /// The default value is 50\n    /// </summary>\n    public class MaxWarmupCountAttribute : JobMutatorConfigBaseAttribute\n    {\n        /// <param name=\"maxWarmupCount\">Maximum count of warmup iterations that should be performed. The default value is 50</param>\n        /// <param name=\"forceAutoWarmup\">if set to true, will overwrite WarmupCount of the global config</param>\n        public MaxWarmupCountAttribute(int maxWarmupCount, bool forceAutoWarmup = false)\n            : base(forceAutoWarmup\n                ? Job.Default.WithMaxWarmupCount(maxWarmupCount).WithWarmupCount(EngineResolver.ForceAutoWarmup)\n                : Job.Default.WithMaxWarmupCount(maxWarmupCount))\n        {\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Mutators/MemoryRandomizationAttribute.cs",
    "content": "﻿using BenchmarkDotNet.Jobs;\nusing Perfolizer.Mathematics.OutlierDetection;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    /// <summary>\n    /// specifies whether Engine should allocate some random-sized memory between iterations\n    /// <remarks>it makes [GlobalCleanup] and [GlobalSetup] methods to be executed after every iteration</remarks>\n    /// </summary>\n    public class MemoryRandomizationAttribute : JobMutatorConfigBaseAttribute\n    {\n        public MemoryRandomizationAttribute(bool enable = true, OutlierMode outlierMode = OutlierMode.DontRemove)\n            : base(Job.Default.WithMemoryRandomization(enable).WithOutlierMode(outlierMode))\n        {\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Mutators/MinInvokeCountAttribute.cs",
    "content": "﻿using BenchmarkDotNet.Jobs;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    /// <summary>\n    /// Minimum count of benchmark invocations per iteration.\n    /// The default value is 4.\n    /// </summary>\n    [PublicAPI]\n    public class MinInvokeCountAttribute : JobMutatorConfigBaseAttribute\n    {\n        public MinInvokeCountAttribute(int minInvokeCount) : base(Job.Default.WithMinInvokeCount(minInvokeCount))\n        {\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Mutators/MinIterationCountAttribute.cs",
    "content": "﻿using BenchmarkDotNet.Analysers;\nusing BenchmarkDotNet.Jobs;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    /// <summary>\n    /// Minimum count of target iterations that should be performed.\n    /// The default value is 15.\n    /// <remarks>If you set this value to below 15, then <see cref=\"MultimodalDistributionAnalyzer\"/> is not going to work.</remarks>\n    /// </summary>\n    [PublicAPI]\n    public class MinIterationCountAttribute : JobMutatorConfigBaseAttribute\n    {\n        public MinIterationCountAttribute(int minTargetIterationCount) : base(Job.Default.WithMinIterationCount(minTargetIterationCount))\n        {\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Mutators/MinIterationTimeAttribute.cs",
    "content": "﻿using BenchmarkDotNet.Jobs;\nusing JetBrains.Annotations;\nusing Perfolizer.Horology;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    /// <summary>\n    /// Minimum time of a single iteration. Unlike Run.IterationTime, this characteristic specifies only the lower limit. In case of need, BenchmarkDotNet can increase this value.\n    /// The default value is 500 milliseconds.\n    /// </summary>\n    [PublicAPI]\n    public class MinIterationTimeAttribute : JobMutatorConfigBaseAttribute\n    {\n        public MinIterationTimeAttribute(double milliseconds) : base(Job.Default.WithMinIterationTime(TimeInterval.FromMilliseconds(milliseconds)))\n        {\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Mutators/MinWarmupCountAttribute.cs",
    "content": "﻿using BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Jobs;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    /// <summary>\n    /// Minimum count of warmup iterations that should be performed\n    /// The default value is 6\n    /// </summary>\n    public class MinWarmupCountAttribute : JobMutatorConfigBaseAttribute\n    {\n        /// <param name=\"minWarmupCount\">Minimum count of warmup iterations that should be performed. The default value is 6</param>\n        /// <param name=\"forceAutoWarmup\">if set to true, will overwrite WarmupCount in the global config</param>\n        public MinWarmupCountAttribute(int minWarmupCount, bool forceAutoWarmup = false)\n            : base(forceAutoWarmup\n                ? Job.Default.WithMinWarmupCount(minWarmupCount).WithWarmupCount(EngineResolver.ForceAutoWarmup)\n                : Job.Default.WithMinWarmupCount(minWarmupCount))\n        {\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Mutators/OutliersAttribute.cs",
    "content": "﻿using BenchmarkDotNet.Jobs;\nusing Perfolizer.Mathematics.OutlierDetection;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    /// <summary>\n    /// Specifies which outliers should be removed from the distribution\n    /// </summary>\n    public class OutliersAttribute : JobMutatorConfigBaseAttribute\n    {\n        public OutliersAttribute(OutlierMode outlierMode) : base(Job.Default.WithOutlierMode(outlierMode))\n        {\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Mutators/ProcessCountAttribute.cs",
    "content": "﻿using BenchmarkDotNet.Jobs;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    /// <summary>\n    /// How many times we should launch process with target benchmark.\n    /// </summary>\n    [PublicAPI]\n    public class ProcessCountAttribute : JobMutatorConfigBaseAttribute\n    {\n        public ProcessCountAttribute(int processLaunchCount) : base(Job.Default.WithLaunchCount(processLaunchCount))\n        {\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Mutators/RunOncePerIterationAttribute.cs",
    "content": "﻿using BenchmarkDotNet.Jobs;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    /// <summary>\n    /// Run the benchmark exactly once per iteration.\n    /// </summary>\n    public class RunOncePerIterationAttribute : JobMutatorConfigBaseAttribute\n    {\n        public RunOncePerIterationAttribute() : base(Job.Default.RunOncePerIteration())\n        {\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Mutators/WarmupCountAttribute.cs",
    "content": "﻿using BenchmarkDotNet.Jobs;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    /// <summary>\n    /// How many warmup iterations should be performed.\n    /// </summary>\n    [PublicAPI]\n    public class WarmupCountAttribute : JobMutatorConfigBaseAttribute\n    {\n        public WarmupCountAttribute(int warmupCount) : base(Job.Default.WithWarmupCount(warmupCount))\n        {\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/OrdererAttribute.cs",
    "content": "﻿using System;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Order;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Assembly)]\n    public class OrdererAttribute : Attribute, IConfigSource\n    {\n        public OrdererAttribute(\n            SummaryOrderPolicy summaryOrderPolicy = SummaryOrderPolicy.Default,\n            MethodOrderPolicy methodOrderPolicy = MethodOrderPolicy.Declared,\n            JobOrderPolicy jobOrderPolicy = JobOrderPolicy.Numeric)\n        {\n            Config = ManualConfig.CreateEmpty().WithOrderer(new DefaultOrderer(summaryOrderPolicy, methodOrderPolicy, jobOrderPolicy));\n        }\n\n        public IConfig Config { get; }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/PerfCollectProfilerAttribute.cs",
    "content": "using System;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Diagnosers;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Assembly)]\n    public class PerfCollectProfilerAttribute : Attribute, IConfigSource\n    {\n        /// <param name=\"performExtraBenchmarksRun\">When set to true, benchmarks will be executed one more time with the profiler attached. If set to false, there will be no extra run but the results will contain overhead. False by default.</param>\n        /// <param name=\"timeoutInSeconds\">How long should we wait for the perfcollect script to finish processing the trace. 300s by default.</param>\n        public PerfCollectProfilerAttribute(bool performExtraBenchmarksRun = false, int timeoutInSeconds = 300)\n        {\n            Config = ManualConfig.CreateEmpty().AddDiagnoser(new PerfCollectProfiler(new PerfCollectProfilerConfig(performExtraBenchmarksRun, timeoutInSeconds)));\n        }\n\n        public IConfig Config { get; }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/StopOnFirstErrorAttribute.cs",
    "content": "﻿using System;\nusing BenchmarkDotNet.Configs;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    /// <summary>\n    /// determines if running should be stop after first error\n    /// </summary>\n    [PublicAPI]\n    [AttributeUsage(AttributeTargets.Class)]\n    public class StopOnFirstErrorAttribute : Attribute, IConfigSource\n    {\n        public IConfig Config { get; }\n\n        public StopOnFirstErrorAttribute(bool value = true)\n        {\n            Config = ManualConfig.CreateEmpty().WithOption(ConfigOptions.StopOnFirstError, value);\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/ThreadingDiagnoserAttribute.cs",
    "content": "﻿using System;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Diagnosers;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    [AttributeUsage(AttributeTargets.Class)]\n    public class ThreadingDiagnoserAttribute : Attribute, IConfigSource\n    {\n        public IConfig Config { get; }\n\n        //public ThreadingDiagnoserAttribute() => Config = ManualConfig.CreateEmpty().AddDiagnoser(ThreadingDiagnoser.Default);\n\n        /// <param name=\"displayLockContentionWhenZero\">Display configuration for 'LockContentionCount' when it is empty. True (displayed) by default.</param>\n        /// <param name=\"displayCompletedWorkItemCountWhenZero\">Display configuration for 'CompletedWorkItemCount' when it is empty. True (displayed) by default.</param>\n\n        [PublicAPI]\n        public ThreadingDiagnoserAttribute(bool displayLockContentionWhenZero = true, bool displayCompletedWorkItemCountWhenZero = true)\n        {\n            Config = ManualConfig.CreateEmpty().AddDiagnoser(new ThreadingDiagnoser(new ThreadingDiagnoserConfig(displayLockContentionWhenZero, displayCompletedWorkItemCountWhenZero)));\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/UnicodeConsoleLoggerAttribute.cs",
    "content": "using System;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Loggers;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    /// <summary>\n    /// Enable unicode support in console logger\n    /// </summary>\n    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Assembly)]\n    public class UnicodeConsoleLoggerAttribute : Attribute, IConfigSource\n    {\n        public UnicodeConsoleLoggerAttribute()\n        {\n            Config = ManualConfig.CreateEmpty().AddLogger(ConsoleLogger.Unicode);\n        }\n\n        public IConfig Config { get; }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Validators/ExecutionValidatorAttribute.cs",
    "content": "﻿using BenchmarkDotNet.Validators;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    [PublicAPI]\n    public class ExecutionValidatorAttribute : ValidatorConfigBaseAttribute\n    {\n        public ExecutionValidatorAttribute()\n            : this(true) { }\n\n        public ExecutionValidatorAttribute(bool failOnError)\n            : base(failOnError ? ExecutionValidator.FailOnError : ExecutionValidator.DontFailOnError) { }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Validators/ReturnValueValidatorAttribute.cs",
    "content": "﻿using BenchmarkDotNet.Validators;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    [PublicAPI]\n    public class ReturnValueValidatorAttribute : ValidatorConfigBaseAttribute\n    {\n        public ReturnValueValidatorAttribute()\n            : this(true) { }\n\n        public ReturnValueValidatorAttribute(bool failOnError)\n            : base(failOnError ? ReturnValueValidator.FailOnError : ReturnValueValidator.DontFailOnError) { }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/Validators/ValidatorConfigBaseAttribute.cs",
    "content": "﻿using System;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Validators;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Assembly)]\n    public abstract class ValidatorConfigBaseAttribute : Attribute, IConfigSource\n    {\n        // CLS-Compliant Code requires a constructor without an array in the argument list\n        [PublicAPI]\n        protected ValidatorConfigBaseAttribute()\n        {\n            Config = ManualConfig.CreateEmpty();\n        }\n\n        protected ValidatorConfigBaseAttribute(params IValidator[] validators)\n        {\n            Config = ManualConfig.CreateEmpty().AddValidator(validators);\n        }\n\n        public IConfig Config { get; }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Attributes/WakeLockAttribute.cs",
    "content": "﻿using BenchmarkDotNet.Configs;\nusing System;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    /// <summary>\n    /// Placing a <see cref=\"WakeLockAttribute\"/> on your assembly or class controls whether the\n    /// Windows system enters sleep or turns off the display while benchmarks run.\n    /// </summary>\n    [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class)]\n    public sealed class WakeLockAttribute : Attribute, IConfigSource\n    {\n        public WakeLockAttribute(WakeLockType wakeLockType) =>\n            Config = ManualConfig.CreateEmpty().WithWakeLock(wakeLockType);\n\n        public IConfig Config { get; }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/BenchmarkDotNet.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\n  <Import Project=\"..\\..\\build\\common.props\" />\n  <PropertyGroup>\n    <AssemblyTitle>BenchmarkDotNet</AssemblyTitle>\n    <TargetFrameworks>netstandard2.0;net6.0;net8.0;net9.0;net10.0</TargetFrameworks>\n    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>\n    <NoWarn>$(NoWarn);1701;1702;1705;1591;3005;NU1702;CS3001;CS3003</NoWarn>\n    <AssemblyName>BenchmarkDotNet</AssemblyName>\n    <PackageId>BenchmarkDotNet</PackageId>\n    <RootNamespace>BenchmarkDotNet</RootNamespace>\n    <!-- needed for docfx xref resolver -->\n    <ProduceReferenceAssembly>True</ProduceReferenceAssembly>\n  </PropertyGroup>\n  <ItemGroup>\n    <EmbeddedResource Include=\"Templates\\*\" Exclude=\"bin\\**;obj\\**;**\\*.xproj;packages\\**;@(EmbeddedResource)\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"BenchmarkDotNet.targets\" Pack=\"true\" PackagePath=\"buildTransitive\" />\n  </ItemGroup>\n  <ItemGroup>\n    <PackageReference Include=\"CommandLineParser\" Version=\"2.9.1\" />\n    <PackageReference Include=\"Gee.External.Capstone\" Version=\"2.3.0\" />\n    <PackageReference Include=\"Iced\" Version=\"1.21.0\" />\n    <PackageReference Include=\"Microsoft.Diagnostics.Runtime\" Version=\"3.1.525101\" />\n    <PackageReference Include=\"Perfolizer\" Version=\"[0.6.6]\" />\n    <PackageReference Include=\"Microsoft.Diagnostics.Tracing.TraceEvent\" Version=\"3.1.30\" PrivateAssets=\"contentfiles;analyzers\" />\n    <PackageReference Include=\"Microsoft.DotNet.PlatformAbstractions\" Version=\"3.1.6\" />\n    <PackageReference Include=\"Microsoft.CodeAnalysis.CSharp\" Version=\"5.0.0\" />\n    <PackageReference Include=\"System.Management\" Version=\"10.0.3\" />\n    <PackageReference Include=\"System.Text.Json\" Version=\"10.0.3\" />\n  </ItemGroup>\n  <ItemGroup Condition=\" '$(TargetFramework)' == 'netstandard2.0' \">\n    <PackageReference Include=\"Microsoft.Win32.Registry\" Version=\"5.0.0\" />\n    <PackageReference Include=\"System.Buffers\" Version=\"4.6.1\" />\n    <PackageReference Include=\"System.Numerics.Vectors\" Version=\"4.6.1\" />\n    <PackageReference Include=\"System.Reflection.Emit\" Version=\"4.7.0\" />\n    <PackageReference Include=\"System.Reflection.Emit.Lightweight\" Version=\"4.7.0\" />\n    <PackageReference Include=\"System.Threading.Tasks.Extensions\" Version=\"4.6.3\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ProjectReference Include=\"..\\BenchmarkDotNet.Annotations\\BenchmarkDotNet.Annotations.csproj\" />\n  </ItemGroup>\n  <!-- Settings for PolySharp -->\n  <PropertyGroup>\n    <PolySharpIncludeRuntimeSupportedAttributes>true</PolySharpIncludeRuntimeSupportedAttributes>\n  </PropertyGroup>\n  <ItemGroup>\n    <PackageReference Include=\"PolySharp\" Version=\"1.15.0\">\n      <PrivateAssets>all</PrivateAssets>\n      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\n    </PackageReference>\n  </ItemGroup>\n  <Import Project=\"..\\..\\build\\common.targets\" />\n</Project>\n"
  },
  {
    "path": "src/BenchmarkDotNet/BenchmarkDotNet.csproj.DotSettings",
    "content": "﻿<wpf:ResourceDictionary xml:space=\"preserve\" xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\" xmlns:s=\"clr-namespace:System;assembly=mscorlib\" xmlns:ss=\"urn:shemas-jetbrains-com:settings-storage-xaml\" xmlns:wpf=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">\n\t<s:Boolean x:Key=\"/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=attributes_005Ccolumns/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=attributes_005Cexporters/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=attributes_005Cfilters/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=attributes_005Cjobs/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=attributes_005Cmutators/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=attributes_005Cvalidators/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=engines_005Cstoppingcriteria/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=toolchains_005Cinprocess_002Eemit_002Eimplementation_005Cemitters/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=toolchains_005Cinprocess_002Eemit_002Eimplementation_005Crunnable/@EntryIndexedValue\">True</s:Boolean></wpf:ResourceDictionary>"
  },
  {
    "path": "src/BenchmarkDotNet/BenchmarkDotNet.targets",
    "content": "﻿<Project>\n\n  <PropertyGroup>\n    <!-- If the RuntimeIdentifier is explicitly specified. Use the specified target platform. -->\n    <BenchmarkDotNetTargetPlatform>$(RuntimeIdentifier)</BenchmarkDotNetTargetPlatform>\n  </PropertyGroup>\n  \n  <PropertyGroup Condition=\"'$(BenchmarkDotNetTargetPlatform)' == ''\">\n    <!-- If RuntimeIdentifier is not specified Use current build platform -->\n    <!-- List of runtimes supported by Gee.External.Capstone: https://github.com/9ee1/Capstone.NET/tree/master/Gee.External.Capstone/runtimes -->\n    <BenchmarkDotNetTargetPlatform Condition=\"$([MSBuild]::IsOSPlatform('Linux'))\">linux</BenchmarkDotNetTargetPlatform>\n    <BenchmarkDotNetTargetPlatform Condition=\"$([MSBuild]::IsOSPlatform('Windows'))\">win</BenchmarkDotNetTargetPlatform>\n    <BenchmarkDotNetTargetPlatform Condition=\"$([MSBuild]::IsOSPlatform('OSX'))\">osx</BenchmarkDotNetTargetPlatform>\n\n    <BenchmarkDotNetTargetPlatform Condition=\"'$([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture)' == 'X64'\">$(BenchmarkDotNetTargetPlatform)-x64</BenchmarkDotNetTargetPlatform>\n    <BenchmarkDotNetTargetPlatform Condition=\"'$([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture)' == 'X86'\">$(BenchmarkDotNetTargetPlatform)-x86</BenchmarkDotNetTargetPlatform>\n    <BenchmarkDotNetTargetPlatform Condition=\"'$([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture)' == 'Arm'\">$(BenchmarkDotNetTargetPlatform)-arm</BenchmarkDotNetTargetPlatform>\n    <BenchmarkDotNetTargetPlatform Condition=\"'$([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture)' == 'Arm64'\">$(BenchmarkDotNetTargetPlatform)-arm64</BenchmarkDotNetTargetPlatform>\n  </PropertyGroup>\n\n  <Target Name=\"FilterBenchmarkDotNetPackageAssets\" AfterTargets=\"ResolvePackageAssets\">\n    <!-- Remove `runtimes/{RuntimeIdentifier}` files that is not matched to target platform. -->\n    <ItemGroup Condition=\"'$(BenchmarkDotNetTargetPlatform)' != '' AND $(BenchmarkDotNetTargetPlatform) != 'all'\">\n      <RuntimeTargetsCopyLocalItems Remove=\"@(RuntimeTargetsCopyLocalItems)\"\n                                    Condition=\"'%(RuntimeTargetsCopyLocalItems.NuGetPackageId)' == 'Gee.External.Capstone' AND '%(RuntimeTargetsCopyLocalItems.RuntimeIdentifier)' != '$(BenchmarkDotNetTargetPlatform)'\" />\n    </ItemGroup>\n\n    <!-- Remove unnecessary satellite assemblies. -->\n    <ItemGroup>\n      <ResourceCopyLocalItems Remove=\"@(ResourceCopyLocalItems)\"\n                              Condition=\"'%(ResourceCopyLocalItems.NuGetPackageId)' == 'Microsoft.CodeAnalysis.Common' OR '%(ResourceCopyLocalItems.NuGetPackageId)' == 'Microsoft.CodeAnalysis.CSharp'\"/>\n    </ItemGroup>\n  </Target>\n</Project>\n"
  },
  {
    "path": "src/BenchmarkDotNet/Characteristics/Characteristic.cs",
    "content": "﻿using System;\nusing System.Diagnostics.CodeAnalysis;\nusing static BenchmarkDotNet.Characteristics.CharacteristicHelper;\n\nnamespace BenchmarkDotNet.Characteristics\n{\n    public abstract class Characteristic\n    {\n        public static readonly object EmptyValue = new object();\n\n        public static Characteristic<T> Create<TOwner, [DynamicallyAccessedMembers(CharacteristicObject.CharacteristicMemberTypes)] T>(string memberName)\n            where TOwner : CharacteristicObject\n            => new Characteristic<T>(\n                memberName,\n                typeof(TOwner),\n                null, default,\n                false);\n\n        public static Characteristic<T> Create<TOwner, [DynamicallyAccessedMembers(CharacteristicObject.CharacteristicMemberTypes)] T>(string memberName, T fallbackValue)\n            where TOwner : CharacteristicObject\n            => new Characteristic<T>(\n                memberName,\n                typeof(TOwner),\n                null, fallbackValue,\n                false);\n\n        public static Characteristic<T> Create<TOwner, [DynamicallyAccessedMembers(CharacteristicObject.CharacteristicMemberTypes)] T>(string memberName, Func<CharacteristicObject, T?, T> resolver, T fallbackValue, bool ignoreOnApply)\n            where TOwner : CharacteristicObject\n            => new Characteristic<T>(\n                memberName,\n                typeof(TOwner),\n                resolver, fallbackValue,\n                ignoreOnApply);\n\n        public static Characteristic<T> CreateHidden<TOwner, [DynamicallyAccessedMembers(CharacteristicObject.CharacteristicMemberTypes)] T>(string memberName)\n            where TOwner : CharacteristicObject\n            => new Characteristic<T>(\n                memberName,\n                typeof(TOwner),\n                null, default,\n                false, true);\n\n        public static Characteristic<T> CreateIgnoreOnApply<TOwner, [DynamicallyAccessedMembers(CharacteristicObject.CharacteristicMemberTypes)] T>(string memberName)\n            where TOwner : CharacteristicObject\n            => new Characteristic<T>(\n                memberName,\n                typeof(TOwner),\n                null, default,\n                true);\n\n        protected Characteristic(\n            string id,\n            [DynamicallyAccessedMembers(CharacteristicObject.CharacteristicMemberTypes)] Type characteristicType,\n            Type declaringType,\n            object? fallbackValue,\n            bool ignoreOnApply,\n            bool dontShowInSummary = false)\n        {\n            ArgumentException.ThrowIfNullOrEmpty(id);\n\n            Id = id;\n            CharacteristicType = characteristicType;\n            DeclaringType = declaringType;\n            FallbackValue = fallbackValue;\n            IgnoreOnApply = ignoreOnApply;\n            DontShowInSummary = dontShowInSummary;\n        }\n\n        public string Id { get; }\n        public string FullId => DeclaringType.Name + \".\" + Id;\n\n        // TODO: better naming. As it is for now this property used for Id only and has meaning \"if set, will not transfer to others nor be cleared\".\n        public bool IgnoreOnApply { get; }\n\n        public bool DontShowInSummary { get; }\n\n        [DynamicallyAccessedMembers(CharacteristicObject.CharacteristicMemberTypes)]\n        public Type CharacteristicType { get; }\n\n        public Type DeclaringType { get; }\n\n        private object? FallbackValue { get; }\n\n        public object? this[CharacteristicObject obj]\n        {\n            get { return obj.GetValue(this); }\n            set { obj.SetValue(this, value); }\n        }\n\n        public bool HasChildCharacteristics => IsCharacteristicObjectSubclass(CharacteristicType);\n\n        internal virtual object? ResolveValueCore(CharacteristicObject obj, object? currentValue) =>\n            ReferenceEquals(currentValue, EmptyValue) ? FallbackValue : currentValue;\n\n        public override string ToString() => Id;\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Characteristics/CharacteristicHelper.cs",
    "content": "﻿using System;\nusing System.Collections.Concurrent;\nusing System.Collections.Generic;\nusing System.Diagnostics.CodeAnalysis;\nusing System.Linq;\nusing System.Reflection;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Characteristics\n{\n    public static class CharacteristicHelper\n    {\n        #region Helpers\n        internal static bool IsCharacteristicObjectSubclass(Type type) =>\n            type.GetTypeInfo().IsSubclassOf(typeof(CharacteristicObject));\n\n        private static bool IsCharacteristicSubclass(Type type) =>\n            type.GetTypeInfo().IsSubclassOf(typeof(Characteristic));\n\n        private static Characteristic AssertHasValue(MemberInfo member, Characteristic? value)\n        {\n            if (member?.DeclaringType == null)\n                throw new NullReferenceException($\"{nameof(member.DeclaringType)}\");\n            if (value == null)\n                throw new ArgumentException($\"The value of {member.DeclaringType.Name}.{member.Name} is null\");\n\n            return value;\n        }\n\n        public static bool IsPresentableCharacteristic(this Characteristic c, bool includeIgnoreOnApply = false) =>\n            !c.HasChildCharacteristics && !c.DontShowInSummary && (includeIgnoreOnApply || !c.IgnoreOnApply);\n        #endregion\n\n        #region Type characteristics\n        private static readonly IReadOnlyList<Characteristic> EmptyCharacteristics = [];\n\n        private static readonly ConcurrentDictionary<Type, IReadOnlyList<Characteristic>> ThisTypeCharacteristics =\n            new ConcurrentDictionary<Type, IReadOnlyList<Characteristic>>();\n\n        [PublicAPI] public static IReadOnlyList<Characteristic> GetThisTypeCharacteristics(this CharacteristicObject obj) =>\n            GetThisTypeCharacteristics(obj.GetType());\n\n        public static IReadOnlyList<Characteristic> GetThisTypeCharacteristics(\n            [DynamicallyAccessedMembers(CharacteristicObject.CharacteristicMemberTypes)] Type characteristicObjectType)\n        {\n            if (!IsCharacteristicObjectSubclass(characteristicObjectType))\n                return EmptyCharacteristics;\n            return ThisTypeCharacteristics.GetOrAdd(characteristicObjectType, GetThisTypeCharacteristicsCore);\n        }\n\n        private static IReadOnlyList<Characteristic> GetThisTypeCharacteristicsCore(\n            [DynamicallyAccessedMembers(CharacteristicObject.CharacteristicMemberTypes)] Type characteristicObjectType)\n        {\n            var fieldValues = characteristicObjectType.GetTypeInfo()\n                .GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy | BindingFlags.Static)\n                .Where(f => IsCharacteristicSubclass(f.FieldType))\n                .Select(f => AssertHasValue(f, (Characteristic?)f.GetValue(null)));\n\n            var propertyValues = characteristicObjectType.GetTypeInfo()\n                .GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy | BindingFlags.Static)\n                .Where(p => p.GetMethod != null && IsCharacteristicSubclass(p.PropertyType))\n                .Select(p => AssertHasValue(p, (Characteristic?)p.GetValue(null)));\n\n            // DONTTOUCH: DO NOT change the order of characteristic as it may break logic of some operations.\n            return fieldValues\n                .Concat(propertyValues)\n                .Distinct()\n                .OrderBy(k => k.HasChildCharacteristics ? 1 : 0)\n                .ThenBy(k => k.Id)\n                .ToArray();\n        }\n\n        private static readonly ConcurrentDictionary<Type, IReadOnlyList<Characteristic>> AllTypeCharacteristics =\n            new ConcurrentDictionary<Type, IReadOnlyList<Characteristic>>();\n\n        public static IReadOnlyList<Characteristic> GetAllCharacteristics(this CharacteristicObject obj) =>\n            GetAllCharacteristics(obj.GetType());\n\n        public static IReadOnlyList<Characteristic> GetAllCharacteristics(\n            [DynamicallyAccessedMembers(CharacteristicObject.CharacteristicMemberTypes)] Type characteristicObjectType)\n        {\n            if (!IsCharacteristicObjectSubclass(characteristicObjectType))\n                return EmptyCharacteristics;\n            return AllTypeCharacteristics.GetOrAdd(characteristicObjectType, GetAllCharacteristicsCore);\n        }\n\n        private static IReadOnlyList<Characteristic> GetAllCharacteristicsCore(\n            [DynamicallyAccessedMembers(CharacteristicObject.CharacteristicMemberTypes)] Type characteristicObjectType)\n        {\n            var result = new List<Characteristic>();\n\n            FillAllCharacteristicsCore(characteristicObjectType, result, []);\n\n            return result.ToArray();\n        }\n\n        private static void FillAllCharacteristicsCore(\n            [DynamicallyAccessedMembers(CharacteristicObject.CharacteristicMemberTypes)] Type characteristicObjectType,\n            List<Characteristic> result, HashSet<Characteristic> visited)\n        {\n            // DONTTOUCH: DO NOT change the order of characteristic as it may break logic of some operations.\n\n            var characteristics = GetThisTypeCharacteristics(characteristicObjectType);\n            foreach (var characteristic in characteristics.Where(c => !c.HasChildCharacteristics))\n            {\n                if (!visited.Add(characteristic))\n                    continue;\n\n                result.Add(characteristic);\n            }\n\n            foreach (var characteristic in characteristics.Where(c => c.HasChildCharacteristics))\n            {\n                if (!visited.Add(characteristic))\n                    continue;\n\n                result.Add(characteristic);\n                FillAllCharacteristicsCore(characteristic.CharacteristicType, result, visited);\n            }\n        }\n\n        public static IReadOnlyList<Characteristic> GetAllPresentableCharacteristics(\n            [DynamicallyAccessedMembers(CharacteristicObject.CharacteristicMemberTypes)] Type characteristicObjectType,\n            bool includeIgnoreOnApply = false) =>\n            GetAllCharacteristics(characteristicObjectType)\n                .Where(c => c.IsPresentableCharacteristic(includeIgnoreOnApply))\n                .ToArray();\n        #endregion\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Characteristics/CharacteristicObject.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Diagnostics.CodeAnalysis;\nusing System.Linq;\nusing System.Reflection;\nusing BenchmarkDotNet.Extensions;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Characteristics\n{\n    // TODO: better naming.\n    [DynamicallyAccessedMembers(CharacteristicMemberTypes)]\n    public abstract class CharacteristicObject\n    {\n        #region IdCharacteristic\n\n        internal const DynamicallyAccessedMemberTypes CharacteristicMemberTypes =\n            DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties\n            | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields;\n\n        protected static string ResolveId(CharacteristicObject obj, string? actual)\n        {\n            if (actual.IsNotBlank() && actual != IdCharacteristic.FallbackValue)\n                return actual;\n\n            string result = CharacteristicSetPresenter.Display.ToPresentation(obj);\n\n            if (result.Length == 0)\n                result = IdCharacteristic.FallbackValue!;\n\n            return result;\n        }\n\n        public static readonly Characteristic<string> IdCharacteristic = Characteristic.Create<CharacteristicObject, string>(nameof(Id), ResolveId, \"Default\", true);\n        #endregion\n\n        #region Fields & ctor\n\n        private Dictionary<Characteristic, object> sharedValues;\n        private bool frozen;\n\n        protected CharacteristicObject()\n        {\n            Owner = null;\n            sharedValues = [];\n        }\n\n        protected CharacteristicObject(string id) : this()\n        {\n            if (id.IsNotBlank())\n            {\n                IdCharacteristic[this] = id;\n            }\n        }\n        #endregion\n\n        #region Assertions\n\n        private void AssertNotFrozen()\n        {\n            if (Frozen)\n            {\n                throw new InvalidOperationException($\"The current object {this} is frozen. Create a copy to modify.\");\n            }\n        }\n\n        private void AssertIsRoot()\n        {\n            if (Owner != null)\n            {\n                throw new InvalidOperationException(\n                    \"The current operation allowed for root nodes only, \" +\n                    $\"but the value {this} is attached to another node, {Owner}.\");\n            }\n        }\n\n        private void AssertIsNonFrozenRoot()\n        {\n            AssertNotFrozen();\n            AssertIsRoot();\n        }\n\n        private static void AssertIsAssignable(Characteristic characteristic, object? value)\n        {\n            if (ReferenceEquals(value, Characteristic.EmptyValue) || ReferenceEquals(value, null))\n            {\n                if (characteristic.HasChildCharacteristics)\n                    throw new ArgumentNullException(characteristic.Id);\n\n                return;\n            }\n\n            if (!characteristic.CharacteristicType.GetTypeInfo().IsInstanceOfType(value))\n                throw new ArgumentException(\n                    $\"The value {value} is not assignable to {characteristic} property.\",\n                    characteristic.Id);\n        }\n        #endregion\n\n        #region Properties\n\n        private CharacteristicObject? Owner { get; set; }\n\n        protected CharacteristicObject OwnerOrSelf => Owner ?? this;\n\n        public bool Frozen => Owner?.Frozen ?? frozen;\n\n        protected virtual bool IsPropertyBag => false;\n\n        public bool HasChanges => GetCharacteristicsWithValues().Any(c => c.IsPresentableCharacteristic());\n        #endregion\n\n        #region  GetCharacteristics helpers\n        public IEnumerable<Characteristic> GetCharacteristicsWithValues() =>\n            IsPropertyBag\n                ? sharedValues.Keys.OrderBy(c => c.Id)\n                : this.GetAllCharacteristics().Where(HasValue);\n\n        private IEnumerable<Characteristic> GetCharacteristicsToApply() =>\n           IsPropertyBag\n                ? sharedValues.Keys.Where(c => !c.IgnoreOnApply).OrderBy(c => c.Id)\n                : this.GetAllCharacteristics().Where(c => !c.IgnoreOnApply);\n\n        private IEnumerable<Characteristic> GetCharacteristicsToApply(CharacteristicObject other)\n        {\n            var result = other.GetCharacteristicsToApply();\n            if (GetType() != other.GetType() && !IsPropertyBag)\n                result = result.Intersect(this.GetAllCharacteristics());\n\n            return result;\n        }\n        #endregion\n\n        #region Get or set value\n        #region Get value\n        public bool HasValue(Characteristic characteristic)\n        {\n            if (sharedValues.TryGetValue(characteristic, out var result))\n                return !ReferenceEquals(result, Characteristic.EmptyValue);\n\n            return false;\n        }\n\n        internal T? GetValue<[DynamicallyAccessedMembers(CharacteristicMemberTypes)] T>(Characteristic<T> characteristic)\n        {\n            return (T?)GetValue((Characteristic)characteristic);\n        }\n\n        internal object? GetValue(Characteristic characteristic)\n        {\n            if (!sharedValues.TryGetValue(characteristic, out var result))\n                result = Characteristic.EmptyValue;\n\n            return ResolveCore(characteristic, result);\n        }\n\n        private object? ResolveCore(Characteristic characteristic, object result)\n        {\n            return characteristic.ResolveValueCore(this, result);\n        }\n        #endregion\n\n        #region Resolve\n        public T? ResolveValue<[DynamicallyAccessedMembers(CharacteristicMemberTypes)] T>(Characteristic<T> characteristic, IResolver resolver)\n        {\n            return resolver.Resolve(this, characteristic);\n        }\n\n        public T? ResolveValue<[DynamicallyAccessedMembers(CharacteristicMemberTypes)] T>(Characteristic<T> characteristic, IResolver resolver, T defaultValue)\n        {\n            return resolver.Resolve(this, characteristic, defaultValue);\n        }\n\n        public object? ResolveValue(Characteristic characteristic, IResolver resolver)\n        {\n            return resolver.Resolve(this, characteristic);\n        }\n\n        public object? ResolveValue(Characteristic characteristic, IResolver resolver, object defaultValue)\n        {\n            return resolver.Resolve(this, characteristic, defaultValue);\n        }\n\n        public T? ResolveValue<[DynamicallyAccessedMembers(CharacteristicObject.CharacteristicMemberTypes)] T>(Characteristic<T> characteristic, T defaultValue)\n        {\n            return HasValue(characteristic) ? GetValue(characteristic) : (T?)characteristic.ResolveValueCore(this, defaultValue!);\n        }\n\n        [PublicAPI]\n        public object? ResolveValue(Characteristic characteristic, object defaultValue)\n        {\n            return HasValue(characteristic) ? GetValue(characteristic) : characteristic.ResolveValueCore(this, defaultValue);\n        }\n\n        public T? ResolveValueAsNullable<[DynamicallyAccessedMembers(CharacteristicMemberTypes)] T>(Characteristic<T> characteristic) where T : struct\n        {\n            return HasValue(characteristic) ? GetValue(characteristic) : (T?)null;\n        }\n        #endregion\n\n        #region Set value\n        internal void SetValue<[DynamicallyAccessedMembers(CharacteristicMemberTypes)] T>(Characteristic<T> characteristic, T value)\n        {\n            SetValue((Characteristic)characteristic, value);\n        }\n\n        internal void SetValue(Characteristic characteristic, object? value)\n        {\n            AssertNotFrozen();\n\n            if (characteristic.HasChildCharacteristics)\n            {\n                AssertIsAssignable(characteristic, value);\n\n                var oldObjectValue = (CharacteristicObject?)GetValue(characteristic);\n                var newObjectValue = (CharacteristicObject?)ResolveCore(characteristic, value!);\n\n                if (!ReferenceEquals(oldObjectValue, newObjectValue))\n                {\n                    oldObjectValue?.DetachFromOwner(characteristic);\n                    newObjectValue?.AttachToOwner(OwnerOrSelf, characteristic);\n                }\n            }\n            else\n            {\n                SetValueCore(characteristic, value);\n            }\n        }\n\n        private void SetValueCore(Characteristic characteristic, object? value)\n        {\n            AssertIsAssignable(characteristic, value);\n\n            if (ReferenceEquals(value, Characteristic.EmptyValue) || ReferenceEquals(value, null))\n            {\n                sharedValues.Remove(characteristic);\n            }\n            else\n            {\n                if (characteristic.HasChildCharacteristics)\n                {\n                    if (sharedValues.ContainsKey(characteristic))\n                        throw new ArgumentException(\n                            $\"The current node {this} has value for {characteristic} already.\",\n                            nameof(characteristic));\n\n                    var characteristicObject = (CharacteristicObject)ResolveCore(characteristic, value!)!;\n                    characteristicObject.SetOwnerCore(OwnerOrSelf);\n\n                    sharedValues[characteristic] = characteristicObject;\n                }\n                else\n                {\n                    sharedValues[characteristic] = value;\n                }\n            }\n        }\n\n        private void SetOwnerCore(CharacteristicObject newOwner)\n        {\n            AssertNotFrozen();\n            newOwner.AssertIsNonFrozenRoot();\n\n            Owner = newOwner;\n            sharedValues = newOwner.sharedValues;\n            frozen = false;\n        }\n\n        private void DetachFromOwner(Characteristic thisCharacteristic)\n        {\n            AssertNotFrozen();\n            if (IsPropertyBag)\n                throw new InvalidOperationException(\"The property bag has no owner.\");\n\n            if (Owner == null)\n                return;\n\n            var oldValues = sharedValues;\n\n            Owner = null;\n            sharedValues = [];\n            frozen = false;\n\n            oldValues.Remove(thisCharacteristic);\n            foreach (var characteristic in GetCharacteristicsToApply())\n            {\n                if (oldValues.TryGetValue(characteristic, out var value))\n                {\n                    oldValues.Remove(characteristic);\n                    SetValueCore(characteristic, value);\n                }\n            }\n        }\n\n        private void AttachToOwner(CharacteristicObject newOwner, Characteristic thisCharacteristic)\n        {\n            if (IsPropertyBag)\n                throw new InvalidOperationException(\n                    $\"The property bag {this} cannot be used as characteristic's value.\");\n\n            AssertIsNonFrozenRoot();\n            newOwner.AssertIsNonFrozenRoot();\n\n            var oldValues = sharedValues;\n\n            newOwner.SetValueOnAttach(thisCharacteristic, this);\n            foreach (var pair in oldValues)\n            {\n                newOwner.SetValueOnAttach(pair.Key, pair.Value);\n            }\n        }\n\n        private void SetValueOnAttach(Characteristic characteristic, object value)\n        {\n            AssertIsAssignable(characteristic, value);\n\n            if (characteristic.HasChildCharacteristics)\n            {\n                // DONTTOUCH: workaround on case there were no parent characteristic.\n                var characteristicObject = (CharacteristicObject?)GetValue(characteristic);\n                characteristicObject?.DetachFromOwner(characteristic);\n            }\n\n            SetValueCore(characteristic, value);\n        }\n        #endregion\n        #endregion\n\n        #region Apply\n\n        [PublicAPI]\n        public void Apply(CharacteristicObject other) => ApplyCore(other);\n\n        protected CharacteristicObject ApplyCore(CharacteristicObject other) =>\n            ApplyCore(\n                other,\n                GetCharacteristicsToApply(other));\n\n        private CharacteristicObject ApplyCore(\n            CharacteristicObject? other,\n            IEnumerable<Characteristic> characteristicsToApply)\n        {\n            AssertNotFrozen();\n\n            if (other == null)\n                return this;\n\n            foreach (var characteristic in characteristicsToApply)\n            {\n                if (!other.sharedValues.TryGetValue(characteristic, out var value))\n                    continue;\n\n                if (characteristic.HasChildCharacteristics)\n                {\n                    if (!HasValue(characteristic))\n                    {\n                        var characteristicObject = (CharacteristicObject?)ResolveCore(characteristic, value);\n                        if (characteristicObject != null)\n                        {\n                            value = Activator.CreateInstance(characteristicObject.GetType());\n                        }\n\n                        SetValueCore(characteristic, value!);\n                    }\n                }\n                else\n                {\n                    SetValueCore(characteristic, value);\n                }\n            }\n\n            return this;\n        }\n        #endregion\n\n        #region Freeze / unfreeze\n\n        [PublicAPI]\n        public void Freeze() => FreezeCore();\n\n        protected CharacteristicObject FreezeCore()\n        {\n            AssertIsRoot();\n\n            if (!frozen)\n                frozen = true;\n\n            return this;\n        }\n\n        [PublicAPI]\n        public CharacteristicObject UnfreezeCopy() => UnfreezeCopyCore();\n\n        protected CharacteristicObject UnfreezeCopyCore()\n        {\n            AssertIsRoot();\n\n            var newRoot = (CharacteristicObject)Activator.CreateInstance(GetType())!;\n            newRoot.ApplyCore(this);\n\n            // Preserve the IdCharacteristic of the original object\n            if (this.HasValue(IdCharacteristic))\n            {\n                newRoot.SetValue(IdCharacteristic, this.GetValue(IdCharacteristic)!);\n            }\n\n            return newRoot;\n        }\n        #endregion\n\n        public string Id => IdCharacteristic[this]!;\n\n        public override string ToString() => Id;\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Characteristics/CharacteristicObject`1.cs",
    "content": "﻿using System.Diagnostics.CodeAnalysis;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Characteristics\n{\n    public abstract class CharacteristicObject<T> : CharacteristicObject\n        where T : CharacteristicObject<T>, new()\n    {\n        protected CharacteristicObject() { }\n\n        protected CharacteristicObject(string id) : base(id) { }\n\n        public new T Apply(CharacteristicObject other) => (T)ApplyCore(other);\n\n        [PublicAPI]\n        public T Apply(params CharacteristicObject[] others)\n        {\n            var result = this;\n            foreach (var other in others)\n            {\n                result.Apply(other);\n            }\n            return (T)result;\n        }\n\n        [PublicAPI]\n        public T ApplyAndFreeze(CharacteristicObject other) => Apply(other).Freeze();\n\n        [PublicAPI]\n        public T ApplyAndFreeze(params CharacteristicObject[] others) => Apply(others).Freeze();\n\n        public new T Freeze() => (T)FreezeCore();\n\n        public new T UnfreezeCopy() => (T)UnfreezeCopyCore();\n\n        protected static Characteristic<TC> CreateCharacteristic<[DynamicallyAccessedMembers(CharacteristicMemberTypes)] TC>(string memberName) => Characteristic.Create<T, TC>(memberName);\n\n        protected static Characteristic<TC> CreateHiddenCharacteristic<[DynamicallyAccessedMembers(CharacteristicMemberTypes)] TC>(string memberName) => Characteristic.CreateHidden<T, TC>(memberName);\n\n        protected static Characteristic<TC> CreateIgnoreOnApplyCharacteristic<[DynamicallyAccessedMembers(CharacteristicMemberTypes)] TC>(string memberName) => Characteristic.CreateIgnoreOnApply<T, TC>(memberName);\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Characteristics/CharacteristicPresenter.cs",
    "content": "﻿using System;\nusing System.Collections;\nusing System.Text;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Helpers;\nusing BenchmarkDotNet.Jobs;\n\nnamespace BenchmarkDotNet.Characteristics\n{\n    public abstract class CharacteristicPresenter\n    {\n        public static readonly CharacteristicPresenter DefaultPresenter = new DefaultCharacteristicPresenter();\n        public static readonly CharacteristicPresenter FolderPresenter = new FolderCharacteristicPresenter();\n        public static readonly CharacteristicPresenter SummaryPresenter = new DefaultCharacteristicPresenter();\n        public static readonly CharacteristicPresenter SourceCodePresenter = new SourceCodeCharacteristicPresenter();\n\n        public abstract string ToPresentation(CharacteristicObject obj, Characteristic characteristic);\n\n        public abstract string ToPresentation(object? characteristicValue, Characteristic characteristic);\n\n        private class DefaultCharacteristicPresenter : CharacteristicPresenter\n        {\n            public override string ToPresentation(CharacteristicObject obj, Characteristic characteristic)\n            {\n                if (characteristic == CharacteristicObject.IdCharacteristic && obj is Job job)\n                    return job.ResolvedId;\n\n                return obj.HasValue(characteristic)\n                    ? ToPresentation(characteristic[obj]!, characteristic)\n                    : \"Default\";\n            }\n\n            public override string ToPresentation(object? value, Characteristic characteristic)\n            {\n                if (!(value is string) && value is IEnumerable collection)\n                    return ToPresentation(collection);\n\n                if (characteristic == EnvironmentMode.AffinityCharacteristic && value is IntPtr intPtr)\n                    return intPtr.ToPresentation(Environment.ProcessorCount);\n\n                if (characteristic == EnvironmentMode.PowerPlanModeCharacteristic && value is Guid guid && guid == Guid.Empty)\n                    return \"\"; // Replace Guid.Empty to empty string.\n\n                return ToPresentation(value);\n            }\n\n            // string.Join(separator, nonGenericCollection) is translated to string.Join(separator, params object[]) with single object!! (collection)\n            // and ends up with exact the same output as collection.ToString() (typeName[])\n            // so I needed to implement this on my own\n            private static string ToPresentation(IEnumerable collection)\n            {\n                var buffer = new StringBuilder();\n                bool first = true;\n                foreach (var item in collection)\n                {\n                    if (!first)\n                        buffer.Append(',');\n                    else\n                        first = false;\n\n                    buffer.Append(ToPresentation(item));\n                }\n\n                if (buffer.Length == 0)\n                    return \"Empty\";\n\n                return buffer.ToString();\n            }\n\n            private static string ToPresentation(object? value)\n                => (value as IFormattable)?.ToString(null, DefaultCultureInfo.Instance)\n                      ?? value?.ToString()\n                      ?? \"\";\n        }\n\n        private class SourceCodeCharacteristicPresenter : CharacteristicPresenter\n        {\n            public override string ToPresentation(CharacteristicObject obj, Characteristic characteristic)\n                => ToPresentation(characteristic[obj], characteristic);\n\n            public override string ToPresentation(object? characteristicValue, Characteristic characteristic)\n            {\n                // TODO: DO NOT hardcode Characteristic suffix\n                string id = characteristic.Id;\n                string type = characteristic.DeclaringType.GetCorrectCSharpTypeName();\n                string value = SourceCodeHelper.ToSourceCode(characteristicValue);\n                return $\"{type}.{id}Characteristic[job] = {value}\";\n            }\n        }\n\n        private class FolderCharacteristicPresenter : CharacteristicPresenter\n        {\n            public override string ToPresentation(CharacteristicObject obj, Characteristic characteristic)\n                => obj.HasValue(characteristic)\n                    ? ToPresentation(characteristic[obj], characteristic)\n                    : \"Default\";\n\n            public override string ToPresentation(object? characteristicValue, Characteristic characteristic)\n                => FolderNameHelper.ToFolderName(characteristicValue);\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Characteristics/CharacteristicSet.cs",
    "content": "﻿using JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Characteristics\n{\n    public sealed class CharacteristicSet : CharacteristicObject<CharacteristicSet>\n    {\n        [PublicAPI] public CharacteristicSet() => Apply();\n        [PublicAPI] public CharacteristicSet(CharacteristicObject other) => Apply(other);\n        [PublicAPI] public CharacteristicSet(params CharacteristicObject[] others) => Apply(others);\n\n        protected override bool IsPropertyBag => true;\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Characteristics/CharacteristicSetPresenter.cs",
    "content": "﻿using BenchmarkDotNet.Diagnosers;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Toolchains;\nusing JetBrains.Annotations;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\n\nnamespace BenchmarkDotNet.Characteristics\n{\n    public abstract class CharacteristicSetPresenter\n    {\n        [PublicAPI] public static readonly CharacteristicSetPresenter Default = new DefaultPresenter();\n        [PublicAPI] public static readonly CharacteristicSetPresenter Display = new DisplayPresenter();\n        [PublicAPI] public static readonly CharacteristicSetPresenter Folder = new FolderPresenter();\n        [PublicAPI] public static readonly CharacteristicSetPresenter SourceCode = new SourceCodePresenter();\n\n        public abstract string ToPresentation(CharacteristicObject obj);\n\n        protected virtual IEnumerable<Characteristic> GetPresentableCharacteristics(CharacteristicObject obj, bool includeIgnoreOnApply = false) =>\n            obj\n                .GetCharacteristicsWithValues()\n                .Where(c => c.IsPresentableCharacteristic(includeIgnoreOnApply));\n\n        private class DefaultPresenter : CharacteristicSetPresenter\n        {\n            private const string Separator = \"&\";\n            private static readonly CharacteristicPresenter CharacteristicPresenter = CharacteristicPresenter.DefaultPresenter;\n\n            public override string ToPresentation(CharacteristicObject obj)\n            {\n                var values = GetPresentableCharacteristics(obj)\n                    .Select(c => c.FullId + \"=\" + CharacteristicPresenter.ToPresentation(obj, c));\n                return string.Join(Separator, values);\n            }\n        }\n\n        private class FolderPresenter : CharacteristicSetPresenter\n        {\n            private const string Separator = \"_\";\n            private const string EqualsSeparator = \"-\";\n            private static readonly CharacteristicPresenter CharacteristicPresenter = CharacteristicPresenter.FolderPresenter;\n\n            public override string ToPresentation(CharacteristicObject obj)\n            {\n                var values = GetPresentableCharacteristics(obj)\n                    .Select(c => c.Id + EqualsSeparator + CharacteristicPresenter.ToPresentation(obj, c));\n                return string.Join(Separator, values);\n            }\n        }\n\n        private class DisplayPresenter : CharacteristicSetPresenter\n        {\n            private const string Separator = \", \";\n            private static readonly CharacteristicPresenter CharacteristicPresenter = CharacteristicPresenter.DefaultPresenter;\n\n            public override string ToPresentation(CharacteristicObject obj)\n            {\n                var values = GetPresentableCharacteristics(obj)\n                    .Select(c => (c.Id, Value: CharacteristicPresenter.ToPresentation(obj, c)))\n                    .Where(x => x.Value != \"\")\n                    .Select(x => $\"{x.Id}={x.Value}\");\n                return string.Join(Separator, values);\n            }\n        }\n\n        private class SourceCodePresenter : CharacteristicSetPresenter\n        {\n            private const string Separator = \"; \";\n            private static readonly CharacteristicPresenter CharacteristicPresenter = CharacteristicPresenter.SourceCodePresenter;\n            private static readonly HashSet<Type> NonExportableTypes =\n            [\n                typeof(IToolchain), // there is no need to set toolchain in child process, it was causing parameterless ctor requirement for all IToolchain implementations\n                typeof(IReadOnlyCollection<HardwareCounter>), // we don't need to export this array to child process\n                typeof(IReadOnlyList<Argument>),\n                typeof(IReadOnlyList<EnvironmentVariable>),\n                typeof(Runtime) // there is no need to set runtime in child process, it was causing parameterless ctor requirement for all Runtime implementations\n            ];\n\n            public override string ToPresentation(CharacteristicObject obj)\n                => string.Join(Separator,\n                        GetPresentableCharacteristics(obj, includeIgnoreOnApply: true)\n                            .Select(c => CharacteristicPresenter.ToPresentation(obj, c)));\n\n            protected override IEnumerable<Characteristic> GetPresentableCharacteristics(CharacteristicObject obj, bool includeIgnoreOnApply = false)\n                => base.GetPresentableCharacteristics(obj, includeIgnoreOnApply)\n                       .Where(characteristic => !NonExportableTypes.Contains(characteristic.CharacteristicType));\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Characteristics/Characteristic`1.cs",
    "content": "﻿using System;\nusing System.Diagnostics.CodeAnalysis;\n\nnamespace BenchmarkDotNet.Characteristics\n{\n    public class Characteristic<[DynamicallyAccessedMembers(CharacteristicObject.CharacteristicMemberTypes)] T> : Characteristic\n    {\n        internal Characteristic(\n            string id,\n            Type declaringType,\n            Func<CharacteristicObject, T?, T>? resolver,\n            T? fallbackValue,\n            bool ignoreOnApply,\n            bool dontShowInSummary = false)\n            : base(id, typeof(T), declaringType, fallbackValue, ignoreOnApply, dontShowInSummary)\n        {\n            Resolver = resolver;\n            FallbackValue = fallbackValue;\n        }\n\n        private Func<CharacteristicObject, T?, T>? Resolver { get; }\n\n        public T? FallbackValue { get; }\n\n        public new T? this[CharacteristicObject obj]\n        {\n            get { return obj.GetValue(this); }\n            set { obj.SetValue(this, value); }\n        }\n\n        internal override object? ResolveValueCore(CharacteristicObject obj, object? currentValue)\n        {\n            if (Resolver == null)\n                return (T?)base.ResolveValueCore(obj, currentValue);\n\n            return Resolver(obj, (T?)base.ResolveValueCore(obj, currentValue));\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Characteristics/CompositeResolver.cs",
    "content": "﻿using System;\nusing System.Diagnostics.CodeAnalysis;\nusing System.Linq;\n\nnamespace BenchmarkDotNet.Characteristics\n{\n    public class CompositeResolver : IResolver\n    {\n        private readonly IResolver[] resolvers;\n\n        public CompositeResolver(params IResolver[] resolvers)\n        {\n            this.resolvers = resolvers;\n        }\n\n        public bool CanResolve(Characteristic characteristic) => resolvers.Any(r => r.CanResolve(characteristic));\n\n        public object? Resolve(CharacteristicObject obj, Characteristic characteristic)\n        {\n            if (obj.HasValue(characteristic))\n                return characteristic[obj];\n\n            var resolver = resolvers.FirstOrDefault(r => r.CanResolve(characteristic));\n            if (resolver != null)\n                return resolver.Resolve(obj, characteristic);\n            throw new InvalidOperationException($\"There is no default resolver for {characteristic.FullId}\");\n        }\n\n        public T? Resolve<[DynamicallyAccessedMembers(CharacteristicObject.CharacteristicMemberTypes)] T>(CharacteristicObject obj, Characteristic<T> characteristic)\n        {\n            if (obj.HasValue(characteristic))\n                return characteristic[obj];\n\n            var resolver = resolvers.FirstOrDefault(r => r.CanResolve(characteristic));\n            if (resolver != null)\n                return resolver.Resolve(obj, characteristic);\n            throw new InvalidOperationException($\"There is no default resolver for {characteristic.FullId}\");\n        }\n\n        public object? Resolve(CharacteristicObject obj, Characteristic characteristic, object defaultValue)\n        {\n            if (obj.HasValue(characteristic))\n                return characteristic[obj];\n\n            var resolver = resolvers.FirstOrDefault(r => r.CanResolve(characteristic));\n            if (resolver != null)\n                return resolver.Resolve(obj, characteristic, defaultValue);\n            return defaultValue;\n        }\n\n        public T? Resolve<[DynamicallyAccessedMembers(CharacteristicObject.CharacteristicMemberTypes)] T>(CharacteristicObject obj, Characteristic<T> characteristic, T defaultValue)\n        {\n            if (obj.HasValue(characteristic))\n                return characteristic[obj];\n\n            var resolver = resolvers.FirstOrDefault(r => r.CanResolve(characteristic));\n            if (resolver != null)\n                return resolver.Resolve(obj, characteristic, defaultValue);\n            return defaultValue;\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Characteristics/IResolver.cs",
    "content": "﻿using System.Diagnostics.CodeAnalysis;\n\nnamespace BenchmarkDotNet.Characteristics\n{\n    /// <summary>\n    /// An entity which can resolve default values of <see cref=\"Characteristic{T}\"/>.\n    /// </summary>\n    public interface IResolver\n    {\n        bool CanResolve(Characteristic characteristic);\n\n        object? Resolve(CharacteristicObject obj, Characteristic characteristic);\n\n        T? Resolve<[DynamicallyAccessedMembers(CharacteristicObject.CharacteristicMemberTypes)] T>(CharacteristicObject obj, Characteristic<T> characteristic);\n\n        object? Resolve(CharacteristicObject obj, Characteristic characteristic, object defaultValue);\n\n        T? Resolve<[DynamicallyAccessedMembers(CharacteristicObject.CharacteristicMemberTypes)] T>(CharacteristicObject obj, Characteristic<T> characteristic, T defaultValue);\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Characteristics/Resolver.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Diagnostics.CodeAnalysis;\n\nnamespace BenchmarkDotNet.Characteristics\n{\n    public class Resolver : IResolver\n    {\n        private readonly Dictionary<Characteristic, Func<CharacteristicObject, object?>> resolvers = [];\n\n        protected void Register<[DynamicallyAccessedMembers(CharacteristicObject.CharacteristicMemberTypes)] T>(Characteristic<T> characteristic, Func<T?> resolver) =>\n            resolvers[characteristic] = obj => resolver();\n\n        protected void Register<[DynamicallyAccessedMembers(CharacteristicObject.CharacteristicMemberTypes)] T>(Characteristic<T> characteristic, Func<CharacteristicObject, T?> resolver) =>\n            resolvers[characteristic] = obj => resolver(obj);\n\n        public bool CanResolve(Characteristic characteristic) => resolvers.ContainsKey(characteristic);\n\n        public object? Resolve(CharacteristicObject obj, Characteristic characteristic)\n        {\n            if (obj.HasValue(characteristic))\n                return characteristic[obj];\n\n            if (resolvers.TryGetValue(characteristic, out var resolver))\n                return resolver(obj);\n            throw new InvalidOperationException($\"There is no default resolver for {characteristic.FullId}\");\n        }\n\n        public T? Resolve<[DynamicallyAccessedMembers(CharacteristicObject.CharacteristicMemberTypes)] T>(CharacteristicObject obj, Characteristic<T> characteristic)\n        {\n            if (obj.HasValue(characteristic))\n                return characteristic[obj];\n\n            if (resolvers.TryGetValue(characteristic, out var resolver))\n                return (T?)resolver(obj);\n            throw new InvalidOperationException($\"There is no default resolver for {characteristic.FullId}\");\n        }\n\n        public object? Resolve(CharacteristicObject obj, Characteristic characteristic, object defaultValue)\n        {\n            if (obj.HasValue(characteristic))\n                return characteristic[obj];\n\n            if (resolvers.TryGetValue(characteristic, out var resolver))\n                return resolver(obj);\n\n            return defaultValue;\n        }\n\n        public T? Resolve<[DynamicallyAccessedMembers(CharacteristicObject.CharacteristicMemberTypes)] T>(CharacteristicObject obj, Characteristic<T> characteristic, T defaultValue)\n        {\n            if (obj.HasValue(characteristic))\n                return characteristic[obj];\n\n            if (resolvers.TryGetValue(characteristic, out var resolver))\n                return (T?)resolver(obj);\n\n            return defaultValue;\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Code/ArrayParam.cs",
    "content": "using System;\nusing System.Linq;\nusing System.Reflection;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Helpers;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Code\n{\n    internal static class ArrayParam\n    {\n        private static (string BaseElementTypeRepr, string InnerDimensions) GetDisplayString(Type arrayType)\n        {\n            var elemType = arrayType.GetElementType()!;\n\n            if (elemType.IsArray)\n            {\n                var (baseElementTypeRepr, innerDimensions) = GetDisplayString(elemType);\n\n                return (baseElementTypeRepr, $\"[{new string(',', arrayType.GetArrayRank() - 1)}]{innerDimensions}\");\n            }\n\n            return (elemType.GetDisplayName(), $\"[{new string(',', arrayType.GetArrayRank() - 1)}]\");\n        }\n\n        public static string GetDisplayString(Array array)\n        {\n            string dimensionRepr = string.Join(\", \", Enumerable.Range(0, array.Rank).Select(array.GetLength));\n\n            var (baseElementTypeRepr, innerDimensions) = GetDisplayString(array.GetType());\n\n            innerDimensions = string.Join(\"\", innerDimensions.Split([']'], count: 2).Skip(1));\n\n            return $\"{baseElementTypeRepr}[{dimensionRepr}]{innerDimensions}\";\n        }\n    }\n\n    public class ArrayParam<T> : IParam\n    {\n        private readonly T[] array;\n        private readonly Func<T, string>? toSourceCode;\n\n        private ArrayParam(T[] array, Func<T, string>? toSourceCode = null)\n        {\n            this.array = array;\n            this.toSourceCode = toSourceCode;\n        }\n\n        public object Value => array;\n\n        public string DisplayText => ArrayParam.GetDisplayString(array);\n\n        public string ToSourceCode()\n            => $\"new {typeof(T).GetCorrectCSharpTypeName()}[] {{ {string.Join(\", \", array.Select(item => toSourceCode?.Invoke(item) ?? SourceCodeHelper.ToSourceCode(item)))} }}\";\n\n        /// <summary>\n        /// for types where calling .ToString() will be enough to re-create them in auto-generated source code file (integers, strings and other primitives)\n        /// </summary>\n        public static ArrayParam<T> ForPrimitives(T[] array) => new ArrayParam<T>(array);\n\n        /// <summary>\n        /// for types where calling .ToString() will be NOT enough to re-create them in auto-generated source code file\n        /// </summary>\n        /// <param name=\"array\">the array</param>\n        /// <param name=\"toSourceCode\">method which transforms an item of type T to it's C# representation\n        /// example: point => $\"new Point2d({point.X}, {point.Y})\"\n        /// </param>\n        [PublicAPI] public static ArrayParam<T> ForComplexTypes(T[] array, Func<T, string> toSourceCode) => new ArrayParam<T>(array, toSourceCode);\n\n        internal static IParam? FromObject(object array)\n        {\n            var type = array.GetType();\n            if (!type.IsArray)\n                throw new InvalidOperationException(\"The argument must be an array\");\n            var elementType = type.GetElementType();\n            if (elementType == null)\n                throw new InvalidOperationException(\"Failed to determine type of array elements\");\n            if (!SourceCodeHelper.IsCompilationTimeConstant(elementType))\n                throw new InvalidOperationException(\"The argument must be an array of primitives\");\n\n            var arrayParamType = typeof(ArrayParam<>).MakeGenericType(elementType);\n\n            var methodInfo = arrayParamType.GetMethod(nameof(ForPrimitives), BindingFlags.Public | BindingFlags.Static)\n                ?? throw new InvalidOperationException($\"{nameof(ForPrimitives)} not found\");\n            return (IParam?)methodInfo.Invoke(null, [array]);\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Code/CodeGenBenchmarkRunCallType.cs",
    "content": "﻿namespace BenchmarkDotNet.Code;\n\n/// <summary>\n/// Specifies how to generate the code that calls the benchmark's Run method.\n/// </summary>\npublic enum CodeGenBenchmarkRunCallType\n{\n    /// <summary>\n    /// Use reflection to call the benchmark's Run method indirectly.\n    /// </summary>\n    /// <remarks>\n    /// This is to avoid strong dependency Main-to-Runnable\n    /// which could cause the jitting/assembly loading to happen before we do anything.\n    /// We have some jitting diagnosers and we want them to catch all the informations.\n    /// </remarks>\n    Reflection,\n    /// <summary>\n    /// Uses a switch to select the benchmark to call Run directly.\n    /// </summary>\n    /// <remarks>\n    /// This is for AOT runtimes where reflection may not exist or the benchmark types\n    /// could be trimmed out when they are not directly referenced.\n    /// </remarks>\n    Direct\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Code/CodeGenerator.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Text;\nusing System.Threading.Tasks;\nusing BenchmarkDotNet.Characteristics;\nusing BenchmarkDotNet.Diagnosers;\nusing BenchmarkDotNet.Disassemblers;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Helpers;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Parameters;\nusing BenchmarkDotNet.Running;\nusing RunMode = BenchmarkDotNet.Jobs.RunMode;\n\nnamespace BenchmarkDotNet.Code\n{\n    internal static class CodeGenerator\n    {\n        internal static string Generate(BuildPartition buildPartition, CodeGenBenchmarkRunCallType benchmarkRunCallType)\n        {\n            (bool useShadowCopy, string shadowCopyFolderPath) = GetShadowCopySettings();\n\n            var benchmarksCode = new List<string>(buildPartition.Benchmarks.Length);\n\n            foreach (var buildInfo in buildPartition.Benchmarks)\n            {\n                var benchmark = buildInfo.BenchmarkCase;\n\n                var provider = GetDeclarationsProvider(benchmark.Descriptor);\n\n                string passArguments = GetPassArguments(benchmark);\n\n                string benchmarkTypeCode = new SmartStringBuilder(ResourceHelper.LoadTemplate(\"BenchmarkType.txt\"))\n                    .Replace(\"$ID$\", buildInfo.Id.ToString())\n                    .Replace(\"$OperationsPerInvoke$\", provider.OperationsPerInvoke)\n                    .Replace(\"$WorkloadTypeName$\", provider.WorkloadTypeName)\n                    .Replace(\"$GlobalSetupMethodName$\", provider.GlobalSetupMethodName)\n                    .Replace(\"$GlobalCleanupMethodName$\", provider.GlobalCleanupMethodName)\n                    .Replace(\"$IterationSetupMethodName$\", provider.IterationSetupMethodName)\n                    .Replace(\"$IterationCleanupMethodName$\", provider.IterationCleanupMethodName)\n                    .Replace(\"$JobSetDefinition$\", GetJobsSetDefinition(benchmark))\n                    .Replace(\"$ParamsContent$\", GetParamsContent(benchmark))\n                    .Replace(\"$ArgumentsDefinition$\", GetArgumentsDefinition(benchmark))\n                    .Replace(\"$DeclareArgumentFields$\", GetDeclareArgumentFields(benchmark))\n                    .Replace(\"$InitializeArgumentFields$\", GetInitializeArgumentFields(benchmark))\n                    .Replace(\"$LoadArguments$\", GetLoadArguments(benchmark))\n                    .Replace(\"$PassArguments$\", passArguments)\n                    .Replace(\"$EngineFactoryType$\", GetEngineFactoryTypeName(benchmark))\n                    .Replace(\"$RunExtraIteration$\", buildInfo.Config.HasExtraIterationDiagnoser(benchmark) ? \"true\" : \"false\")\n                    .Replace(\"$DisassemblerEntryMethodName$\", DisassemblerConstants.DisassemblerEntryMethodName)\n                    .Replace(\"$WorkloadMethodCall$\", provider.GetWorkloadMethodCall(passArguments))\n                    .Replace(\"$InProcessDiagnoserRouters$\", GetInProcessDiagnoserRouters(buildInfo))\n                    .ToString();\n\n                benchmarkTypeCode = Unroll(benchmarkTypeCode, benchmark.Job.ResolveValue(RunMode.UnrollFactorCharacteristic, EnvironmentResolver.Instance));\n\n                benchmarksCode.Add(benchmarkTypeCode);\n            }\n\n            string benchmarkProgramContent = new SmartStringBuilder(ResourceHelper.LoadTemplate(\"BenchmarkProgram.txt\"))\n                .Replace(\"$ShadowCopyDefines$\", useShadowCopy ? \"#define SHADOWCOPY\" : null).Replace(\"$ShadowCopyFolderPath$\", shadowCopyFolderPath)\n                .Replace(\"$ExtraDefines$\", buildPartition.IsNetFramework ? \"#define NETFRAMEWORK\" : string.Empty)\n                .Replace(\"$DerivedTypes$\", string.Join(Environment.NewLine, benchmarksCode))\n                .Replace(\"$ExtraAttribute$\", GetExtraAttributes(buildPartition.RepresentativeBenchmarkCase.Descriptor))\n                .Replace(\"$BenchmarkRunCall$\", GetBenchmarkRunCall(buildPartition, benchmarkRunCallType))\n                .ToString();\n\n            return benchmarkProgramContent;\n        }\n\n        private static void AddNonEmptyUnique(HashSet<string> items, string value)\n        {\n            if (value.IsNotBlank())\n                items.Add(value);\n        }\n\n        private static (bool, string) GetShadowCopySettings()\n        {\n            string benchmarkDotNetLocation = Path.GetDirectoryName(typeof(CodeGenerator).GetTypeInfo().Assembly.Location)!;\n\n            if (benchmarkDotNetLocation != null && benchmarkDotNetLocation.IndexOf(\"LINQPAD\", StringComparison.OrdinalIgnoreCase) >= 0)\n            {\n                /* \"LINQPad normally puts the compiled query into a different folder than the referenced assemblies\n                 * - this allows for optimizations to reduce file I/O, which is important in the scratchpad scenario\"\n                 *\n                 * so in case we detect we are running from LINQPad, we give a hint to assembly loading to search also in this folder\n                 */\n\n                return (true, benchmarkDotNetLocation);\n            }\n\n            return (false, string.Empty);\n        }\n\n        private static string Unroll(string text, int factor)\n        {\n            const string unrollDirective = \"@Unroll@\";\n            var oldLines = text.Split('\\n');\n            var newLines = new List<string>();\n            foreach (string line in oldLines)\n            {\n                if (line.Contains(unrollDirective))\n                {\n                    string newLine = line.Replace(unrollDirective, \"\");\n                    for (int i = 0; i < factor; i++)\n                        newLines.Add(newLine);\n                }\n                else\n                    newLines.Add(line);\n            }\n            return string.Join(\"\\n\", newLines);\n        }\n\n        private static string GetJobsSetDefinition(BenchmarkCase benchmarkCase)\n        {\n            return CharacteristicSetPresenter.SourceCode.\n                ToPresentation(benchmarkCase.Job).\n                Replace(\"; \", \";\\n                \");\n        }\n\n        private static DeclarationsProvider GetDeclarationsProvider(Descriptor descriptor)\n        {\n            var method = descriptor.WorkloadMethod;\n\n            if (method.ReturnType == typeof(Task) || method.ReturnType == typeof(ValueTask))\n            {\n                return new AsyncDeclarationsProvider(descriptor);\n            }\n            if (method.ReturnType.GetTypeInfo().IsGenericType\n                && (method.ReturnType.GetTypeInfo().GetGenericTypeDefinition() == typeof(Task<>)\n                    || method.ReturnType.GetTypeInfo().GetGenericTypeDefinition() == typeof(ValueTask<>)))\n            {\n                return new AsyncDeclarationsProvider(descriptor);\n            }\n\n            if (method.ReturnType == typeof(void) && method.HasAttribute<AsyncStateMachineAttribute>())\n            {\n                throw new NotSupportedException(\"async void is not supported by design\");\n            }\n\n            return new SyncDeclarationsProvider(descriptor);\n        }\n\n        // internal for tests\n\n        internal static string GetParamsContent(BenchmarkCase benchmarkCase)\n            => string.Join(\n                string.Empty,\n                benchmarkCase.Parameters.Items\n                    .Where(parameter => !parameter.IsArgument)\n                    .Select(parameter => $\"{(parameter.IsStatic ? benchmarkCase.Descriptor.Type.GetCorrectCSharpTypeName() : \"base\")}.{parameter.Name} = {parameter.ToSourceCode()};\"));\n\n        private static string GetArgumentsDefinition(BenchmarkCase benchmarkCase)\n            => string.Join(\n                \", \",\n                benchmarkCase.Descriptor.WorkloadMethod.GetParameters()\n                         .Select((parameter, index) => $\"{GetParameterModifier(parameter)} {parameter.ParameterType.GetCorrectCSharpTypeName()} arg{index}\"));\n\n        private static string GetDeclareArgumentFields(BenchmarkCase benchmarkCase)\n            => string.Join(\n                Environment.NewLine,\n                benchmarkCase.Descriptor.WorkloadMethod.GetParameters()\n                         .Select((parameter, index) => $\"private {GetFieldType(parameter.ParameterType, benchmarkCase.Parameters.GetArgument(parameter.Name!)).GetCorrectCSharpTypeName()} __argField{index};\"));\n\n        private static string GetInitializeArgumentFields(BenchmarkCase benchmarkCase)\n            => string.Join(\n                Environment.NewLine,\n                benchmarkCase.Descriptor.WorkloadMethod.GetParameters()\n                    .Select((parameter, index) => $\"this.__argField{index} = {benchmarkCase.Parameters.GetArgument(parameter.Name!).ToSourceCode()};\")); // we init the fields in ctor to provoke all possible allocations and overhead of other type\n\n        private static string GetLoadArguments(BenchmarkCase benchmarkCase)\n            => string.Join(\n                Environment.NewLine,\n                benchmarkCase.Descriptor.WorkloadMethod.GetParameters()\n                    .Select((parameter, index) => $\"{(parameter.ParameterType.IsByRef ? \"ref\" : string.Empty)} {parameter.ParameterType.GetCorrectCSharpTypeName()} arg{index} = {(parameter.ParameterType.IsByRef ? \"ref\" : string.Empty)} this.__argField{index};\"));\n\n        private static string GetPassArguments(BenchmarkCase benchmarkCase)\n            => string.Join(\n                \", \",\n                benchmarkCase.Descriptor.WorkloadMethod.GetParameters()\n                    .Select((parameter, index) => $\"{GetParameterModifier(parameter)} arg{index}\"));\n\n        private static string GetExtraAttributes(Descriptor descriptor)\n            => descriptor.WorkloadMethod.GetCustomAttributes(false).OfType<STAThreadAttribute>().Any() ? \"[System.STAThreadAttribute]\" : string.Empty;\n\n        private static string GetEngineFactoryTypeName(BenchmarkCase benchmarkCase)\n        {\n            var factory = benchmarkCase.Job.ResolveValue(InfrastructureMode.EngineFactoryCharacteristic, InfrastructureResolver.Instance)!;\n            var factoryType = factory.GetType();\n\n            if (!factoryType.GetTypeInfo().DeclaredConstructors.Any(ctor => ctor.IsPublic && !ctor.GetParameters().Any()))\n            {\n                throw new NotSupportedException(\"Custom factory must have a public parameterless constructor\");\n            }\n\n            return factoryType.GetCorrectCSharpTypeName();\n        }\n\n        private static string GetInProcessDiagnoserRouters(BenchmarkBuildInfo buildInfo)\n        {\n            var sourceCodes = buildInfo.CompositeInProcessDiagnoser.InProcessDiagnosers\n                .Select((d, i) => ToSourceCode(d, buildInfo.BenchmarkCase, i))\n                .WhereNotNull();\n            return string.Join($\",\\n\", sourceCodes);\n\n            static string? ToSourceCode(IInProcessDiagnoser diagnoser, BenchmarkCase benchmarkCase, int index)\n            {\n                var handlerData = diagnoser.GetHandlerData(benchmarkCase);\n                if (handlerData.HandlerType is null)\n                {\n                    return null;\n                }\n                string routerType = typeof(InProcessDiagnoserRouter).GetCorrectCSharpTypeName();\n                return $$\"\"\"\n                new {{routerType}}() {\n                    {{nameof(InProcessDiagnoserRouter.handler)}} = {{routerType}}.{{nameof(InProcessDiagnoserRouter.Init)}}(new {{handlerData.HandlerType.GetCorrectCSharpTypeName()}}(), {{SourceCodeHelper.ToSourceCode(handlerData.SerializedConfig)}}),\n                    {{nameof(InProcessDiagnoserRouter.index)}} = {{index}},\n                    {{nameof(InProcessDiagnoserRouter.runMode)}} = {{SourceCodeHelper.ToSourceCode(diagnoser.GetRunMode(benchmarkCase))}}\n                }\n                \"\"\";\n            }\n        }\n\n        private static string GetParameterModifier(ParameterInfo parameterInfo)\n        {\n            if (!parameterInfo.ParameterType.IsByRef)\n                return string.Empty;\n\n            // From https://stackoverflow.com/a/38110036/5852046 :\n            // \"If you don't do the IsByRef check for out parameters, then you'll incorrectly get members decorated with the\n            // [Out] attribute from System.Runtime.InteropServices but which aren't actually C# out parameters.\"\n            if (parameterInfo.IsOut)\n                return \"out\";\n            else if (parameterInfo.IsIn)\n                return \"in\";\n            else\n                return \"ref\";\n        }\n\n        private static string GetBenchmarkRunCall(BuildPartition buildPartition, CodeGenBenchmarkRunCallType runCallType)\n        {\n            if (runCallType == CodeGenBenchmarkRunCallType.Reflection)\n            {\n                // Use reflection to call benchmark's Run method indirectly.\n                return \"\"\"\n                typeof(global::BenchmarkDotNet.Autogenerated.UniqueProgramName).Assembly\n                                    .GetType($\"BenchmarkDotNet.Autogenerated.Runnable_{id}\")\n                                    .GetMethod(\"Run\", global::System.Reflection.BindingFlags.Public | global::System.Reflection.BindingFlags.Static)\n                                    .Invoke(null, new global::System.Object[] { host, benchmarkName, diagnoserRunMode });\n                \"\"\";\n            }\n\n            // Generate a switch to call benchmark's Run method directly.\n            var @switch = new StringBuilder(buildPartition.Benchmarks.Length * 30);\n            @switch.AppendLine(\"switch (id) {\");\n\n            foreach (var buildInfo in buildPartition.Benchmarks)\n                @switch.AppendLine($\"case {buildInfo.Id.Value}: BenchmarkDotNet.Autogenerated.Runnable_{buildInfo.Id.Value}.Run(host, benchmarkName, diagnoserRunMode); break;\");\n\n            @switch.AppendLine(\"default: throw new System.NotSupportedException(\\\"invalid benchmark id\\\");\");\n            @switch.AppendLine(\"}\");\n\n            return @switch.ToString();\n        }\n\n        private static Type GetFieldType(Type argumentType, ParameterInstance argument)\n        {\n            // #774 we can't store Span in a field, so we store an array (which is later casted to Span when we load the arguments)\n            if (argumentType.IsStackOnlyWithImplicitCast(argument.Value))\n                return argument.Value.GetType();\n\n            return argumentType;\n        }\n\n        private class SmartStringBuilder\n        {\n            private readonly string originalText;\n            private readonly StringBuilder builder;\n\n            public SmartStringBuilder(string text)\n            {\n                originalText = text;\n                builder = new StringBuilder(text);\n            }\n\n            public SmartStringBuilder Replace(string oldValue, string? newValue)\n            {\n                if (originalText.Contains(oldValue))\n                    builder.Replace(oldValue, newValue);\n                else\n                    builder.Append($\"\\n// '{oldValue}' not found\");\n                return this;\n            }\n\n            public override string ToString() => builder.ToString();\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Code/DeclarationsProvider.cs",
    "content": "﻿using System.Reflection;\nusing System.Threading.Tasks;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Running;\n\nnamespace BenchmarkDotNet.Code\n{\n    internal abstract class DeclarationsProvider\n    {\n        // \"GlobalSetup\" or \"GlobalCleanup\" methods are optional, so default to an empty delegate, so there is always something that can be invoked\n        private const string EmptyAction = \"() => { }\";\n\n        protected readonly Descriptor Descriptor;\n\n        internal DeclarationsProvider(Descriptor descriptor) => Descriptor = descriptor;\n\n        public string OperationsPerInvoke => Descriptor.OperationsPerInvoke.ToString();\n\n        public string WorkloadTypeName => Descriptor.Type.GetCorrectCSharpTypeName();\n\n        public string GlobalSetupMethodName => GetMethodName(Descriptor.GlobalSetupMethod);\n\n        public string GlobalCleanupMethodName => GetMethodName(Descriptor.GlobalCleanupMethod);\n\n        public string IterationSetupMethodName => Descriptor.IterationSetupMethod?.Name ?? EmptyAction;\n\n        public string IterationCleanupMethodName => Descriptor.IterationCleanupMethod?.Name ?? EmptyAction;\n\n        public abstract string GetWorkloadMethodCall(string passArguments);\n\n        protected static string GetMethodPrefix(MethodInfo method)\n            => method.IsStatic ? method.DeclaringType!.GetCorrectCSharpTypeName() : \"base\";\n\n        private string GetMethodName(MethodInfo? method)\n        {\n            if (method == null)\n            {\n                return EmptyAction;\n            }\n\n            if (method.ReturnType == typeof(Task) ||\n                method.ReturnType == typeof(ValueTask) ||\n                (method.ReturnType.IsGenericType &&\n                    (method.ReturnType.GetGenericTypeDefinition() == typeof(Task<>) ||\n                     method.ReturnType.GetGenericTypeDefinition() == typeof(ValueTask<>))))\n            {\n                return $\"() => global::BenchmarkDotNet.Helpers.AwaitHelper.GetResult({GetMethodPrefix(Descriptor.WorkloadMethod)}.{method.Name}())\";\n            }\n\n            return $\"{GetMethodPrefix(Descriptor.WorkloadMethod)}.{method.Name}\";\n        }\n    }\n\n    internal class SyncDeclarationsProvider(Descriptor descriptor) : DeclarationsProvider(descriptor)\n    {\n        public override string GetWorkloadMethodCall(string passArguments)\n             => $\"{GetMethodPrefix(Descriptor.WorkloadMethod)}.{Descriptor.WorkloadMethod.Name}({passArguments})\";\n    }\n\n    internal class AsyncDeclarationsProvider(Descriptor descriptor) : DeclarationsProvider(descriptor)\n    {\n        public override string GetWorkloadMethodCall(string passArguments)\n            => $\"global::BenchmarkDotNet.Helpers.AwaitHelper.GetResult({GetMethodPrefix(Descriptor.WorkloadMethod)}.{Descriptor.WorkloadMethod.Name}({passArguments}))\";\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Code/EnumParam.cs",
    "content": "﻿using System;\nusing System.Globalization;\nusing BenchmarkDotNet.Extensions;\n\nnamespace BenchmarkDotNet.Code\n{\n    public class EnumParam : IParam\n    {\n        // Preserves type information for enum values from F# code\n        // See also:\n        // https://github.com/dotnet/fsharp/issues/995\n        private readonly Type type;\n\n        private EnumParam(object value, Type type)\n        {\n            this.Value = value;\n            this.type = type;\n        }\n\n        public object Value { get; }\n\n        public string DisplayText => $\"{Enum.ToObject(type, Value)}\";\n\n        public string ToSourceCode() =>\n            $\"({type.GetCorrectCSharpTypeName()})({ToInvariantCultureString()})\";\n\n        internal static IParam FromObject(object value, Type? type = null)\n        {\n            type = type ?? value.GetType();\n            if (!type.IsEnum)\n                throw new ArgumentOutOfRangeException(nameof(type));\n\n            return new EnumParam(value, type);\n        }\n\n        private string ToInvariantCultureString()\n        {\n            switch (Type.GetTypeCode(Enum.GetUnderlyingType(type)))\n            {\n                case TypeCode.Byte:\n                    return ((byte)Value).ToString(CultureInfo.InvariantCulture);\n                case TypeCode.Int16:\n                    return ((short)Value).ToString(CultureInfo.InvariantCulture);\n                case TypeCode.Int32:\n                    return ((int)Value).ToString(CultureInfo.InvariantCulture);\n                case TypeCode.Int64:\n                    return ((long)Value).ToString(CultureInfo.InvariantCulture);\n                case TypeCode.SByte:\n                    return ((sbyte)Value).ToString(CultureInfo.InvariantCulture);\n                case TypeCode.UInt16:\n                    return ((ushort)Value).ToString(CultureInfo.InvariantCulture);\n                case TypeCode.UInt32:\n                    return ((uint)Value).ToString(CultureInfo.InvariantCulture);\n                case TypeCode.UInt64:\n                    return ((ulong)Value).ToString(CultureInfo.InvariantCulture);\n                default:\n                    throw new ArgumentOutOfRangeException(nameof(Value));\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Code/IParam.cs",
    "content": "﻿namespace BenchmarkDotNet.Code\n{\n    public interface IParam\n    {\n        /// <summary>\n        /// value of the parameter object for benchmark\n        /// used internally (e.g. by the InProcessToolchain)\n        /// </summary>\n        object Value { get; }\n\n        /// <summary>\n        /// used to display the value (e.g. in summary in Params column)\n        /// </summary>\n        string DisplayText { get; }\n\n        /// <summary>\n        /// this source code is used to create parameter for benchmark\n        /// in C# source code file\n        /// example: $\"new Point2D({Value.X}, {Value.Y})\"\n        /// </summary>\n        string ToSourceCode();\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Columns/BaselineAllocationRatioColumn.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing BenchmarkDotNet.Diagnosers;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Mathematics;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Running;\n\nnamespace BenchmarkDotNet.Columns\n{\n    public class BaselineAllocationRatioColumn : BaselineCustomColumn\n    {\n        public override string Id => nameof(BaselineAllocationRatioColumn);\n\n        public override string ColumnName => Column.AllocRatio;\n\n        public static readonly IColumn RatioMean = new BaselineAllocationRatioColumn();\n\n        private BaselineAllocationRatioColumn() { }\n\n        public override string GetValue(Summary summary, BenchmarkCase benchmarkCase, Statistics baseline, IReadOnlyDictionary<string, Metric> baselineMetrics,\n            Statistics current, IReadOnlyDictionary<string, Metric> currentMetrics, bool isBaseline)\n        {\n            double? ratio = GetAllocationRatio(currentMetrics, baselineMetrics);\n            double? invertedRatio = GetAllocationRatio(baselineMetrics, currentMetrics);\n\n            if (ratio == null)\n                return \"NA\";\n\n            var cultureInfo = summary.GetCultureInfo();\n            var ratioStyle = summary.Style.RatioStyle;\n\n            bool advancedPrecision = IsNonBaselinesPrecise(summary, baselineMetrics, benchmarkCase);\n            switch (ratioStyle)\n            {\n                case RatioStyle.Value:\n                    return ratio.Value.ToString(advancedPrecision ? \"N3\" : \"N2\", cultureInfo);\n                case RatioStyle.Percentage:\n                    return isBaseline\n                        ? \"\"\n                        : ratio.Value >= 1.0\n                            ? \"+\" + ((ratio.Value - 1.0) * 100).ToString(advancedPrecision ? \"N1\" : \"N0\", cultureInfo) + \"%\"\n                            : \"-\" + ((1.0 - ratio.Value) * 100).ToString(advancedPrecision ? \"N1\" : \"N0\", cultureInfo) + \"%\";\n                case RatioStyle.Trend:\n                    return isBaseline\n                        ? \"\"\n                        : ratio.Value >= 1.0\n                            ? ratio.Value.ToString(advancedPrecision ? \"N3\" : \"N2\", cultureInfo) + \"x more\"\n                            : invertedRatio == null\n                                ? \"NA\"\n                                : invertedRatio.Value.ToString(advancedPrecision ? \"N3\" : \"N2\", cultureInfo) + \"x less\";\n                default:\n                    throw new ArgumentOutOfRangeException(nameof(summary), ratioStyle, \"RatioStyle is not supported\");\n            }\n        }\n\n        private static bool IsNonBaselinesPrecise(Summary summary, IReadOnlyDictionary<string, Metric> baselineMetric, BenchmarkCase benchmarkCase)\n        {\n            var logicalGroupKey = summary.GetLogicalGroupKey(benchmarkCase);\n            var nonBaselines = summary.GetNonBaselines(logicalGroupKey);\n\n            return nonBaselines.Any(c => GetAllocationRatio(summary[c]!.Metrics, baselineMetric) is > 0 and < 0.01);\n        }\n\n        private static double? GetAllocationRatio(\n            IReadOnlyDictionary<string, Metric> current,\n            IReadOnlyDictionary<string, Metric> baseline)\n        {\n            double? currentBytes = GetAllocatedBytes(current);\n            double? baselineBytes = GetAllocatedBytes(baseline);\n\n            if (currentBytes == null || baselineBytes == null)\n                return null;\n\n            if (baselineBytes == 0)\n                return null;\n\n            return currentBytes / baselineBytes;\n        }\n\n        private static double? GetAllocatedBytes(IReadOnlyDictionary<string, Metric> metrics)\n        {\n            var metric = metrics.Values.FirstOrDefault(m => m.Descriptor is AllocatedMemoryMetricDescriptor);\n            return metric?.Value;\n        }\n\n        public override ColumnCategory Category => ColumnCategory.Metric; //it should be displayed after Allocated column\n        public override int PriorityInCategory => AllocatedMemoryMetricDescriptor.Instance.PriorityInCategory + 1;\n        public override bool IsNumeric => true;\n        public override UnitType UnitType => UnitType.Dimensionless;\n        public override string Legend => \"Allocated memory ratio distribution ([Current]/[Baseline])\";\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Columns/BaselineColumn.cs",
    "content": "﻿using BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Running;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Columns\n{\n    public class BaselineColumn : IColumn\n    {\n        [PublicAPI] public static readonly IColumn Default = new BaselineColumn();\n\n        public string Id => nameof(BaselineColumn);\n        public string ColumnName => Column.Baseline;\n\n        public string GetValue(Summary summary, BenchmarkCase benchmarkCase) => summary.IsBaseline(benchmarkCase) ? \"Yes\" : \"No\";\n        public string GetValue(Summary summary, BenchmarkCase benchmarkCase, SummaryStyle style) => GetValue(summary, benchmarkCase);\n        public bool IsDefault(Summary summary, BenchmarkCase benchmarkCase) => false;\n        public bool IsAvailable(Summary summary) => true;\n\n        public bool AlwaysShow => true;\n        public ColumnCategory Category => ColumnCategory.Meta;\n        public int PriorityInCategory => 2;\n        public bool IsNumeric => false;\n        public UnitType UnitType => UnitType.Dimensionless;\n        public string Legend => \"\";\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Columns/BaselineCustomColumn.cs",
    "content": "using System.Collections.Generic;\nusing System.Diagnostics.CodeAnalysis;\nusing BenchmarkDotNet.Mathematics;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Running;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Columns\n{\n    public abstract class BaselineCustomColumn : IColumn\n    {\n        public abstract string Id { get; }\n        public abstract string ColumnName { get; }\n\n        public string GetValue(Summary summary, BenchmarkCase benchmarkCase)\n        {\n            var logicalGroupKey = summary.GetLogicalGroupKey(benchmarkCase);\n            var baseline = summary.GetBaseline(logicalGroupKey);\n            bool isBaseline = summary.IsBaseline(benchmarkCase);\n\n            if (ResultsAreInvalid(summary, benchmarkCase, baseline))\n                return MetricColumn.UnknownRepresentation;\n\n            var baselineReport = summary[baseline]!;\n            var baselineStat = baselineReport.ResultStatistics!;\n            var baselineMetrics = baselineReport.Metrics;\n\n            var benchmarkCaseReport = summary[benchmarkCase]!;\n            var currentStat = benchmarkCaseReport.ResultStatistics!;\n            var currentMetrics = benchmarkCaseReport.Metrics;\n\n            return GetValue(summary, benchmarkCase, baselineStat, baselineMetrics, currentStat, currentMetrics, isBaseline);\n        }\n\n        [PublicAPI]\n        public abstract string GetValue(Summary summary, BenchmarkCase benchmarkCase, Statistics baseline, IReadOnlyDictionary<string, Metric> baselineMetrics,\n            Statistics current, IReadOnlyDictionary<string, Metric> currentMetrics, bool isBaseline);\n\n        public bool IsAvailable(Summary summary) => summary.HasBaselines();\n        public bool AlwaysShow => true;\n        public virtual ColumnCategory Category => ColumnCategory.Baseline;\n        public abstract int PriorityInCategory { get; }\n        public abstract bool IsNumeric { get; }\n        public abstract UnitType UnitType { get; }\n        public abstract string Legend { get; }\n        public string GetValue(Summary summary, BenchmarkCase benchmarkCase, SummaryStyle style) => GetValue(summary, benchmarkCase);\n        public override string ToString() => ColumnName;\n        public bool IsDefault(Summary summary, BenchmarkCase benchmarkCase) => false;\n\n        internal static bool ResultsAreInvalid(Summary summary, BenchmarkCase benchmarkCase, [NotNullWhen(false)] BenchmarkCase? baseline)\n        {\n            return baseline == null ||\n                   summary[baseline]?.ResultStatistics == null ||\n                   !summary[baseline]!.ResultStatistics!.CanBeInverted() ||\n                   summary[benchmarkCase]?.ResultStatistics == null;\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Columns/BaselineRatioColumn.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing BenchmarkDotNet.Mathematics;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Running;\n\nnamespace BenchmarkDotNet.Columns\n{\n    public class BaselineRatioColumn : BaselineCustomColumn\n    {\n        public enum RatioMetric\n        {\n            Mean,\n            StdDev\n        }\n\n        public static readonly IColumn RatioMean = new BaselineRatioColumn(RatioMetric.Mean);\n        public static readonly IColumn RatioStdDev = new BaselineRatioColumn(RatioMetric.StdDev);\n\n        public RatioMetric Metric { get; }\n\n        private BaselineRatioColumn(RatioMetric metric)\n        {\n            Metric = metric;\n        }\n\n        public override string Id => nameof(BaselineRatioColumn) + \".\" + Metric;\n\n        public override string ColumnName\n        {\n            get\n            {\n                switch (Metric)\n                {\n                    case RatioMetric.Mean:\n                        return Column.Ratio;\n                    case RatioMetric.StdDev:\n                        return Column.RatioSD;\n                    default:\n                        throw new NotSupportedException();\n                }\n            }\n        }\n\n        public override string GetValue(Summary summary, BenchmarkCase benchmarkCase, Statistics baseline, IReadOnlyDictionary<string, Metric> baselineMetrics,\n            Statistics current, IReadOnlyDictionary<string, Metric> currentMetrics, bool isBaseline)\n        {\n            var ratio = GetRatioStatistics(current, baseline);\n            if (ratio == null)\n                return \"NA\";\n            var invertedRatio = GetRatioStatistics(baseline, current);\n\n            var cultureInfo = summary.GetCultureInfo();\n            var ratioStyle = summary.Style.RatioStyle;\n\n            switch (Metric)\n            {\n                case RatioMetric.Mean:\n                {\n                    bool advancedPrecision = IsNonBaselinesPrecise(summary, baseline, benchmarkCase);\n                    switch (ratioStyle)\n                    {\n                        case RatioStyle.Value:\n                            return ratio.Mean.ToString(advancedPrecision ? \"N3\" : \"N2\", cultureInfo);\n                        case RatioStyle.Percentage:\n                            return isBaseline\n                                ? \"baseline\"\n                                : ratio.Mean >= 1.0\n                                    ? \"+\" + ((ratio.Mean - 1.0) * 100).ToString(advancedPrecision ? \"N1\" : \"N0\", cultureInfo) + \"%\"\n                                    : \"-\" + ((1.0 - ratio.Mean) * 100).ToString(advancedPrecision ? \"N1\" : \"N0\", cultureInfo) + \"%\";\n                        case RatioStyle.Trend:\n                            return isBaseline\n                                ? \"baseline\"\n                                : ratio.Mean >= 1.0\n                                    ? ratio.Mean.ToString(advancedPrecision ? \"N3\" : \"N2\", cultureInfo) + \"x slower\"\n                                    : invertedRatio == null\n                                        ? \"NA\"\n                                        : invertedRatio.Mean.ToString(advancedPrecision ? \"N3\" : \"N2\", cultureInfo) + \"x faster\";\n                        default:\n                            throw new ArgumentOutOfRangeException(nameof(summary), ratioStyle, \"RatioStyle is not supported\");\n                    }\n                }\n                case RatioMetric.StdDev:\n                {\n                    switch (ratioStyle)\n                    {\n                        case RatioStyle.Value:\n                            return ratio.StandardDeviation.ToString(\"N2\", cultureInfo);\n                        case RatioStyle.Percentage:\n                            return isBaseline\n                                ? \"\"\n                                : Math.Abs(ratio.Mean) < 1e-9\n                                    ? \"NA\"\n                                    : (100 * ratio.StandardDeviation / ratio.Mean).ToString(\"N1\", cultureInfo) + \"%\";\n                        case RatioStyle.Trend:\n                            return isBaseline\n                                ? \"\"\n                                : ratio.Mean >= 1.0\n                                    ? ratio.StandardDeviation.ToString(\"N2\", cultureInfo) + \"x\"\n                                    : invertedRatio == null\n                                        ? \"NA\"\n                                        : invertedRatio.StandardDeviation.ToString(\"N2\", cultureInfo) + \"x\";\n                        default:\n                            throw new ArgumentOutOfRangeException(nameof(summary), ratioStyle, \"RatioStyle is not supported\");\n                    }\n                }\n                default:\n                    throw new NotSupportedException();\n            }\n        }\n\n        private static bool IsNonBaselinesPrecise(Summary summary, Statistics baselineStat, BenchmarkCase benchmarkCase)\n        {\n            var logicalGroupKey = summary.GetLogicalGroupKey(benchmarkCase);\n            var nonBaselines = summary.GetNonBaselines(logicalGroupKey);\n            return nonBaselines.Any(x => GetRatioStatistics(summary[x]?.ResultStatistics, baselineStat)?.Mean < 0.01);\n        }\n\n        private static RatioStatistics? GetRatioStatistics(Statistics? current, Statistics? baseline)\n        {\n            if (current == null || current.N < 1)\n                return null;\n            if (baseline == null || baseline.N < 1)\n                return null;\n            try\n            {\n                return new RatioStatistics(current, baseline);\n            }\n            catch (DivideByZeroException)\n            {\n                return null;\n            }\n        }\n\n        public override int PriorityInCategory => (int) Metric;\n        public override bool IsNumeric => true;\n        public override UnitType UnitType => UnitType.Dimensionless;\n\n        public override string Legend\n        {\n            get\n            {\n                switch (Metric)\n                {\n                    case RatioMetric.Mean:\n                        return \"Mean of the ratio distribution ([Current]/[Baseline])\";\n                    case RatioMetric.StdDev:\n                        return \"Standard deviation of the ratio distribution ([Current]/[Baseline])\";\n                    default:\n                        throw new ArgumentOutOfRangeException(nameof(Metric));\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Columns/CategoriesColumn.cs",
    "content": "using System.Linq;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Running;\n\nnamespace BenchmarkDotNet.Columns\n{\n    public class CategoriesColumn : IColumn\n    {\n        public static readonly IColumn Default = new CategoriesColumn();\n\n        public string Id => nameof(CategoriesColumn);\n        public string ColumnName => Column.Categories;\n        public string GetValue(Summary summary, BenchmarkCase benchmarkCase) => string.Join(\",\", benchmarkCase.Descriptor.Categories);\n        public string GetValue(Summary summary, BenchmarkCase benchmarkCase, SummaryStyle style) => GetValue(summary, benchmarkCase);\n        public bool IsDefault(Summary summary, BenchmarkCase benchmarkCase) => false;\n        public bool IsAvailable(Summary summary) => summary.BenchmarksCases.Any(b => !b.Descriptor.Categories.IsEmpty());\n        public bool AlwaysShow => false;\n        public ColumnCategory Category => ColumnCategory.Job;\n        public int PriorityInCategory => 100;\n        public bool IsNumeric => false;\n        public UnitType UnitType => UnitType.Dimensionless;\n        public string Legend => \"All categories of the corresponded method, class, and assembly\";\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Columns/Column.cs",
    "content": "﻿using JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Columns\n{\n    // ReSharper disable once InconsistentNaming\n    [PublicAPI] // this type is public, so the users can do things like [HideColumns(Column.$)] and get suggestions from IDE\n    public static class Column\n    {\n        public const string Namespace = \"Namespace\";\n        public const string Type = \"Type\";\n        public const string Method = \"Method\";\n\n        public const string Job = \"Job\";\n\n        public const string Mean = \"Mean\";\n        public const string StdErr = \"StdErr\";\n        public const string StdDev = \"StdDev\";\n        public const string Error = \"Error\";\n        public const string OperationPerSecond = \"Op/s\";\n        public const string Min = \"Min\";\n        public const string Q1 = \"Q1\";\n        public const string Median = \"Median\";\n        public const string Q3 = \"Q3\";\n        public const string Max = \"Max\";\n        public const string Skewness = \"Skewness\";\n        public const string Kurtosis = \"Kurtosis\";\n        public const string MValue = \"MValue\";\n        public const string Iterations = \"Iterations\";\n\n        public const string P0 = \"P0\";\n        public const string P25 = \"P25\";\n        public const string P50 = \"P50\";\n        public const string P67 = \"P67\";\n        public const string P80 = \"P80\";\n        public const string P85 = \"P85\";\n        public const string P90 = \"P90\";\n        public const string P95 = \"P95\";\n        public const string P100 = \"P100\";\n\n        public const string Categories = \"Categories\";\n        public const string LogicalGroup = \"LogicalGroup\";\n        public const string Rank = \"Rank\";\n\n        public const string Ratio = \"Ratio\";\n        public const string RatioSD = \"RatioSD\";\n        public const string AllocRatio = \"Alloc Ratio\";\n\n        public const string Allocated = \"Allocated\";\n        public const string Gen0 = \"Gen0\";\n        public const string Gen1 = \"Gen1\";\n        public const string Gen2 = \"Gen2\";\n\n        public const string AllocatedNativeMemory = \"Allocated native memory\";\n        public const string NativeMemoryLeak = \"Native memory leak\";\n        public const string CompletedWorkItems = \"Completed Work Items\";\n        public const string LockContentions = \"Lock Contentions\";\n        public const string CodeSize = \"Code Size\";\n        public const string Exceptions = \"Exceptions\";\n\n        //Characteristics:\n        public const string Id = \"Id\";\n\n        public const string MaxRelativeError = \"MaxRelativeError\";\n        public const string MaxAbsoluteError = \"MaxAbsoluteError\";\n        public const string MinIterationTime = \"MinIterationTime\";\n        public const string MinInvokeCount = \"MinInvokeCount\";\n        public const string EvaluateOverhead = \"EvaluateOverhead\";\n        public const string OutlierMode = \"OutlierMode\";\n        public const string AnalyzeLaunchVariance = \"AnalyzeLaunchVariance\";\n\n        public const string Platform = \"Platform\";\n        public const string Jit = \"Jit\";\n        public const string Runtime = \"Runtime\";\n        public const string Affinity = \"Affinity\";\n        public const string Gc = \"Gc\";\n        public const string EnvironmentVariables = \"EnvironmentVariables\";\n        public const string PowerPlanMode = \"PowerPlanMode\";\n\n        public const string Server = \"Server\";\n        public const string Concurrent = \"Concurrent\";\n        public const string CpuGroups = \"CpuGroups\";\n        public const string Force = \"Force\";\n        public const string AllowVeryLargeObjects = \"AllowVeryLargeObjects\";\n        public const string RetainVm = \"RetainVm\";\n        public const string NoAffinitize = \"NoAffinitize\";\n        public const string HeapAffinitizeMask = \"HeapAffinitizeMask\";\n        public const string HeapCount = \"HeapCount\";\n\n        public const string Toolchain = \"Toolchain\";\n        public const string Clock = \"Clock\";\n        public const string EngineFactory = \"EngineFactory\";\n        public const string BuildConfiguration = \"BuildConfiguration\";\n        public const string Arguments = \"Arguments\";\n        public const string NuGetReferences = \"NuGetReferences\";\n\n        public const string Environment = \"Environment\";\n        public const string Run = \"Run\";\n        public const string Infrastructure = \"Infrastructure\";\n        public const string Accuracy = \"Accuracy\";\n        public const string Meta = \"Meta\";\n\n        public const string Baseline = \"Baseline\";\n        public const string IsMutator = \"IsMutator\";\n        public const string IsDefault = \"IsDefault\";\n\n        public const string RunStrategy = \"RunStrategy\";\n        public const string LaunchCount = \"LaunchCount\";\n        public const string InvocationCount = \"InvocationCount\";\n        public const string UnrollFactor = \"UnrollFactor\";\n        public const string IterationCount = \"IterationCount\";\n        public const string MinIterationCount = \"MinIterationCount\";\n        public const string MaxIterationCount = \"MaxIterationCount\";\n        public const string IterationTime = \"IterationTime\";\n        public const string WarmupCount = \"WarmupCount\";\n        public const string MinWarmupIterationCount = \"MinWarmupIterationCount\";\n        public const string MaxWarmupIterationCount = \"MaxWarmupIterationCount\";\n        public const string MemoryRandomization = \"MemoryRandomization\";\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Columns/ColumnCategory.cs",
    "content": "﻿namespace BenchmarkDotNet.Columns\n{\n    public enum ColumnCategory\n    {\n        Job, Params, Statistics, Baseline, Custom, Meta, Metric\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Columns/ColumnExtensions.cs",
    "content": "﻿namespace BenchmarkDotNet.Columns\n{\n    public static class ColumnExtensions\n    {\n        public static IColumnProvider ToProvider(this IColumn column) => new SimpleColumnProvider(column);\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Columns/ColumnHidingByIdRule.cs",
    "content": "﻿using JetBrains.Annotations;\nusing System;\n\nnamespace BenchmarkDotNet.Columns\n{\n    [PublicAPI]\n    public sealed class ColumnHidingByIdRule : IColumnHidingRule, IEquatable<ColumnHidingByIdRule>\n    {\n        public string Id { get; }\n\n        public ColumnHidingByIdRule(IColumn column) => Id = column.Id;\n\n        public bool NeedToHide(IColumn column) => column.Id == Id;\n\n        public bool Equals(ColumnHidingByIdRule? other)\n        {\n            if (ReferenceEquals(null, other))\n                return false;\n            if (ReferenceEquals(this, other))\n                return true;\n            return Id == other.Id;\n        }\n\n        public override bool Equals(object? obj)\n            => Equals(obj as ColumnHidingByIdRule);\n\n        public override int GetHashCode()\n            => HashCode.Combine(Id);\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Columns/ColumnHidingByNameRule.cs",
    "content": "﻿using JetBrains.Annotations;\nusing System;\n\nnamespace BenchmarkDotNet.Columns\n{\n    [PublicAPI]\n    public sealed class ColumnHidingByNameRule : IColumnHidingRule, IEquatable<ColumnHidingByNameRule>\n    {\n        public string Name { get; }\n\n        public ColumnHidingByNameRule(string name) => Name = name;\n\n        public bool NeedToHide(IColumn column) => column.ColumnName == Name;\n\n        public bool Equals(ColumnHidingByNameRule? other)\n        {\n            if (ReferenceEquals(null, other))\n                return false;\n            if (ReferenceEquals(this, other))\n                return true;\n\n            return Name == other.Name;\n        }\n\n        public override bool Equals(object? obj)\n            => Equals(obj as ColumnHidingByNameRule);\n\n        public override int GetHashCode()\n            => HashCode.Combine(Name);\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Columns/CompositeColumnProvider.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Linq;\nusing BenchmarkDotNet.Reports;\n\nnamespace BenchmarkDotNet.Columns\n{\n    public class CompositeColumnProvider : IColumnProvider\n    {\n        private readonly IColumnProvider[] providers;\n\n        public CompositeColumnProvider(params IColumnProvider[] providers)\n        {\n            this.providers = providers;\n        }\n\n        public IEnumerable<IColumn> GetColumns(Summary summary) => providers.SelectMany(p => p.GetColumns(summary));\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Columns/DefaultColumnProvider.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Mathematics;\nusing BenchmarkDotNet.Reports;\nusing JetBrains.Annotations;\nusing Perfolizer.Mathematics.Common;\n\nnamespace BenchmarkDotNet.Columns\n{\n    public static class DefaultColumnProviders\n    {\n        [PublicAPI] public static readonly IColumnProvider Descriptor = new DescriptorColumnProvider();\n        [PublicAPI] public static readonly IColumnProvider Job = new JobColumnProvider();\n        [PublicAPI] public static readonly IColumnProvider Statistics = new StatisticsColumnProvider();\n        [PublicAPI] public static readonly IColumnProvider Params = new ParamsColumnProvider();\n        [PublicAPI] public static readonly IColumnProvider Metrics = new MetricsColumnProvider();\n\n        public static readonly IColumnProvider[] Instance = [Descriptor, Job, Statistics, Params, Metrics];\n\n        private class DescriptorColumnProvider : IColumnProvider\n        {\n            public IEnumerable<IColumn> GetColumns(Summary summary)\n            {\n                if (summary.BenchmarksCases.Select(b => b.Descriptor.Type.Namespace).Distinct().Count() > 1)\n                    yield return TargetMethodColumn.Namespace;\n                if (summary.BenchmarksCases.Select(b => b.Descriptor.Type.GetDisplayName()).Distinct().Count() > 1)\n                    yield return TargetMethodColumn.Type;\n                yield return TargetMethodColumn.Method;\n            }\n        }\n\n        private class JobColumnProvider : IColumnProvider\n        {\n            public IEnumerable<IColumn> GetColumns(Summary summary) => JobCharacteristicColumn.AllColumns;\n        }\n\n        private class StatisticsColumnProvider : IColumnProvider\n        {\n            public IEnumerable<IColumn> GetColumns(Summary summary)\n            {\n                yield return StatisticColumn.Mean;\n                yield return StatisticColumn.Error;\n\n                if (NeedToShow(summary, s => s.Percentiles.P95 > s.Mean + 3 * s.StandardDeviation))\n                    yield return StatisticColumn.P95;\n                if (NeedToShow(summary, s => s.N >= 3 &&\n                                             (!s.GetConfidenceInterval(ConfidenceLevel.L99).Contains(s.Median) ||\n                                              Math.Abs(s.Median - s.Mean) > s.Mean * 0.2)))\n                    yield return StatisticColumn.Median;\n                if (NeedToShow(summary, s => s.StandardDeviation > 1e-9))\n                    yield return StatisticColumn.StdDev;\n\n                if (summary.Reports != null && summary.HasBaselines())\n                {\n                    yield return BaselineRatioColumn.RatioMean;\n                    var stdDevColumn = BaselineRatioColumn.RatioStdDev;\n                    var stdDevColumnValues = summary.BenchmarksCases.Select(b => stdDevColumn.GetValue(summary, b));\n\n                    // Hide RatioSD column if values is small\n                    // TODO: rewrite and check raw values\n                    bool hide = stdDevColumnValues.All(value => value == \"0.00\" || value == \"0.01\");\n                    if (!hide)\n                        yield return BaselineRatioColumn.RatioStdDev;\n\n                    if (HasMemoryDiagnoser(summary))\n                    {\n                        yield return BaselineAllocationRatioColumn.RatioMean;\n                    }\n                }\n            }\n\n            private static bool NeedToShow(Summary summary, Func<Statistics, bool> check)\n            {\n                return summary.Reports != null && summary.Reports.Any(r => r.ResultStatistics != null && check(r.ResultStatistics));\n            }\n\n            private static bool HasMemoryDiagnoser(Summary summary)\n            {\n                return summary.BenchmarksCases.Any(c => c.Config.HasMemoryDiagnoser());\n            }\n        }\n\n        private class ParamsColumnProvider : IColumnProvider\n        {\n            public IEnumerable<IColumn> GetColumns(Summary summary) => summary\n                .BenchmarksCases\n                .SelectMany(b => b.Parameters.Items.Select(item => item.Definition))\n                .Distinct()\n                .Select(definition => new ParamColumn(definition.Name, definition.PriorityInCategory));\n        }\n\n        private class MetricsColumnProvider : IColumnProvider\n        {\n            public IEnumerable<IColumn> GetColumns(Summary summary) => summary\n                .Reports\n                .SelectMany(report => report.Metrics.Values.Select(metric => metric.Descriptor))\n                .Distinct(MetricDescriptorEqualityComparer.Instance)\n                .Select(descriptor => new MetricColumn(descriptor));\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Columns/EmptyColumnProvider.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Linq;\nusing BenchmarkDotNet.Reports;\n\nnamespace BenchmarkDotNet.Columns\n{\n    public class EmptyColumnProvider : IColumnProvider\n    {\n        public static readonly IColumnProvider Instance = new EmptyColumnProvider();\n\n        private EmptyColumnProvider()\n        {\n        }\n\n        public IEnumerable<IColumn> GetColumns(Summary summary) => [];\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Columns/IColumn.cs",
    "content": "﻿using BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Running;\n\nnamespace BenchmarkDotNet.Columns\n{\n    public interface IColumn\n    {\n        /// <summary>\n        /// An unique identifier of the column.\n        /// <remarks>If there are several columns with the same Id, only one of them will be shown in the summary.</remarks>\n        /// </summary>\n        string Id { get; }\n\n        /// <summary>\n        /// Display column title in the summary.\n        /// </summary>\n        string ColumnName { get; }\n\n        /// <summary>\n        /// Value in this column formatted using the default style.\n        /// </summary>\n        string GetValue(Summary summary, BenchmarkCase benchmarkCase);\n\n        /// <summary>\n        /// Value in this column formatted using the specified style.\n        /// </summary>\n        string GetValue(Summary summary, BenchmarkCase benchmarkCase, SummaryStyle style);\n\n        bool IsDefault(Summary summary, BenchmarkCase benchmarkCase);\n\n        bool IsAvailable(Summary summary);\n\n        bool AlwaysShow { get; }\n\n        ColumnCategory Category { get; }\n\n        /// <summary>\n        /// Defines order of column in the same category.\n        /// </summary>\n        int PriorityInCategory { get; }\n\n        /// <summary>\n        /// Defines if the column's value represents a number\n        /// </summary>\n        bool IsNumeric { get; }\n\n        /// <summary>\n        /// Defines how to format column's value\n        /// </summary>\n        UnitType UnitType { get; }\n\n        /// <summary>\n        /// Column description.\n        /// </summary>\n        string Legend { get; }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Columns/IColumnHidingRule.cs",
    "content": "﻿namespace BenchmarkDotNet.Columns\n{\n    public interface IColumnHidingRule\n    {\n        bool NeedToHide(IColumn column);\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Columns/IColumnProvider.cs",
    "content": "﻿using System.Collections.Generic;\nusing BenchmarkDotNet.Reports;\n\nnamespace BenchmarkDotNet.Columns\n{\n    public interface IColumnProvider\n    {\n        IEnumerable<IColumn> GetColumns(Summary summary);\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Columns/JobCharacteristicColumn.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing BenchmarkDotNet.Characteristics;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Running;\n\nnamespace BenchmarkDotNet.Columns\n{\n    public class JobCharacteristicColumn : IColumn\n    {\n        private static readonly CharacteristicPresenter Presenter = CharacteristicPresenter.SummaryPresenter;\n\n        private readonly Characteristic characteristic;\n\n        private JobCharacteristicColumn(Characteristic characteristic)\n        {\n            this.characteristic = characteristic;\n            Id = \"Job.\" + characteristic.Id;\n            ColumnName = characteristic.Id;\n\n            // The 'Id' characteristic is a special case:\n            // here we just print 'Job'\n            if (characteristic.Id == \"Id\")\n                ColumnName = Column.Job;\n        }\n\n        public string Id { get; }\n        public string ColumnName { get; }\n        public bool AlwaysShow => false;\n        public ColumnCategory Category => ColumnCategory.Job;\n        public int PriorityInCategory => 0;\n        public bool IsNumeric => false;\n        public UnitType UnitType => UnitType.Dimensionless;\n        public string GetValue(Summary summary, BenchmarkCase benchmarkCase, SummaryStyle style) => GetValue(summary, benchmarkCase);\n\n        public bool IsDefault(Summary summary, BenchmarkCase benchmarkCase) => !benchmarkCase.Job.HasValue(characteristic);\n\n        public bool IsAvailable(Summary summary)\n        {\n            if (summary.IsMultipleRuntimes)\n            {\n                if (nameof(Toolchains.Toolchain).Equals(ColumnName))\n                {\n                    return false;\n                }\n                if (nameof(Job).Equals(ColumnName))\n                {\n                    return summary.BenchmarksCases.Any(x => x.Job.HasValue(CharacteristicObject.IdCharacteristic));\n                }\n            }\n\n            return true;\n        }\n\n        public string GetValue(Summary summary, BenchmarkCase benchmarkCase)\n        {\n            if (!benchmarkCase.Job.HasValue(characteristic) && EnvironmentResolver.Instance.CanResolve(characteristic))\n                return Presenter.ToPresentation(benchmarkCase.Job.ResolveValue(characteristic, EnvironmentResolver.Instance), characteristic);\n\n            return Presenter.ToPresentation(benchmarkCase.Job, characteristic);\n        }\n\n        private static readonly Lazy<IColumn[]> LazyAllColumns =\n            new Lazy<IColumn[]>(() =>\n                CharacteristicHelper.GetAllPresentableCharacteristics(typeof(Job), true)\n                .Select(c => (IColumn)new JobCharacteristicColumn(c)).ToArray());\n\n        public static IColumn[] AllColumns => LazyAllColumns.Value;\n\n        public string Legend => \"\";\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Columns/LogicalGroupColumn.cs",
    "content": "﻿using BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Running;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Columns\n{\n    public class LogicalGroupColumn : IColumn\n    {\n        [PublicAPI] public static readonly IColumn Default = new LogicalGroupColumn();\n\n        public string Id => nameof(LogicalGroupColumn);\n        public string ColumnName => Column.LogicalGroup;\n\n        public string GetValue(Summary summary, BenchmarkCase benchmarkCase) => summary.GetLogicalGroupKey(benchmarkCase) ?? \"\";\n        public string GetValue(Summary summary, BenchmarkCase benchmarkCase, SummaryStyle style) => GetValue(summary, benchmarkCase);\n        public bool IsDefault(Summary summary, BenchmarkCase benchmarkCase) => false;\n        public bool IsAvailable(Summary summary) => true;\n\n        public bool AlwaysShow => true;\n        public ColumnCategory Category => ColumnCategory.Meta;\n        public int PriorityInCategory => 1;\n        public bool IsNumeric => false;\n        public UnitType UnitType => UnitType.Dimensionless;\n        public string Legend => \"\";\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Columns/MetricColumn.cs",
    "content": "﻿using System.Linq;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Running;\nusing Perfolizer.Horology;\nusing Perfolizer.Metrology;\nusing Pragmastat.Metrology;\n\nnamespace BenchmarkDotNet.Columns\n{\n    public class MetricColumn : IColumn\n    {\n        internal const string UnknownRepresentation = \"?\";\n\n        private readonly IMetricDescriptor descriptor;\n\n        public MetricColumn(IMetricDescriptor metricDescriptor) => descriptor = metricDescriptor;\n\n        public string Id => descriptor.Id;\n        public string ColumnName => descriptor.DisplayName;\n        public string Legend => descriptor.Legend;\n        public bool AlwaysShow => true;\n        public ColumnCategory Category => ColumnCategory.Metric;\n        public int PriorityInCategory => descriptor.PriorityInCategory;\n        public bool IsNumeric => true;\n        public UnitType UnitType => descriptor.UnitType;\n\n        public bool IsDefault(Summary summary, BenchmarkCase benchmarkCase) => false;\n\n        public bool IsAvailable(Summary summary) => summary.Reports.Any(report =>\n            report.Metrics.TryGetValue(descriptor.Id, out var metric)\n            && metric.Descriptor.GetIsAvailable(metric));\n\n        public string GetValue(Summary summary, BenchmarkCase benchmarkCase) => GetValue(summary, benchmarkCase, SummaryStyle.Default);\n\n        public string GetValue(Summary summary, BenchmarkCase benchmarkCase, SummaryStyle style)\n        {\n            if (!summary.HasReport(benchmarkCase) || !summary[benchmarkCase]!.Metrics.TryGetValue(descriptor.Id, out var metric))\n                return \"NA\";\n            if (double.IsNaN(metric.Value))\n                return UnknownRepresentation;\n            if (metric.Value == 0.0 && !style.PrintZeroValuesInContent)\n                return \"-\";\n\n            var cultureInfo = summary.GetCultureInfo();\n\n            bool printUnits = style.PrintUnitsInContent || style.PrintUnitsInHeader;\n            var unitPresentation = new UnitPresentation(style.PrintUnitsInContent, minUnitWidth: 0, gap: true);\n            string numberFormat = descriptor.NumberFormat;\n\n            if (printUnits && descriptor.UnitType == UnitType.CodeSize)\n            {\n                var measurement = SizeValue.FromBytes((long)metric.Value).ToMeasurement(style.CodeSizeUnit);\n                return PerfolizerMeasurementFormatter.Instance.Format(measurement, numberFormat, cultureInfo, unitPresentation);\n            }\n            if (printUnits && descriptor.UnitType == UnitType.Size)\n            {\n                var measurement = SizeValue.FromBytes((long)metric.Value).ToMeasurement(style.SizeUnit);\n                return PerfolizerMeasurementFormatter.Instance.Format(measurement, numberFormat, cultureInfo, unitPresentation);\n            }\n            if (printUnits && descriptor.UnitType == UnitType.Time)\n            {\n                if (numberFormat.IsBlank())\n                    numberFormat = \"N4\";\n                var measurement = TimeInterval.FromNanoseconds(metric.Value).ToMeasurement(style.TimeUnit);\n                return PerfolizerMeasurementFormatter.Instance.Format(measurement, numberFormat, cultureInfo, unitPresentation);\n            }\n\n            return metric.Value.ToString(numberFormat, cultureInfo);\n        }\n\n        public override string ToString() => descriptor.DisplayName;\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Columns/ParamColumn.cs",
    "content": "﻿using System.Linq;\nusing BenchmarkDotNet.Parameters;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Running;\n\nnamespace BenchmarkDotNet.Columns\n{\n    public class ParamColumn : IColumn\n    {\n        public string Id => nameof(ParamColumn) + \".\" + ColumnName;\n        public string ColumnName { get; }\n\n        public ParamColumn(string columnName, int priorityInCategory = 0)\n        {\n            ColumnName = columnName;\n            PriorityInCategory = priorityInCategory;\n        }\n\n        public bool IsDefault(Summary summary, BenchmarkCase benchmarkCase) => false;\n        public string GetValue(Summary summary, BenchmarkCase benchmarkCase) =>\n            benchmarkCase.Parameters.Items.FirstOrDefault(item => item.Name == ColumnName)?.ToDisplayText(summary.Style) ??\n            ParameterInstance.NullParameterTextRepresentation;\n\n        public bool IsAvailable(Summary summary) => true;\n        public bool AlwaysShow => true;\n        public ColumnCategory Category => ColumnCategory.Params;\n        public int PriorityInCategory { get; private set; }\n        public override string ToString() => ColumnName;\n        public bool IsNumeric => false;\n        public UnitType UnitType => UnitType.Dimensionless;\n        public string GetValue(Summary summary, BenchmarkCase benchmarkCase, SummaryStyle style) => GetValue(summary, benchmarkCase);\n\n        public string Legend => $\"Value of the '{ColumnName}' parameter\";\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Columns/RankColumn.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Mathematics;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Running;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Columns\n{\n    public class RankColumn : IColumn\n    {\n        private readonly NumeralSystem numeralSystem;\n\n        public RankColumn(NumeralSystem system) => numeralSystem = system;\n\n        [PublicAPI] public static readonly IColumn Arabic = new RankColumn(NumeralSystem.Arabic);\n        [PublicAPI] public static readonly IColumn Roman = new RankColumn(NumeralSystem.Roman);\n        [PublicAPI] public static readonly IColumn Stars = new RankColumn(NumeralSystem.Stars);\n\n        public string Id => nameof(RankColumn) + \".\" + numeralSystem;\n        public string ColumnName => Column.Rank;\n\n        public string GetValue(Summary summary, BenchmarkCase benchmarkCase)\n        {\n            var logicalGroup = summary\n                .GetLogicalGroupForBenchmark(benchmarkCase)\n                .Where(b => summary[b]?.ResultStatistics != null)\n                .WhereNotNull()\n                .ToArray();\n            int index = Array.IndexOf(logicalGroup, benchmarkCase);\n            if (index == -1)\n                return MetricColumn.UnknownRepresentation;\n\n            var ranks = RankHelper.GetRanks(logicalGroup.Select(b => summary[b]!.ResultStatistics!).ToArray());\n            int rank = ranks[index];\n            return numeralSystem.ToPresentation(rank);\n        }\n\n        public bool IsDefault(Summary summary, BenchmarkCase benchmarkCase) => false;\n        public bool IsAvailable(Summary summary) => true;\n        public bool AlwaysShow => true;\n        public ColumnCategory Category => ColumnCategory.Custom;\n        public bool IsNumeric => true;\n        public UnitType UnitType => UnitType.Dimensionless;\n        public string GetValue(Summary summary, BenchmarkCase benchmarkCase, SummaryStyle style) => GetValue(summary, benchmarkCase);\n        public int PriorityInCategory => (int)numeralSystem;\n        public override string ToString() => ColumnName;\n        public string Legend => $\"Relative position of current benchmark mean among all benchmarks ({numeralSystem} style)\";\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Columns/RatioColumnStyle.cs",
    "content": "namespace BenchmarkDotNet.Columns\n{\n    public enum RatioStyle\n    {\n        Value,\n        Percentage,\n        Trend\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Columns/SimpleColumnProvider.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing BenchmarkDotNet.Reports;\n\nnamespace BenchmarkDotNet.Columns\n{\n    public class SimpleColumnProvider : IColumnProvider, IEquatable<SimpleColumnProvider>\n    {\n        private readonly IColumn[] columns;\n\n        public SimpleColumnProvider(params IColumn[] columns)\n        {\n            this.columns = columns;\n        }\n\n        public IEnumerable<IColumn> GetColumns(Summary summary) => columns.Where(c => c.IsAvailable(summary));\n\n        public bool Equals(SimpleColumnProvider? other)\n        {\n            if (ReferenceEquals(this, other))\n                return true;\n            if (other is null)\n                return false;\n\n            return columns.SequenceEqual(other.columns);\n        }\n\n        public override bool Equals(object? obj)\n           => Equals(obj as SimpleColumnProvider);\n\n        public override int GetHashCode()\n        {\n            // Compute hashcode of each column.\n            var hash = new HashCode();\n            foreach (var column in columns)\n                hash.Add(column);\n            return hash.ToHashCode();\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Columns/StatisticColumn.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Mathematics;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Running;\nusing JetBrains.Annotations;\nusing Perfolizer.Horology;\nusing Perfolizer.Mathematics.Common;\nusing Perfolizer.Mathematics.Multimodality;\nusing Perfolizer.Metrology;\nusing Pragmastat.Metrology;\n\nnamespace BenchmarkDotNet.Columns\n{\n    public interface IStatisticColumn : IColumn\n    {\n        List<double> GetAllValues(Summary summary, SummaryStyle style);\n    }\n\n    public class StatisticColumn : IStatisticColumn\n    {\n        private enum Priority\n        {\n            Main,\n            Quartile,\n            Percentiles,\n            Additional\n        }\n\n        public static readonly IStatisticColumn Mean = new StatisticColumn(Column.Mean, \"Arithmetic mean of all measurements\",\n            s => s.Mean, Priority.Main);\n\n        public static readonly IColumn StdErr = new StatisticColumn(Column.StdErr, \"Standard error of all measurements\",\n            s => s.StandardError, Priority.Main, parentColumn: Mean);\n\n        public static readonly IColumn StdDev = new StatisticColumn(Column.StdDev, \"Standard deviation of all measurements\",\n            s => s.StandardDeviation, Priority.Main, parentColumn: Mean);\n\n        public static readonly IColumn Error = new StatisticColumn(Column.Error, \"Half of 99.9% confidence interval\",\n            s => s.GetConfidenceInterval(ConfidenceLevel.L999).Margin, Priority.Main, parentColumn: Mean);\n\n        public static readonly IColumn OperationsPerSecond = new StatisticColumn(Column.OperationPerSecond, \"Operation per second\",\n            s => 1.0 * 1000 * 1000 * 1000 / s.Mean, Priority.Additional, UnitType.Dimensionless);\n\n        public static readonly IColumn Min = new StatisticColumn(Column.Min, \"Minimum\",\n            s => s.Min, Priority.Quartile);\n\n        public static readonly IColumn Q1 = new StatisticColumn(Column.Q1, \"Quartile 1 (25th percentile)\",\n            s => s.Q1, Priority.Quartile);\n\n        public static readonly IColumn Median = new StatisticColumn(Column.Median, \"Value separating the higher half of all measurements (50th percentile)\",\n            s => s.Median, Priority.Quartile);\n\n        public static readonly IColumn Q3 = new StatisticColumn(Column.Q3, \"Quartile 3 (75th percentile)\",\n            s => s.Q3, Priority.Quartile);\n\n        public static readonly IColumn Max = new StatisticColumn(Column.Max, \"Maximum\", s => s.Max, Priority.Quartile);\n\n        public static readonly IColumn Skewness = new StatisticColumn(Column.Skewness, \"Measure of the asymmetry (third standardized moment)\",\n            s => s.Skewness, Priority.Additional, UnitType.Dimensionless);\n\n        public static readonly IColumn Kurtosis = new StatisticColumn(Column.Kurtosis, \"Measure of the tailedness ( fourth standardized moment)\",\n            s => s.Kurtosis, Priority.Additional, UnitType.Dimensionless);\n\n        /// <summary>\n        /// See http://www.brendangregg.com/FrequencyTrails/modes.html\n        /// </summary>\n        public static readonly IColumn MValue = new StatisticColumn(Column.MValue, \"Modal value, see http://www.brendangregg.com/FrequencyTrails/modes.html\",\n            s => MValueCalculator.Calculate(s.Sample.Values), Priority.Additional, UnitType.Dimensionless);\n\n        public static readonly IColumn Iterations = new StatisticColumn(Column.Iterations, \"Number of target iterations\",\n            s => s.N, Priority.Additional, UnitType.Dimensionless);\n\n        public static readonly IColumn P0 = CreatePercentileColumn(0, Column.P0, s => s.Percentiles.P0);\n        public static readonly IColumn P25 = CreatePercentileColumn(25, Column.P25, s => s.Percentiles.P25);\n        public static readonly IColumn P50 = CreatePercentileColumn(50, Column.P50, s => s.Percentiles.P50);\n        public static readonly IColumn P67 = CreatePercentileColumn(67, Column.P67, s => s.Percentiles.P67);\n        public static readonly IColumn P80 = CreatePercentileColumn(80, Column.P80, s => s.Percentiles.P80);\n        public static readonly IColumn P85 = CreatePercentileColumn(85, Column.P85, s => s.Percentiles.P85);\n        public static readonly IColumn P90 = CreatePercentileColumn(90, Column.P90, s => s.Percentiles.P90);\n        public static readonly IColumn P95 = CreatePercentileColumn(95, Column.P95, s => s.Percentiles.P95);\n        public static readonly IColumn P100 = CreatePercentileColumn(100, Column.P100, s => s.Percentiles.P100);\n\n        [PublicAPI]\n        public static IColumn CiLower(ConfidenceLevel level) => new StatisticColumn(\n            $\"CI{level} Lower\", $\"Lower bound of {level} confidence interval\",\n            s => new ConfidenceInterval(s.Mean, s.StandardError, s.N, level).Lower, Priority.Additional);\n\n        [PublicAPI]\n        public static IColumn CiUpper(ConfidenceLevel level) => new StatisticColumn(\n            $\"CI{level} Upper\", $\"Upper bound of {level} confidence interval\",\n            s => new ConfidenceInterval(s.Mean, s.StandardError, s.N, level).Upper, Priority.Additional);\n\n        [PublicAPI]\n        public static IColumn CiError(ConfidenceLevel level) => new StatisticColumn(\n            $\"CI{level} Margin\", $\"Half of {level} confidence interval\",\n            s => new ConfidenceInterval(s.Mean, s.StandardError, s.N, level).Margin, Priority.Additional);\n\n\n        public static readonly IColumn[] AllStatistics = [Mean, StdErr, StdDev, OperationsPerSecond, Min, Q1, Median, Q3, Max];\n\n        private readonly Func<Statistics, double> calc;\n        public string Id => nameof(StatisticColumn) + \".\" + ColumnName;\n        public string ColumnName { get; }\n        private readonly Priority priority;\n        private readonly IStatisticColumn? parentColumn;\n\n        private StatisticColumn(string columnName, string legend, Func<Statistics, double> calc, Priority priority, UnitType type = UnitType.Time,\n            IStatisticColumn? parentColumn = null)\n        {\n            this.calc = calc;\n            this.priority = priority;\n            this.parentColumn = parentColumn;\n            UnitType = type;\n            ColumnName = columnName;\n            Legend = legend;\n        }\n\n        public string GetValue(Summary summary, BenchmarkCase benchmarkCase)\n            => Format(summary, benchmarkCase.Config, summary[benchmarkCase]?.ResultStatistics, SummaryStyle.Default);\n\n        public string GetValue(Summary summary, BenchmarkCase benchmarkCase, SummaryStyle style)\n            => Format(summary, benchmarkCase.Config, summary[benchmarkCase]?.ResultStatistics, style);\n\n        public bool IsAvailable(Summary summary) => true;\n        public bool AlwaysShow => true;\n        public ColumnCategory Category => ColumnCategory.Statistics;\n        public int PriorityInCategory => (int)priority;\n        public bool IsNumeric => true;\n        public UnitType UnitType { get; }\n\n        public string Legend { get; }\n\n        public List<double> GetAllValues(Summary summary, SummaryStyle style)\n        {\n            return summary.Reports\n                .Where(r => r.ResultStatistics != null)\n                .Select(r => calc(r.ResultStatistics!))\n                .Where(v => !double.IsNaN(v) && !double.IsInfinity(v))\n                .Select(v => UnitType == UnitType.Time && style.TimeUnit != null ? v / style.TimeUnit.BaseUnits : v)\n                .ToList();\n        }\n\n        private string Format(Summary summary, ImmutableConfig config, Statistics? statistics, SummaryStyle style)\n        {\n            if (statistics == null)\n                return \"NA\";\n            int precision = summary.DisplayPrecisionManager.GetPrecision(style, this, parentColumn);\n            string format = \"N\" + precision;\n\n            double value = calc(statistics);\n            if (double.IsNaN(value))\n                return \"NA\";\n            return UnitType == UnitType.Time\n                ? PerfolizerMeasurementFormatter.Instance.Format(\n                    TimeInterval.FromNanoseconds(value).ToMeasurement(style.TimeUnit),\n                    format,\n                    style.CultureInfo,\n                    new UnitPresentation(style.PrintUnitsInContent, minUnitWidth: 0, gap: true))\n                : value.ToString(format, style.CultureInfo);\n        }\n\n        public override string ToString() => ColumnName;\n\n        public bool IsDefault(Summary summary, BenchmarkCase benchmarkCase) => false;\n\n        private static IColumn CreatePercentileColumn(int percentiles, string columnName, Func<Statistics, double> calc) => new StatisticColumn(\n            columnName, \"Percentile \" + percentiles, calc, Priority.Percentiles);\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Columns/StatisticalTestColumn.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing BenchmarkDotNet.Mathematics;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Running;\nusing Perfolizer.Mathematics.Common;\nusing Perfolizer.Mathematics.SignificanceTesting;\nusing Perfolizer.Mathematics.SignificanceTesting.MannWhitney;\nusing Perfolizer.Metrology;\n\nnamespace BenchmarkDotNet.Columns\n{\n    public class StatisticalTestColumn(Threshold threshold, SignificanceLevel? significanceLevel = null) : BaselineCustomColumn\n    {\n        private static readonly SignificanceLevel DefaultSignificanceLevel = SignificanceLevel.P1E5;\n\n        public static StatisticalTestColumn CreateDefault() => new(new PercentValue(10).ToThreshold());\n\n        public static StatisticalTestColumn Create(Threshold threshold, SignificanceLevel? significanceLevel = null) => new(threshold, significanceLevel);\n\n        public static StatisticalTestColumn Create(string threshold, SignificanceLevel? significanceLevel = null)\n        {\n            if (!Threshold.TryParse(threshold, out var parsedThreshold))\n                throw new ArgumentException($\"Can't parse threshold '{threshold}'\");\n            return new StatisticalTestColumn(parsedThreshold, significanceLevel);\n        }\n\n        public Threshold Threshold { get; } = threshold;\n        public SignificanceLevel SignificanceLevel { get; } = significanceLevel ?? DefaultSignificanceLevel;\n\n        public override string Id => $\"{nameof(StatisticalTestColumn)}/{Threshold}\";\n        public override string ColumnName => $\"MannWhitney({Threshold})\";\n\n        public override string GetValue(Summary summary, BenchmarkCase benchmarkCase, Statistics baseline, IReadOnlyDictionary<string, Metric> baselineMetrics,\n            Statistics current, IReadOnlyDictionary<string, Metric> currentMetrics, bool isBaseline)\n        {\n            if (baseline.Sample.Values.SequenceEqual(current.Sample.Values))\n                return \"Baseline\";\n            if (current.Sample.Size == 1 && baseline.Sample.Size == 1)\n                return \"?\";\n\n            var test = new SimpleEquivalenceTest(MannWhitneyTest.Instance);\n            var comparisonResult = test.Perform(current.Sample, baseline.Sample, Threshold, SignificanceLevel);\n            return comparisonResult switch\n            {\n                ComparisonResult.Greater => \"Slower\",\n                ComparisonResult.Indistinguishable => \"Same\",\n                ComparisonResult.Lesser => \"Faster\",\n                _ => throw new ArgumentOutOfRangeException()\n            };\n        }\n\n        public override int PriorityInCategory => 0;\n        public override bool IsNumeric => false;\n        public override UnitType UnitType => UnitType.Dimensionless;\n\n        public override string Legend => $\"MannWhitney-based equivalence test (threshold={Threshold}, alpha = {SignificanceLevel})\";\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Columns/TagColumn.cs",
    "content": "﻿using System;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Running;\n\nnamespace BenchmarkDotNet.Columns\n{\n    public class TagColumn : IColumn\n    {\n        private readonly Func<string, string> getTag;\n\n        public string Id { get; }\n        public string ColumnName { get; }\n\n        public TagColumn(string columnName, Func<string, string> getTag)\n        {\n            this.getTag = getTag;\n            ColumnName = columnName;\n            Id = nameof(TagColumn) + \".\" + ColumnName;\n        }\n\n        public bool IsDefault(Summary summary, BenchmarkCase benchmarkCase) => false;\n        public string GetValue(Summary summary, BenchmarkCase benchmarkCase) => getTag(benchmarkCase.Descriptor?.WorkloadMethod?.Name ?? \"\");\n\n        public bool IsAvailable(Summary summary) => true;\n        public bool AlwaysShow => true;\n        public ColumnCategory Category => ColumnCategory.Custom;\n        public int PriorityInCategory => 0;\n        public bool IsNumeric => false;\n        public UnitType UnitType => UnitType.Dimensionless;\n        public string Legend => $\"Custom '{ColumnName}' tag column\";\n        public string GetValue(Summary summary, BenchmarkCase benchmarkCase, SummaryStyle style) => GetValue(summary, benchmarkCase);\n        public override string ToString() => ColumnName;\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Columns/TargetMethodColumn.cs",
    "content": "﻿using System;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Running;\n\nnamespace BenchmarkDotNet.Columns\n{\n    public class TargetMethodColumn : IColumn\n    {\n        public static readonly IColumn Namespace = new TargetMethodColumn(Column.Namespace, benchmark => benchmark.Descriptor.Type.Namespace ?? \"\");\n        public static readonly IColumn Type = new TargetMethodColumn(Column.Type, benchmark => benchmark.Descriptor.Type.GetDisplayName());\n        public static readonly IColumn Method = new TargetMethodColumn(Column.Method, benchmark => benchmark.Descriptor.WorkloadMethodDisplayInfo, true);\n\n        private readonly Func<BenchmarkCase, string> valueProvider;\n        public string Id => nameof(TargetMethodColumn) + \".\" + ColumnName;\n        public string ColumnName { get; }\n        public string GetValue(Summary summary, BenchmarkCase benchmarkCase) => valueProvider(benchmarkCase);\n        public bool IsAvailable(Summary summary) => true;\n        public bool AlwaysShow { get; }\n        public ColumnCategory Category => ColumnCategory.Job;\n        public int PriorityInCategory => 0;\n        public bool IsNumeric => false;\n        public UnitType UnitType => UnitType.Dimensionless;\n        public string Legend => \"\";\n        public string GetValue(Summary summary, BenchmarkCase benchmarkCase, SummaryStyle style) => GetValue(summary, benchmarkCase);\n\n        private TargetMethodColumn(string columnName, Func<BenchmarkCase, string> valueProvider, bool alwaysShow = false)\n        {\n            this.valueProvider = valueProvider;\n            AlwaysShow = alwaysShow;\n            ColumnName = columnName;\n        }\n\n        public override string ToString() => ColumnName;\n\n        public bool IsDefault(Summary summary, BenchmarkCase benchmarkCase) => false;\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Columns/UnitType.cs",
    "content": "﻿namespace BenchmarkDotNet.Columns\n{\n    // TODO: migrate to Perfolizer.Metrology\n    public enum UnitType\n    {\n        Dimensionless,\n        Time,\n        Size,\n        CodeSize\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Configs/BenchmarkLogicalGroupRule.cs",
    "content": "﻿namespace BenchmarkDotNet.Configs\n{\n    public enum BenchmarkLogicalGroupRule\n    {\n        ByMethod, ByJob, ByParams, ByCategory\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Configs/ConfigExtensions.cs",
    "content": "﻿using System;\nusing System.Collections.Immutable;\nusing System.ComponentModel;\nusing System.Globalization;\nusing System.Linq;\nusing System.Text;\nusing BenchmarkDotNet.Analysers;\nusing BenchmarkDotNet.Columns;\nusing BenchmarkDotNet.Diagnosers;\nusing BenchmarkDotNet.EventProcessors;\nusing BenchmarkDotNet.Exporters;\nusing BenchmarkDotNet.Filters;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Order;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Validators;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Configs\n{\n    public static class ConfigExtensions\n    {\n        [PublicAPI] public static ManualConfig AddColumn(this IConfig config, params IColumn[] columns) => config.With(m => m.AddColumn(columns));\n\n        [PublicAPI] public static ManualConfig AddColumnProvider(this IConfig config, params IColumnProvider[] columnProviders) => config.With(m => m.AddColumnProvider(columnProviders));\n\n        [PublicAPI] public static ManualConfig AddLogger(this IConfig config, params ILogger[] loggers) => config.With(m => m.AddLogger(loggers));\n\n        [PublicAPI] public static ManualConfig AddExporter(this IConfig config, params IExporter[] exporters) => config.With(m => m.AddExporter(exporters));\n\n        [PublicAPI] public static ManualConfig AddDiagnoser(this IConfig config, params IDiagnoser[] diagnosers) => config.With(m => m.AddDiagnoser(diagnosers));\n\n        [PublicAPI] public static ManualConfig AddAnalyser(this IConfig config, params IAnalyser[] analysers) => config.With(m => m.AddAnalyser(analysers));\n\n        [PublicAPI] public static ManualConfig AddValidator(this IConfig config, params IValidator[] validators) => config.With(m => m.AddValidator(validators));\n\n        [PublicAPI] public static ManualConfig AddJob(this IConfig config, Job job) => config.With(m => m.AddJob(job));\n\n        [PublicAPI] public static ManualConfig WithOrderer(this IConfig config, IOrderer orderer) => config.With(m => m.WithOrderer(orderer));\n\n        [PublicAPI] public static ManualConfig AddHardwareCounters(this IConfig config, params HardwareCounter[] counters) => config.With(c => c.AddHardwareCounters(counters));\n\n        [PublicAPI] public static ManualConfig AddFilter(this IConfig config, params IFilter[] filters) => config.With(c => c.AddFilter(filters));\n\n        [PublicAPI] public static ManualConfig WithSummaryStyle(this IConfig config, SummaryStyle summaryStyle) => config.With(c => c.WithSummaryStyle(summaryStyle));\n\n        [PublicAPI] public static ManualConfig WithArtifactsPath(this IConfig config, string artifactsPath) => config.With(m => m.WithArtifactsPath(artifactsPath));\n        [PublicAPI] public static ManualConfig WithUnionRule(this IConfig config, ConfigUnionRule unionRule) => config.With(m => m.WithUnionRule(unionRule));\n        [PublicAPI] public static ManualConfig WithCultureInfo(this IConfig config, CultureInfo cultureInfo) => config.With(m => m.CultureInfo = cultureInfo);\n\n        /// <summary>\n        /// determines if all auto-generated files should be kept or removed after running the benchmarks\n        /// </summary>\n        [PublicAPI] public static IConfig KeepBenchmarkFiles(this IConfig config, bool value = true) => config.WithOption(ConfigOptions.KeepBenchmarkFiles, value);\n\n        /// <summary>\n        /// determines if the exported result files should not be overwritten (be default they are overwritten)\n        /// </summary>\n\n        [PublicAPI] public static IConfig DontOverwriteResults(this IConfig config, bool value = true) => config.WithOption(ConfigOptions.DontOverwriteResults, value);\n\n        /// <summary>\n        /// determines if benchmarking should be stopped after the first error (by default it's not)\n        /// </summary>\n        [PublicAPI] public static IConfig StopOnFirstError(this IConfig config, bool value = true) => config.WithOption(ConfigOptions.StopOnFirstError, value);\n\n        /// <summary>\n        /// sets given option to provided value\n        /// </summary>\n        [PublicAPI] public static ManualConfig WithOption(this IConfig config, ConfigOptions option, bool value) => config.With(m => m.WithOption(option, value));\n\n        /// <summary>\n        /// sets given options for the config\n        /// </summary>\n        [PublicAPI] public static ManualConfig WithOptions(this IConfig config, ConfigOptions options) => config.With(m => m.WithOptions(options));\n\n        [PublicAPI] public static ManualConfig AddLogicalGroupRules(this IConfig config, params BenchmarkLogicalGroupRule[] rules) => config.With(c => c.AddLogicalGroupRules(rules));\n        [PublicAPI] public static ManualConfig AddEventProcessor(this IConfig config, params EventProcessor[] eventProcessors) => config.With(c => c.AddEventProcessor(eventProcessors));\n\n        [PublicAPI] public static ManualConfig HideColumns(this IConfig config, params string[] columnNames) => config.With(c => c.HideColumns(columnNames));\n        [PublicAPI] public static ManualConfig HideColumns(this IConfig config, params IColumn[] columns) => config.With(c => c.HideColumns(columns));\n        [PublicAPI] public static ManualConfig HideColumns(this IConfig config, params IColumnHidingRule[] rules) => config.With(c => c.HideColumns(rules));\n\n        public static ImmutableConfig CreateImmutableConfig(this IConfig config) => ImmutableConfigBuilder.Create(config);\n\n        internal static ILogger GetNonNullCompositeLogger(this IConfig config)\n        {\n            // if user did not provide any loggers, we use the ConsoleLogger to somehow show the errors to the user\n            if (config == null || !config.GetLoggers().Any())\n                return new CompositeLogger([ConsoleLogger.Default]);\n\n            return new CompositeLogger(config.GetLoggers().ToImmutableHashSet());\n        }\n\n        private static ManualConfig With(this IConfig config, Action<ManualConfig> addAction)\n        {\n            var manualConfig = ManualConfig.Create(config);\n            addAction(manualConfig);\n            return manualConfig;\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Configs/ConfigOptions.cs",
    "content": "﻿using System;\n\nnamespace BenchmarkDotNet.Configs\n{\n    [Flags]\n    public enum ConfigOptions\n    {\n        /// <summary>\n        /// no custom settings\n        /// </summary>\n        Default = 0,\n        /// <summary>\n        /// determines if all auto-generated files should be kept after running the benchmarks (be default they are removed)\n        /// </summary>\n        KeepBenchmarkFiles = 1 << 0,\n        /// <summary>\n        /// determines if all benchmarks results should be joined into a single summary (by default we have a summary per type)\n        /// </summary>\n        JoinSummary = 1 << 1,\n        /// <summary>\n        /// determines if benchmarking should be stopped after the first error (by default it's not)\n        /// </summary>\n        StopOnFirstError = 1 << 2,\n        /// <summary>\n        /// determines if \"mandatory\" optimizations validator should be entirely turned off\n        /// </summary>\n        DisableOptimizationsValidator = 1 << 3,\n        /// <summary>\n        /// determines if the exported result files should not be overwritten (be default they are overwritten)\n        /// </summary>\n        DontOverwriteResults = 1 << 4,\n        /// <summary>\n        /// Determines if the log file should be disabled.\n        /// </summary>\n        DisableLogFile = 1 << 5,\n        /// <summary>\n        /// Determines whether build output should be logged.\n        /// </summary>\n        LogBuildOutput = 1 << 6,\n        /// <summary>\n        /// Determines whether to generate msbuild binlogs\n        /// </summary>\n        GenerateMSBuildBinLog = 1 << 7,\n        /// <summary>\n        /// Performs apples-to-apples comparison for provided benchmarks and jobs. Experimental, will change in the near future!\n        /// </summary>\n        ApplesToApples = 1 << 8,\n        /// <summary>\n        /// Continue the execution if the last run was stopped.\n        /// </summary>\n        Resume = 1 << 9,\n        /// <summary>\n        /// Determines whether parallel build of benchmark projects should be disabled.\n        /// </summary>\n        DisableParallelBuild = 1 << 10,\n    }\n\n    internal static class ConfigOptionsExtensions\n    {\n        internal static bool IsSet(this ConfigOptions currentValue, ConfigOptions flag) => (currentValue & flag) == flag;\n\n        internal static ConfigOptions Set(this ConfigOptions currentValue, bool value, ConfigOptions flag) => value ? currentValue | flag : currentValue & ~flag;\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Configs/ConfigUnionRule.cs",
    "content": "﻿namespace BenchmarkDotNet.Configs\n{\n    public enum ConfigUnionRule\n    {\n        Union, AlwaysUseLocal, AlwaysUseGlobal\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Configs/DebugConfig.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Globalization;\nusing BenchmarkDotNet.Analysers;\nusing BenchmarkDotNet.Columns;\nusing BenchmarkDotNet.Diagnosers;\nusing BenchmarkDotNet.EventProcessors;\nusing BenchmarkDotNet.Exporters;\nusing BenchmarkDotNet.Filters;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Order;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Toolchains.InProcess.Emit;\nusing BenchmarkDotNet.Validators;\n\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Configs\n{\n    /// <summary>\n    /// config which allows to debug benchmarks running it in the same process\n    /// </summary>\n    [PublicAPI]\n    public class DebugInProcessConfig : DebugConfig\n    {\n        public override IEnumerable<Job> GetJobs() =>\n        [\n            Job.Default\n                .WithToolchain(InProcessEmitToolchain.Default)\n        ];\n    }\n\n    /// <summary>\n    /// config which allows to build benchmarks in Debug\n    /// </summary>\n    [PublicAPI]\n    public class DebugBuildConfig : DebugConfig\n    {\n        public override IEnumerable<Job> GetJobs() =>\n        [\n            Job.Default\n                .WithCustomBuildConfiguration(\"Debug\") // will do `-c Debug everywhere`\n        ];\n    }\n\n    public abstract class DebugConfig : IConfig\n    {\n        private readonly static Conclusion[] emptyConclusion = [];\n        public abstract IEnumerable<Job> GetJobs();\n\n        public IEnumerable<IValidator> GetValidators() => [];\n        public IEnumerable<IColumnProvider> GetColumnProviders() => DefaultColumnProviders.Instance;\n        public IEnumerable<IExporter> GetExporters() => [];\n        public IEnumerable<ILogger> GetLoggers() => [ConsoleLogger.Default];\n        public IEnumerable<IDiagnoser> GetDiagnosers() => [];\n        public IEnumerable<IAnalyser> GetAnalysers() => [];\n        public IEnumerable<HardwareCounter> GetHardwareCounters() => [];\n        public IEnumerable<EventProcessor> GetEventProcessors() => [];\n        public IEnumerable<IFilter> GetFilters() => [];\n        public IEnumerable<IColumnHidingRule> GetColumnHidingRules() => [];\n\n        public IOrderer Orderer => DefaultOrderer.Instance;\n        public ICategoryDiscoverer? CategoryDiscoverer => DefaultCategoryDiscoverer.Instance;\n        public SummaryStyle SummaryStyle => SummaryStyle.Default;\n        public ConfigUnionRule UnionRule => ConfigUnionRule.Union;\n        public TimeSpan BuildTimeout => DefaultConfig.Instance.BuildTimeout;\n        public WakeLockType WakeLock => WakeLockType.None;\n\n        public string? ArtifactsPath => null; // DefaultConfig.ArtifactsPath will be used if the user does not specify it in explicit way\n\n        public CultureInfo? CultureInfo => null;\n        public IEnumerable<BenchmarkLogicalGroupRule> GetLogicalGroupRules() => [];\n\n        public ConfigOptions Options => ConfigOptions.KeepBenchmarkFiles | ConfigOptions.DisableOptimizationsValidator;\n\n        public IReadOnlyList<Conclusion> ConfigAnalysisConclusion => emptyConclusion;\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Configs/DefaultConfig.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Globalization;\nusing System.IO;\nusing BenchmarkDotNet.Analysers;\nusing BenchmarkDotNet.Columns;\nusing BenchmarkDotNet.Detectors;\nusing BenchmarkDotNet.Diagnosers;\nusing BenchmarkDotNet.EventProcessors;\nusing BenchmarkDotNet.Exporters;\nusing BenchmarkDotNet.Exporters.Csv;\nusing BenchmarkDotNet.Filters;\nusing BenchmarkDotNet.Helpers;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Order;\nusing BenchmarkDotNet.Portability;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Validators;\n\nnamespace BenchmarkDotNet.Configs\n{\n    public class DefaultConfig : IConfig\n    {\n        public static IConfig Instance => customDefaultConfig ?? Default;\n\n        public static readonly IConfig Default = new DefaultConfig();\n\n        private readonly static Conclusion[] emptyConclusion = [];\n\n        private static IConfig? customDefaultConfig = null;\n\n        private DefaultConfig()\n        {\n        }\n\n        public static void SetCustomConfig(ImmutableConfig? config)\n        {\n            customDefaultConfig = config;\n        }\n\n        public IEnumerable<IColumnProvider> GetColumnProviders() => DefaultColumnProviders.Instance;\n\n        public IEnumerable<IExporter> GetExporters()\n        {\n            // Now that we can specify exporters on the cmd line (e.g. \"exporters=html,stackoverflow\"),\n            // we should have less enabled by default and then users can turn on the ones they want\n            yield return CsvExporter.Default;\n            yield return MarkdownExporter.GitHub;\n            yield return HtmlExporter.Default;\n        }\n\n        public IEnumerable<ILogger> GetLoggers()\n        {\n            if (LinqPadLogger.IsAvailable)\n                yield return LinqPadLogger.Instance!;\n            else\n                yield return ConsoleLogger.Default;\n        }\n\n        public IEnumerable<IAnalyser> GetAnalysers()\n        {\n            yield return EnvironmentAnalyser.Default;\n            yield return OutliersAnalyser.Default;\n            yield return MinIterationTimeAnalyser.Default;\n            yield return MultimodalDistributionAnalyzer.Default;\n            yield return RuntimeErrorAnalyser.Default;\n            yield return ZeroMeasurementAnalyser.Default;\n            yield return BaselineCustomAnalyzer.Default;\n            yield return HideColumnsAnalyser.Default;\n        }\n\n        public IEnumerable<IValidator> GetValidators()\n        {\n            yield return BaselineValidator.FailOnError;\n            yield return SetupCleanupValidator.FailOnError;\n#if !DEBUG\n            yield return JitOptimizationsValidator.FailOnError;\n#endif\n            yield return RunModeValidator.FailOnError;\n            yield return GenericBenchmarksValidator.DontFailOnError;\n            yield return DeferredExecutionValidator.FailOnError;\n            yield return ParamsAllValuesValidator.FailOnError;\n            yield return ParamsValidator.FailOnError;\n            yield return RuntimeValidator.DontFailOnError;\n        }\n\n        public IOrderer? Orderer => null;\n        public ICategoryDiscoverer? CategoryDiscoverer => null;\n\n        public ConfigUnionRule UnionRule => ConfigUnionRule.Union;\n\n        public CultureInfo? CultureInfo => null;\n\n        public ConfigOptions Options => ConfigOptions.Default;\n\n        public SummaryStyle SummaryStyle => SummaryStyle.Default;\n\n        public TimeSpan BuildTimeout => TimeSpan.FromSeconds(120);\n\n        public WakeLockType WakeLock => WakeLockType.System;\n\n        public string ArtifactsPath\n        {\n            get\n            {\n                string root;\n                if (OsDetector.IsAndroid() || OsDetector.IsIOS())\n                {\n                    // On mobile platforms (Android, iOS, and Mac Catalyst), use a writable location\n                    // because the app bundle and current directory are read-only due to sandboxing\n                    root = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);\n                }\n                else\n                {\n                    root = Directory.GetCurrentDirectory();\n                }\n                return Path.Combine(root, \"BenchmarkDotNet.Artifacts\");\n            }\n        }\n\n        public IReadOnlyList<Conclusion> ConfigAnalysisConclusion => emptyConclusion;\n\n        public IEnumerable<Job> GetJobs() => [];\n\n        public IEnumerable<BenchmarkLogicalGroupRule> GetLogicalGroupRules() => [];\n\n        public IEnumerable<IDiagnoser> GetDiagnosers() => [];\n\n        public IEnumerable<HardwareCounter> GetHardwareCounters() => [];\n\n        public IEnumerable<IFilter> GetFilters() => [];\n\n        public IEnumerable<EventProcessor> GetEventProcessors() => [];\n\n        public IEnumerable<IColumnHidingRule> GetColumnHidingRules() => [];\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Configs/IConfig.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Globalization;\nusing BenchmarkDotNet.Analysers;\nusing BenchmarkDotNet.Columns;\nusing BenchmarkDotNet.Diagnosers;\nusing BenchmarkDotNet.EventProcessors;\nusing BenchmarkDotNet.Exporters;\nusing BenchmarkDotNet.Filters;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Order;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Validators;\n\nnamespace BenchmarkDotNet.Configs\n{\n    public interface IConfig\n    {\n        IEnumerable<IColumnProvider> GetColumnProviders();\n        IEnumerable<IExporter> GetExporters();\n        IEnumerable<ILogger> GetLoggers();\n        IEnumerable<IDiagnoser> GetDiagnosers();\n        IEnumerable<IAnalyser> GetAnalysers();\n        IEnumerable<Job> GetJobs();\n        IEnumerable<IValidator> GetValidators();\n        IEnumerable<HardwareCounter> GetHardwareCounters();\n        IEnumerable<IFilter> GetFilters();\n        IEnumerable<BenchmarkLogicalGroupRule> GetLogicalGroupRules();\n        IEnumerable<EventProcessor> GetEventProcessors();\n        IEnumerable<IColumnHidingRule> GetColumnHidingRules();\n\n        IOrderer? Orderer { get; }\n        ICategoryDiscoverer? CategoryDiscoverer { get; }\n\n        SummaryStyle? SummaryStyle { get; }\n\n        ConfigUnionRule UnionRule { get; }\n\n        /// <summary>\n        /// the default value is \"./BenchmarkDotNet.Artifacts\"\n        /// </summary>\n        string? ArtifactsPath { get; }\n\n        CultureInfo? CultureInfo { get; }\n\n        /// <summary>\n        /// a set of custom flags that can enable/disable various settings\n        /// </summary>\n        ConfigOptions Options { get; }\n\n        /// <summary>\n        /// the auto-generated project build timeout\n        /// </summary>\n        TimeSpan BuildTimeout { get; }\n\n        public WakeLockType WakeLock { get; }\n\n        /// <summary>\n        /// Collect any errors or warnings when composing the configuration\n        /// </summary>\n        IReadOnlyList<Conclusion> ConfigAnalysisConclusion { get; }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Configs/IConfigSource.cs",
    "content": "﻿namespace BenchmarkDotNet.Configs\n{\n    public interface IConfigSource\n    {\n         IConfig Config { get; }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Configs/ImmutableConfig.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Collections.Immutable;\nusing System.Globalization;\nusing System.Linq;\nusing BenchmarkDotNet.Analysers;\nusing BenchmarkDotNet.Columns;\nusing BenchmarkDotNet.Diagnosers;\nusing BenchmarkDotNet.EventProcessors;\nusing BenchmarkDotNet.Exporters;\nusing BenchmarkDotNet.Filters;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Order;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Validators;\nusing RunMode = BenchmarkDotNet.Diagnosers.RunMode;\n\nnamespace BenchmarkDotNet.Configs\n{\n    public sealed class ImmutableConfig : IConfig\n    {\n        // if something is an array here instead of hashset it means it must have a guaranteed order of elements\n        private readonly ImmutableArray<IColumnProvider> columnProviders;\n        private readonly ImmutableArray<IExporter> exporters;\n        private readonly ImmutableHashSet<ILogger> loggers;\n        private readonly ImmutableHashSet<IDiagnoser> diagnosers;\n        private readonly ImmutableHashSet<IAnalyser> analysers;\n        private readonly ImmutableHashSet<IValidator> validators;\n        private readonly ImmutableHashSet<Job> jobs;\n        private readonly ImmutableHashSet<HardwareCounter> hardwareCounters;\n        private readonly ImmutableHashSet<IFilter> filters;\n        private readonly ImmutableArray<BenchmarkLogicalGroupRule> rules;\n        private readonly ImmutableHashSet<EventProcessor> eventProcessors;\n        private readonly ImmutableArray<IColumnHidingRule> columnHidingRules;\n\n        internal ImmutableConfig(\n            ImmutableArray<IColumnProvider> uniqueColumnProviders,\n            ImmutableHashSet<ILogger> uniqueLoggers,\n            ImmutableHashSet<HardwareCounter> uniqueHardwareCounters,\n            ImmutableHashSet<IDiagnoser> uniqueDiagnosers,\n            ImmutableArray<IExporter> uniqueExporters,\n            ImmutableHashSet<IAnalyser> uniqueAnalyzers,\n            ImmutableHashSet<IValidator> uniqueValidators,\n            ImmutableHashSet<IFilter> uniqueFilters,\n            ImmutableArray<BenchmarkLogicalGroupRule> uniqueRules,\n            ImmutableArray<IColumnHidingRule> uniqueColumnHidingRules,\n            ImmutableHashSet<Job> uniqueRunnableJobs,\n            ImmutableHashSet<EventProcessor> uniqueEventProcessors,\n            ConfigUnionRule unionRule,\n            string artifactsPath,\n            CultureInfo cultureInfo,\n            IOrderer orderer,\n            ICategoryDiscoverer categoryDiscoverer,\n            SummaryStyle summaryStyle,\n            ConfigOptions options,\n            TimeSpan buildTimeout,\n            WakeLockType wakeLock,\n            IReadOnlyList<Conclusion> configAnalysisConclusion)\n        {\n            columnProviders = uniqueColumnProviders;\n            loggers = uniqueLoggers;\n            hardwareCounters = uniqueHardwareCounters;\n            diagnosers = uniqueDiagnosers;\n            exporters = uniqueExporters;\n            analysers = uniqueAnalyzers;\n            validators = uniqueValidators;\n            filters = uniqueFilters;\n            rules = uniqueRules;\n            columnHidingRules = uniqueColumnHidingRules;\n            jobs = uniqueRunnableJobs;\n            eventProcessors = uniqueEventProcessors;\n            UnionRule = unionRule;\n            ArtifactsPath = artifactsPath;\n            CultureInfo = cultureInfo;\n            Orderer = orderer;\n            CategoryDiscoverer = categoryDiscoverer;\n            SummaryStyle = summaryStyle;\n            Options = options;\n            BuildTimeout = buildTimeout;\n            WakeLock = wakeLock;\n            ConfigAnalysisConclusion = configAnalysisConclusion;\n        }\n\n        public ConfigUnionRule UnionRule { get; }\n        public string ArtifactsPath { get; }\n        public CultureInfo CultureInfo { get; }\n        public ConfigOptions Options { get; }\n        public IOrderer Orderer { get; }\n        public ICategoryDiscoverer CategoryDiscoverer { get; }\n        public SummaryStyle SummaryStyle { get; }\n        public TimeSpan BuildTimeout { get; }\n        public WakeLockType WakeLock { get; }\n\n        public IEnumerable<IColumnProvider> GetColumnProviders() => columnProviders;\n        public IEnumerable<IExporter> GetExporters() => exporters;\n        public IEnumerable<ILogger> GetLoggers() => loggers;\n        public IEnumerable<IDiagnoser> GetDiagnosers() => diagnosers;\n        public IEnumerable<IAnalyser> GetAnalysers() => analysers;\n        public IEnumerable<Job> GetJobs() => jobs;\n        public IEnumerable<IValidator> GetValidators() => validators;\n        public IEnumerable<HardwareCounter> GetHardwareCounters() => hardwareCounters;\n        public IEnumerable<IFilter> GetFilters() => filters;\n        public IEnumerable<BenchmarkLogicalGroupRule> GetLogicalGroupRules() => rules;\n        public IEnumerable<EventProcessor> GetEventProcessors() => eventProcessors;\n        public IEnumerable<IColumnHidingRule> GetColumnHidingRules() => columnHidingRules;\n\n        public ILogger GetCompositeLogger() => new CompositeLogger(loggers);\n        public IExporter GetCompositeExporter() => new CompositeExporter(exporters);\n        public IValidator GetCompositeValidator() => new CompositeValidator(validators);\n        public IAnalyser GetCompositeAnalyser() => new CompositeAnalyser(analysers);\n        public IDiagnoser GetCompositeDiagnoser() => new CompositeDiagnoser(diagnosers);\n\n        public bool HasMemoryDiagnoser() => diagnosers.OfType<MemoryDiagnoser>().Any();\n\n        internal bool HasPerfCollectProfiler() => diagnosers.OfType<PerfCollectProfiler>().Any();\n\n        internal bool HasDisassemblyDiagnoser() => diagnosers.OfType<DisassemblyDiagnoser>().Any();\n\n        public bool HasExtraIterationDiagnoser(BenchmarkCase benchmarkCase) => HasMemoryDiagnoser() || diagnosers.Any(d => d.GetRunMode(benchmarkCase) == RunMode.ExtraIteration);\n\n        public IDiagnoser? GetCompositeDiagnoser(BenchmarkCase benchmarkCase, Func<RunMode, bool> runModeComparer)\n        {\n            var diagnosersForGivenMode = diagnosers.Where(diagnoser => runModeComparer(diagnoser.GetRunMode(benchmarkCase))).ToImmutableHashSet();\n\n            return diagnosersForGivenMode.Any() ? new CompositeDiagnoser(diagnosersForGivenMode) : null;\n        }\n\n        public IReadOnlyList<Conclusion> ConfigAnalysisConclusion { get; private set; }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Configs/ImmutableConfigBuilder.cs",
    "content": "﻿using BenchmarkDotNet.Analysers;\nusing BenchmarkDotNet.Diagnosers;\nusing BenchmarkDotNet.Exporters;\nusing BenchmarkDotNet.Helpers;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Order;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Validators;\nusing System.Collections.Generic;\nusing System.Collections.Immutable;\nusing System.Linq;\n\nnamespace BenchmarkDotNet.Configs\n{\n    /// <summary>\n    /// this class is responsible for config that has no duplicates, does all of the internal hacks and is ready to run\n    /// </summary>\n    public static class ImmutableConfigBuilder\n    {\n        private static readonly IValidator[] MandatoryValidators =\n        {\n            BaselineValidator.FailOnError,\n            SetupCleanupValidator.FailOnError,\n            RunModeValidator.FailOnError,\n            DiagnosersValidator.Composite,\n            CompilationValidator.FailOnError,\n            ConfigValidator.DontFailOnError,\n            ShadowCopyValidator.DontFailOnError,\n            JitOptimizationsValidator.DontFailOnError,\n            DeferredExecutionValidator.DontFailOnError,\n            ParamsAllValuesValidator.FailOnError,\n            ParamsValidator.FailOnError\n        };\n\n        /// <summary>\n        /// removes duplicates and applies all extra logic required to make the config a final one\n        /// </summary>\n        public static ImmutableConfig Create(IConfig source)\n        {\n            var uniqueColumnProviders = source.GetColumnProviders().Distinct().ToImmutableArray();\n            var uniqueLoggers = source.GetLoggers().ToImmutableHashSet();\n            var configAnalyse = new List<Conclusion>();\n\n            var uniqueHardwareCounters = source.GetHardwareCounters().Where(counter => counter != HardwareCounter.NotSet).ToImmutableHashSet();\n            var uniqueDiagnosers = GetDiagnosers(source.GetDiagnosers(), uniqueHardwareCounters);\n            var uniqueExporters = GetExporters(source.GetExporters(), uniqueDiagnosers, configAnalyse);\n            var uniqueAnalyzers = GetAnalysers(source.GetAnalysers(), uniqueDiagnosers);\n\n            var uniqueValidators = GetValidators(source.GetValidators(), MandatoryValidators, source.Options);\n\n            var uniqueFilters = source.GetFilters().ToImmutableHashSet();\n            var uniqueRules = source.GetLogicalGroupRules().ToImmutableArray();\n            var uniqueHidingRules = source.GetColumnHidingRules().ToImmutableArray();\n\n            var uniqueRunnableJobs = GetRunnableJobs(source.GetJobs()).ToImmutableHashSet();\n            var uniqueEventProcessors = source.GetEventProcessors().ToImmutableHashSet();\n\n            return new ImmutableConfig(\n                uniqueColumnProviders,\n                uniqueLoggers,\n                uniqueHardwareCounters,\n                uniqueDiagnosers,\n                uniqueExporters,\n                uniqueAnalyzers,\n                uniqueValidators,\n                uniqueFilters,\n                uniqueRules,\n                uniqueHidingRules,\n                uniqueRunnableJobs,\n                uniqueEventProcessors,\n                source.UnionRule,\n                source.ArtifactsPath ?? DefaultConfig.Instance.ArtifactsPath!,\n                source.CultureInfo ?? DefaultCultureInfo.Instance,\n                source.Orderer ?? DefaultOrderer.Instance,\n                source.CategoryDiscoverer ?? DefaultCategoryDiscoverer.Instance,\n                source.SummaryStyle ?? SummaryStyle.Default,\n                source.Options,\n                source.BuildTimeout,\n                source.WakeLock,\n                configAnalyse.AsReadOnly()\n            );\n        }\n\n        private static ImmutableHashSet<IDiagnoser> GetDiagnosers(IEnumerable<IDiagnoser> diagnosers, ImmutableHashSet<HardwareCounter> uniqueHardwareCounters)\n        {\n            var builder = ImmutableHashSet.CreateBuilder(new TypeComparer<IDiagnoser>());\n\n            foreach (var diagnoser in diagnosers)\n                if (!builder.Contains(diagnoser))\n                    builder.Add(diagnoser);\n\n            if (!uniqueHardwareCounters.IsEmpty && !diagnosers.OfType<IHardwareCountersDiagnoser>().Any())\n            {\n                // if users define hardware counters via [HardwareCounters] we need to dynamically load the right diagnoser\n                var hardwareCountersDiagnoser = DiagnosersLoader.GetImplementation<IHardwareCountersDiagnoser>();\n\n                if (hardwareCountersDiagnoser != default(IDiagnoser) && !builder.Contains(hardwareCountersDiagnoser))\n                    builder.Add(hardwareCountersDiagnoser);\n            }\n\n            return builder.ToImmutable();\n        }\n\n        private static ImmutableArray<IExporter> GetExporters(IEnumerable<IExporter> exporters,\n            ImmutableHashSet<IDiagnoser> uniqueDiagnosers,\n            IList<Conclusion> configAnalyse)\n        {\n\n            void AddWarning(string message)\n            {\n                var conclusion = Conclusion.CreateWarning(\"Configuration\", message);\n                configAnalyse.Add(conclusion);\n            }\n\n            var mergeDictionary = new Dictionary<string, IExporter>();\n\n            foreach (var exporter in exporters)\n            {\n                var exporterName = exporter.Name;\n                if (mergeDictionary.ContainsKey(exporterName))\n                {\n                    AddWarning($\"The exporter {exporterName} is already present in configuration. There may be unexpected results.\");\n                }\n                mergeDictionary[exporterName] = exporter;\n            }\n\n\n            foreach (var diagnoser in uniqueDiagnosers)\n                foreach (var exporter in diagnoser.Exporters)\n                {\n                    var exporterName = exporter.Name;\n                    if (mergeDictionary.ContainsKey(exporterName))\n                    {\n                        AddWarning($\"The exporter {exporterName} of {diagnoser.GetType().Name} is already present in configuration. There may be unexpected results.\");\n                    }\n                    mergeDictionary[exporterName] = exporter;\n                }\n\n            var result = mergeDictionary.Values.ToList();\n\n\n            var hardwareCounterDiagnoser = uniqueDiagnosers.OfType<IHardwareCountersDiagnoser>().SingleOrDefault();\n            var disassemblyDiagnoser = uniqueDiagnosers.OfType<DisassemblyDiagnoser>().SingleOrDefault();\n\n            // we can use InstructionPointerExporter only when we have both IHardwareCountersDiagnoser and DisassemblyDiagnoser\n            if (hardwareCounterDiagnoser != default(IHardwareCountersDiagnoser) && disassemblyDiagnoser != default(DisassemblyDiagnoser))\n                result.Add(new InstructionPointerExporter(hardwareCounterDiagnoser, disassemblyDiagnoser));\n\n            for (int i = result.Count - 1; i >= 0; i--)\n                if (result[i] is IExporterDependencies exporterDependencies)\n                    foreach (var dependency in exporterDependencies.Dependencies)\n                        /*\n                         *  When exporter that depends on an other already present in the configuration print warning.\n                         *\n                         *  Example:\n                         *\n                         *  // Global Current Culture separator is Semicolon;\n                         *  [CsvMeasurementsExporter(CsvSeparator.Comma)] // force use Comma\n                         *  [RPlotExporter]\n                         *  public class MyBanch\n                         *  {\n                         *\n                         *  }\n                         *\n                         *  RPlotExporter is depend from CsvMeasurementsExporter.Default\n                         *\n                         *  On active logger will by print:\n                         *  \"The CsvMeasurementsExporter is already present in the configuration. There may be unexpected results of RPlotExporter.\n                         *\n                         */\n                        if (!result.Any(exporter => exporter.GetType() == dependency.GetType()))\n                            result.Insert(i, dependency); // All the exporter dependencies should be added before the exporter\n                        else\n                        {\n                            AddWarning($\"The {dependency.Name} is already present in the configuration. There may be unexpected results of {result[i].GetType().Name}.\");\n                        }\n\n            result.Sort((left, right) => (left is IExporterDependencies).CompareTo(right is IExporterDependencies)); // the case when they were defined by user in wrong order ;)\n\n            return result.ToImmutableArray();\n        }\n\n        private static ImmutableHashSet<IAnalyser> GetAnalysers(IEnumerable<IAnalyser> analysers, ImmutableHashSet<IDiagnoser> uniqueDiagnosers)\n        {\n            var builder = ImmutableHashSet.CreateBuilder<IAnalyser>();\n\n            foreach (var analyser in analysers)\n                if (!builder.Contains(analyser))\n                    builder.Add(analyser);\n\n            foreach (var diagnoser in uniqueDiagnosers)\n                foreach (var analyser in diagnoser.Analysers)\n                    if (!builder.Contains(analyser))\n                        builder.Add(analyser);\n\n            return builder.ToImmutable();\n        }\n\n        private static ImmutableHashSet<IValidator> GetValidators(IEnumerable<IValidator> configuredValidators, IValidator[] mandatoryValidators, ConfigOptions options)\n        {\n            var builder = ImmutableHashSet.CreateBuilder<IValidator>();\n\n            foreach (var validator in configuredValidators\n                .Concat(mandatoryValidators)\n                .GroupBy(validator => validator.GetType())\n                .Select(groupedByType => groupedByType.FirstOrDefault(validator => validator.TreatsWarningsAsErrors) ?? groupedByType.First()))\n            {\n                builder.Add(validator);\n            }\n\n            if (options.IsSet(ConfigOptions.DisableOptimizationsValidator) && builder.Contains(JitOptimizationsValidator.DontFailOnError))\n                builder.Remove(JitOptimizationsValidator.DontFailOnError);\n            if (options.IsSet(ConfigOptions.DisableOptimizationsValidator) && builder.Contains(JitOptimizationsValidator.FailOnError))\n                builder.Remove(JitOptimizationsValidator.FailOnError);\n\n            return builder.ToImmutable();\n        }\n\n        /// <summary>\n        /// returns a set of unique jobs that are ready to run\n        /// </summary>\n        private static IReadOnlyList<Job> GetRunnableJobs(IEnumerable<Job> jobs)\n        {\n            var unique = jobs.Distinct(JobComparer.Default).ToArray();\n            var result = new List<Job>();\n\n            foreach (var standardJob in unique.Where(job => !job.Meta.IsMutator && !job.Meta.IsDefault))\n                result.Add(standardJob);\n\n            var customDefaultJob = unique.SingleOrDefault(job => job.Meta.IsDefault);\n            var defaultJob = customDefaultJob ?? Job.Default;\n\n            if (!result.Any())\n                result.Add(defaultJob);\n\n            foreach (var mutatorJob in unique.Where(job => job.Meta.IsMutator))\n            {\n                for (int i = 0; i < result.Count; i++)\n                {\n                    var copy = result[i].UnfreezeCopy();\n\n                    copy.Apply(mutatorJob);\n\n                    result[i] = copy.Freeze();\n                }\n            }\n\n            return result;\n        }\n\n        private class TypeComparer<TInterface> : IEqualityComparer<TInterface>\n        {\n            // different types can implement the same interface, we want to distinct by type\n            public bool Equals(TInterface? x, TInterface? y)\n            {\n                if (ReferenceEquals(x, y))\n                    return true;\n                if (x is null || y is null)\n                    return false;\n\n                return x.GetType() == y.GetType();\n            }\n\n            public int GetHashCode(TInterface obj) => obj?.GetType().GetHashCode() ?? 0;\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Configs/ManualConfig.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Globalization;\nusing System.Linq;\nusing BenchmarkDotNet.Analysers;\nusing BenchmarkDotNet.Columns;\nusing BenchmarkDotNet.Diagnosers;\nusing BenchmarkDotNet.EventProcessors;\nusing BenchmarkDotNet.Exporters;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Filters;\nusing BenchmarkDotNet.Helpers;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Order;\nusing BenchmarkDotNet.Portability;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Validators;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Configs\n{\n    public class ManualConfig : IConfig\n    {\n        private readonly static Conclusion[] emptyConclusion = [];\n\n        private readonly List<IColumnProvider> columnProviders = [];\n        private readonly List<IExporter> exporters = [];\n        private readonly List<ILogger> loggers = [];\n        private readonly List<IDiagnoser> diagnosers = [];\n        private readonly List<IAnalyser> analysers = [];\n        private readonly List<IValidator> validators = [];\n        private readonly List<Job> jobs = [];\n        private readonly HashSet<HardwareCounter> hardwareCounters = [];\n        private readonly List<IFilter> filters = [];\n        private readonly List<BenchmarkLogicalGroupRule> logicalGroupRules = [];\n        private readonly List<EventProcessor> eventProcessors = [];\n        private readonly List<IColumnHidingRule> columnHidingRules = [];\n\n        public IEnumerable<IColumnProvider> GetColumnProviders() => columnProviders;\n        public IEnumerable<IExporter> GetExporters() => exporters;\n        public IEnumerable<ILogger> GetLoggers() => loggers;\n        public IEnumerable<IDiagnoser> GetDiagnosers() => diagnosers;\n        public IEnumerable<IAnalyser> GetAnalysers() => analysers;\n        public IEnumerable<IValidator> GetValidators() => validators;\n        public IEnumerable<Job> GetJobs() => jobs;\n        public IEnumerable<HardwareCounter> GetHardwareCounters() => hardwareCounters;\n        public IEnumerable<IFilter> GetFilters() => filters;\n        public IEnumerable<BenchmarkLogicalGroupRule> GetLogicalGroupRules() => logicalGroupRules;\n        public IEnumerable<EventProcessor> GetEventProcessors() => eventProcessors;\n        public IEnumerable<IColumnHidingRule> GetColumnHidingRules() => columnHidingRules;\n\n        [PublicAPI] public ConfigOptions Options { get; set; }\n        [PublicAPI] public ConfigUnionRule UnionRule { get; set; } = ConfigUnionRule.Union;\n        [PublicAPI] public string? ArtifactsPath { get; set; }\n        [PublicAPI] public CultureInfo? CultureInfo { get; set; }\n        [PublicAPI] public IOrderer? Orderer { get; set; }\n        [PublicAPI] public ICategoryDiscoverer? CategoryDiscoverer { get; set; }\n        [PublicAPI] public SummaryStyle? SummaryStyle { get; set; }\n        [PublicAPI] public TimeSpan BuildTimeout { get; set; } = DefaultConfig.Instance.BuildTimeout;\n        [PublicAPI] public WakeLockType WakeLock { get; set; } = DefaultConfig.Instance.WakeLock;\n\n        public IReadOnlyList<Conclusion> ConfigAnalysisConclusion => emptyConclusion;\n\n        public ManualConfig WithOption(ConfigOptions option, bool value)\n        {\n            Options = Options.Set(value, option);\n            return this;\n        }\n\n        public ManualConfig WithOptions(ConfigOptions options)\n        {\n            Options |= options;\n            return this;\n        }\n\n        public ManualConfig WithUnionRule(ConfigUnionRule unionRule)\n        {\n            UnionRule = unionRule;\n            return this;\n        }\n\n        public ManualConfig WithArtifactsPath(string artifactsPath)\n        {\n            ArtifactsPath = artifactsPath;\n            return this;\n        }\n\n        public ManualConfig WithSummaryStyle(SummaryStyle summaryStyle)\n        {\n            SummaryStyle = summaryStyle;\n            return this;\n        }\n\n        public ManualConfig WithOrderer(IOrderer orderer)\n        {\n            Orderer = orderer;\n            return this;\n        }\n\n        public ManualConfig WithCategoryDiscoverer(ICategoryDiscoverer categoryDiscoverer)\n        {\n            CategoryDiscoverer = categoryDiscoverer;\n            return this;\n        }\n\n        public ManualConfig WithBuildTimeout(TimeSpan buildTimeout)\n        {\n            BuildTimeout = buildTimeout;\n            return this;\n        }\n\n        public ManualConfig WithWakeLock(WakeLockType wakeLockType)\n        {\n            WakeLock = wakeLockType;\n            return this;\n        }\n\n        public ManualConfig AddColumn(params IColumn[] newColumns)\n        {\n            columnProviders.AddRangeDistinct(newColumns.Select(c => c.ToProvider()));\n            return this;\n        }\n\n        public ManualConfig AddColumnProvider(params IColumnProvider[] newColumnProviders)\n        {\n            columnProviders.AddRangeDistinct(newColumnProviders);\n            return this;\n        }\n\n        public ManualConfig AddExporter(params IExporter[] newExporters)\n        {\n            exporters.AddRangeDistinct(newExporters);\n            return this;\n        }\n\n        public ManualConfig AddLogger(params ILogger[] newLoggers)\n        {\n            loggers.AddRangeDistinct(newLoggers);\n            return this;\n        }\n\n        public ManualConfig AddDiagnoser(params IDiagnoser[] newDiagnosers)\n        {\n            diagnosers.AddRangeDistinct(newDiagnosers);\n            return this;\n        }\n\n        public ManualConfig AddAnalyser(params IAnalyser[] newAnalysers)\n        {\n            analysers.AddRangeDistinct(newAnalysers);\n            return this;\n        }\n\n        public ManualConfig AddValidator(params IValidator[] newValidators)\n        {\n            validators.AddRangeDistinct(newValidators);\n            return this;\n        }\n\n        public ManualConfig AddJob(params Job[] newJobs)\n        {\n            jobs.AddRangeDistinct(newJobs.Select(j => j.Freeze())); // DONTTOUCH: please DO NOT remove .Freeze() call.\n            return this;\n        }\n\n        public ManualConfig AddHardwareCounters(params HardwareCounter[] newHardwareCounters)\n        {\n            hardwareCounters.AddRange(newHardwareCounters);\n            return this;\n        }\n\n        public ManualConfig AddFilter(params IFilter[] newFilters)\n        {\n            filters.AddRangeDistinct(newFilters);\n            return this;\n        }\n\n        public ManualConfig AddLogicalGroupRules(params BenchmarkLogicalGroupRule[] rules)\n        {\n            logicalGroupRules.AddRangeDistinct(rules);\n            return this;\n        }\n\n        public ManualConfig AddEventProcessor(params EventProcessor[] newEventProcessors)\n        {\n            eventProcessors.AddRangeDistinct(newEventProcessors);\n            return this;\n        }\n\n        [PublicAPI]\n        public ManualConfig HideColumns(params string[] columnNames)\n        {\n            columnHidingRules.AddRangeDistinct(columnNames.Select(c => new ColumnHidingByNameRule(c)));\n            return this;\n        }\n\n        [PublicAPI]\n        public ManualConfig HideColumns(params IColumn[] columns)\n        {\n            columnHidingRules.AddRangeDistinct(columns.Select(c => new ColumnHidingByIdRule(c)));\n            return this;\n        }\n\n        [PublicAPI]\n        public ManualConfig HideColumns(params IColumnHidingRule[] rules)\n        {\n            columnHidingRules.AddRangeDistinct(rules);\n            return this;\n        }\n\n        [PublicAPI]\n        public void Add(IConfig config)\n        {\n            columnProviders.AddRangeDistinct(config.GetColumnProviders());\n            exporters.AddRangeDistinct(config.GetExporters());\n            loggers.AddRangeDistinct(config.GetLoggers());\n            diagnosers.AddRangeDistinct(config.GetDiagnosers());\n            analysers.AddRangeDistinct(config.GetAnalysers());\n            jobs.AddRangeDistinct(config.GetJobs());\n            validators.AddRangeDistinct(config.GetValidators());\n            hardwareCounters.AddRange(config.GetHardwareCounters());\n            filters.AddRangeDistinct(config.GetFilters());\n            eventProcessors.AddRangeDistinct(config.GetEventProcessors());\n            Orderer = config.Orderer ?? Orderer;\n            CategoryDiscoverer = config.CategoryDiscoverer ?? CategoryDiscoverer;\n            ArtifactsPath = config.ArtifactsPath ?? ArtifactsPath;\n            CultureInfo = config.CultureInfo ?? CultureInfo;\n            SummaryStyle = config.SummaryStyle ?? SummaryStyle;\n            logicalGroupRules.AddRangeDistinct(config.GetLogicalGroupRules());\n            columnHidingRules.AddRangeDistinct(config.GetColumnHidingRules());\n            Options |= config.Options;\n            BuildTimeout = GetBuildTimeout(BuildTimeout, config.BuildTimeout);\n            WakeLock = GetWakeLock(WakeLock, config.WakeLock);\n        }\n\n        /// <summary>\n        /// Creates a completely EMPTY config with no predefined settings.\n        /// </summary>\n        /// <remarks>You should most probably use the <see cref=\"CreateMinimumViable\"></see> method instead.</remarks>\n        public static ManualConfig CreateEmpty() => new ManualConfig();\n\n        /// <summary>\n        /// Creates a minimum viable config with predefined columns provider and console logger.\n        /// </summary>\n        public static ManualConfig CreateMinimumViable()\n            => CreateEmpty()\n                .AddColumnProvider(DefaultColumnProviders.Instance)\n                .AddLogger(ConsoleLogger.Default);\n\n        public static ManualConfig Create(IConfig config)\n        {\n            var manualConfig = new ManualConfig();\n            manualConfig.Add(config);\n            return manualConfig;\n        }\n\n        public static ManualConfig Union(IConfig globalConfig, IConfig localConfig)\n        {\n            var manualConfig = new ManualConfig();\n            switch (localConfig.UnionRule)\n            {\n                case ConfigUnionRule.AlwaysUseLocal:\n                    manualConfig.Add(localConfig);\n                    manualConfig.AddFilter(globalConfig.GetFilters().ToArray()); // the filters should be merged anyway\n                    break;\n                case ConfigUnionRule.AlwaysUseGlobal:\n                    manualConfig.Add(globalConfig);\n                    manualConfig.AddFilter(localConfig.GetFilters().ToArray()); // the filters should be merged anyway\n                    break;\n                case ConfigUnionRule.Union:\n                    manualConfig.Add(globalConfig);\n                    manualConfig.Add(localConfig);\n                    break;\n                default:\n                    throw new ArgumentOutOfRangeException();\n            }\n            return manualConfig;\n        }\n\n        internal ManualConfig RemoveLoggersOfType<T>()\n        {\n            loggers.RemoveAll(logger => logger is T);\n            return this;\n        }\n\n        internal void RemoveAllJobs() => jobs.Clear();\n\n        internal void RemoveAllDiagnosers() => diagnosers.Clear();\n\n        private static TimeSpan GetBuildTimeout(TimeSpan current, TimeSpan other)\n            => current == DefaultConfig.Instance.BuildTimeout\n                ? other\n                : TimeSpan.FromMilliseconds(Math.Max(current.TotalMilliseconds, other.TotalMilliseconds));\n\n        private static WakeLockType GetWakeLock(WakeLockType current, WakeLockType other)\n        {\n            if (current == DefaultConfig.Instance.WakeLock) { return other; }\n            if (other == DefaultConfig.Instance.WakeLock) { return current; }\n            return current.CompareTo(other) > 0 ? current : other;\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Configs/WakeLockType.cs",
    "content": "﻿namespace BenchmarkDotNet.Configs\n{\n    public enum WakeLockType\n    {\n        /// <summary>\n        /// Allows the system to enter sleep and/or turn off the display while benchmarks are running.\n        /// </summary>\n        None,\n\n        /// <summary>\n        /// Forces the system to be in the working state while benchmarks are running.\n        /// </summary>\n        System,\n\n        /// <summary>\n        /// Forces the display to be on while benchmarks are running.\n        /// </summary>\n        Display\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/ConsoleArguments/CommandLineOptions.cs",
    "content": "using System.Collections.Generic;\nusing System.Diagnostics.CodeAnalysis;\nusing System.IO;\nusing System.Linq;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.ConsoleArguments.ListBenchmarks;\nusing BenchmarkDotNet.Diagnosers;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Helpers;\nusing BenchmarkDotNet.Toolchains.MonoAotLLVM;\nusing CommandLine;\nusing CommandLine.Text;\nusing JetBrains.Annotations;\nusing Perfolizer.Mathematics.OutlierDetection;\n\nnamespace BenchmarkDotNet.ConsoleArguments\n{\n    [SuppressMessage(\"ReSharper\", \"MemberCanBePrivate.Global\")]\n    [SuppressMessage(\"ReSharper\", \"UnusedAutoPropertyAccessor.Global\")]\n    public class CommandLineOptions\n    {\n        private const int DefaultDisassemblerRecursiveDepth = 1;\n        private bool useDisassemblyDiagnoser;\n\n        [Option('j', \"job\", Required = false, Default = \"Default\", HelpText = \"Dry/Short/Medium/Long or Default\")]\n        public string BaseJob { get; set; } = \"\";\n\n        [Option('r', \"runtimes\", Required = false, HelpText = \"Full target framework moniker for .NET Core and .NET. For Mono just 'Mono'. For NativeAOT please append target runtime version (example: 'nativeaot7.0'). First one will be marked as baseline!\")]\n        public IEnumerable<string> Runtimes { get; set; } = [];\n\n        [Option('e', \"exporters\", Required = false, HelpText = \"GitHub/StackOverflow/RPlot/CSV/JSON/HTML/XML\")]\n        public IEnumerable<string> Exporters { get; set; } = [];\n\n        [Option('m', \"memory\", Required = false, Default = false, HelpText = \"Prints memory statistics\")]\n        public bool UseMemoryDiagnoser { get; set; }\n\n        [Option('t', \"threading\", Required = false, Default = false, HelpText = \"Prints threading statistics\")]\n        public bool UseThreadingDiagnoser { get; set; }\n\n        [Option(\"exceptions\", Required = false, Default = false, HelpText = \"Prints exception statistics\")]\n        public bool UseExceptionDiagnoser { get; set; }\n\n        [Option('d', \"disasm\", Required = false, Default = false, HelpText = \"Gets disassembly of benchmarked code\")]\n        public bool UseDisassemblyDiagnoser\n        {\n            get => useDisassemblyDiagnoser || DisassemblerRecursiveDepth != DefaultDisassemblerRecursiveDepth || DisassemblerFilters.Any();\n            set => useDisassemblyDiagnoser = value;\n        }\n\n        [Option('p', \"profiler\", Required = false, HelpText = \"Profiles benchmarked code using selected profiler. Available options: EP/ETW/CV/NativeMemory\")]\n        public string? Profiler { get; set; }\n\n        [Option('f', \"filter\", Required = false, HelpText = \"Glob patterns\")]\n        public IEnumerable<string> Filters { get; set; } = [];\n\n        [Option('h', \"hide\", Required = false, HelpText = \"Hides columns by name\")]\n        public IEnumerable<string> HiddenColumns { get; set; } = [];\n\n        [Option('i', \"inProcess\", Required = false, Default = false, HelpText = \"Run benchmarks in Process\")]\n        public bool RunInProcess { get; set; }\n\n        [Option('a', \"artifacts\", Required = false, HelpText = \"Valid path to accessible directory\")]\n        public DirectoryInfo? ArtifactsDirectory { get; set; }\n\n        [Option(\"outliers\", Required = false, Default = OutlierMode.RemoveUpper, HelpText = \"DontRemove/RemoveUpper/RemoveLower/RemoveAll\")]\n        public OutlierMode Outliers { get; set; }\n\n        [Option(\"affinity\", Required = false, HelpText = \"Affinity mask to set for the benchmark process\")]\n        public int? Affinity { get; set; }\n\n        [Option(\"allStats\", Required = false, Default = false, HelpText = \"Displays all statistics (min, max & more)\")]\n        public bool DisplayAllStatistics { get; set; }\n\n        [Option(\"allCategories\", Required = false, HelpText = \"Categories to run. If few are provided, only the benchmarks which belong to all of them are going to be executed\")]\n        public IEnumerable<string> AllCategories { get; set; } = [];\n\n        [Option(\"anyCategories\", Required = false, HelpText = \"Any Categories to run\")]\n        public IEnumerable<string> AnyCategories { get; set; } = [];\n\n        [Option(\"attribute\", Required = false, HelpText = \"Run all methods with given attribute (applied to class or method)\")]\n        public IEnumerable<string> AttributeNames { get; set; } = [];\n\n        [Option(\"join\", Required = false, Default = false, HelpText = \"Prints single table with results for all benchmarks\")]\n        public bool Join { get; set; }\n\n        [Option(\"keepFiles\", Required = false, Default = false, HelpText = \"Determines if all auto-generated files should be kept or removed after running the benchmarks.\")]\n        public bool KeepBenchmarkFiles { get; set; }\n\n        [Option(\"noOverwrite\", Required = false, Default = false, HelpText = \"Determines if the exported result files should not be overwritten (be default they are overwritten).\")]\n        public bool DontOverwriteResults { get; set; }\n\n        [Option(\"counters\", Required = false, HelpText = \"Hardware Counters\", Separator = '+')]\n        public IEnumerable<string> HardwareCounters { get; set; } = [];\n\n        [Option(\"cli\", Required = false, HelpText = \"Path to dotnet cli (optional).\")]\n        public FileInfo? CliPath { get; set; }\n\n        [Option(\"packages\", Required = false, HelpText = \"The directory to restore packages to (optional).\")]\n        public DirectoryInfo? RestorePath { get; set; }\n\n        [Option(\"coreRun\", Required = false, HelpText = \"Path(s) to CoreRun (optional).\")]\n        public IReadOnlyList<FileInfo> CoreRunPaths { get; set; } = [];\n\n        [Option(\"monoPath\", Required = false, HelpText = \"Optional path to Mono which should be used for running benchmarks.\")]\n        public FileInfo? MonoPath { get; set; }\n\n        [Option(\"clrVersion\", Required = false, HelpText = \"Optional version of private CLR build used as the value of COMPLUS_Version env var.\")]\n        public string? ClrVersion { get; set; }\n\n        [Option(\"ilCompilerVersion\", Required = false, HelpText = \"Optional version of Microsoft.DotNet.ILCompiler which should be used to run with NativeAOT. Example: \\\"7.0.0-preview.3.22123.2\\\"\")]\n        public string? ILCompilerVersion { get; set; }\n\n        [Option(\"ilcPackages\", Required = false, HelpText = @\"Optional path to shipping packages produced by local dotnet/runtime build. Example: 'D:\\projects\\runtime\\artifacts\\packages\\Release\\Shipping\\'\")]\n        public DirectoryInfo? IlcPackages { get; set; }\n\n        [Option(\"launchCount\", Required = false, HelpText = \"How many times we should launch process with target benchmark. The default is 1.\")]\n        public int? LaunchCount { get; set; }\n\n        [Option(\"warmupCount\", Required = false, HelpText = \"How many warmup iterations should be performed. If you set it, the minWarmupCount and maxWarmupCount are ignored. By default calculated by the heuristic.\")]\n        public int? WarmupIterationCount { get; set; }\n\n        [Option(\"minWarmupCount\", Required = false, HelpText = \"Minimum count of warmup iterations that should be performed. The default is 6.\")]\n        public int? MinWarmupIterationCount { get; set; }\n\n        [Option(\"maxWarmupCount\", Required = false, HelpText = \"Maximum count of warmup iterations that should be performed. The default is 50.\")]\n        public int? MaxWarmupIterationCount { get; set; }\n\n        [Option(\"iterationTime\", Required = false, HelpText = \"Desired time of execution of an iteration in milliseconds. Used by Pilot stage to estimate the number of invocations per iteration. 500ms by default\")]\n        public int? IterationTimeInMilliseconds { get; set; }\n\n        [Option(\"iterationCount\", Required = false, HelpText = \"How many target iterations should be performed. By default calculated by the heuristic.\")]\n        public int? IterationCount { get; set; }\n\n        [Option(\"minIterationCount\", Required = false, HelpText = \"Minimum number of iterations to run. The default is 15.\")]\n        public int? MinIterationCount { get; set; }\n\n        [Option(\"maxIterationCount\", Required = false, HelpText = \"Maximum number of iterations to run. The default is 100.\")]\n        public int? MaxIterationCount { get; set; }\n\n        [Option(\"invocationCount\", Required = false, HelpText = \"Invocation count in a single iteration. By default calculated by the heuristic.\")]\n        public long? InvocationCount { get; set; }\n\n        [Option(\"unrollFactor\", Required = false, HelpText = \"How many times the benchmark method will be invoked per one iteration of a generated loop. 16 by default\")]\n        public int? UnrollFactor { get; set; }\n\n        [Option(\"strategy\", Required = false, HelpText = \"The RunStrategy that should be used. Throughput/ColdStart/Monitoring.\")]\n        public RunStrategy? RunStrategy { get; set; }\n\n        [Option(\"platform\", Required = false, HelpText = \"The Platform that should be used. If not specified, the host process platform is used (default). AnyCpu/X86/X64/Arm/Arm64/LoongArch64.\")]\n        public Platform? Platform { get; set; }\n\n        [Option(\"runOncePerIteration\", Required = false, Default = false, HelpText = \"Run the benchmark exactly once per iteration.\")]\n        public bool RunOncePerIteration { get; set; }\n\n        [Option(\"info\", Required = false, Default = false, HelpText = \"Print environment information.\")]\n        public bool PrintInformation { get; set; }\n\n        [Option(\"apples\", Required = false, Default = false, HelpText = \"Runs apples-to-apples comparison for specified Jobs.\")]\n        public bool ApplesToApples { get; set; }\n\n        [Option(\"list\", Required = false, Default = ListBenchmarkCaseMode.Disabled, HelpText = \"Prints all of the available benchmark names. Flat/Tree\")]\n        public ListBenchmarkCaseMode ListBenchmarkCaseMode { get; set; }\n\n        [Option(\"disasmDepth\", Required = false, Default = DefaultDisassemblerRecursiveDepth, HelpText = \"Sets the recursive depth for the disassembler.\")]\n        public int DisassemblerRecursiveDepth { get; set; }\n\n        [Option(\"disasmFilter\", Required = false, HelpText = \"Glob patterns applied to full method signatures by the the disassembler.\")]\n        public IEnumerable<string> DisassemblerFilters { get; set; } = [];\n\n        [Option(\"disasmDiff\", Required = false, Default = false, HelpText = \"Generates diff reports for the disassembler.\")]\n        public bool DisassemblerDiff { get; set; }\n\n        [Option(\"logBuildOutput\", Required = false, HelpText = \"Log Build output.\")]\n        public bool LogBuildOutput { get; set; }\n\n        [Option(\"generateBinLog\", Required = false, HelpText = \"Generate msbuild binlog for builds\")]\n        public bool GenerateMSBuildBinLog { get; set; }\n\n        [Option(\"buildTimeout\", Required = false, HelpText = \"Build timeout in seconds.\")]\n        public int? TimeOutInSeconds { get; set; }\n\n        [Option(\"wakeLock\", Required = false, HelpText = \"Prevents the system from entering sleep or turning off the display. None/System/Display.\")]\n        public WakeLockType? WakeLock { get; set; }\n\n        [Option(\"stopOnFirstError\", Required = false, Default = false, HelpText = \"Stop on first error.\")]\n        public bool StopOnFirstError { get; set; }\n\n        [Option(\"statisticalTest\", Required = false, HelpText = \"Threshold for Mann–Whitney U Test. Examples: 5%, 10ms, 100ns, 1s\")]\n        public string? StatisticalTestThreshold { get; set; }\n\n        [Option(\"disableLogFile\", Required = false, HelpText = \"Disables the logfile.\")]\n        public bool DisableLogFile { get; set; }\n\n        [Option(\"maxWidth\", Required = false, HelpText = \"Max parameter column width, the default is 20.\")]\n        public int? MaxParameterColumnWidth { get; set; }\n\n        [Option(\"envVars\", Required = false, HelpText = \"Colon separated environment variables (key:value)\")]\n        public IEnumerable<string> EnvironmentVariables { get; set; } = [];\n\n        [Option(\"memoryRandomization\", Required = false, HelpText = \"Specifies whether Engine should allocate some random-sized memory between iterations. It makes [GlobalCleanup] and [GlobalSetup] methods to be executed after every iteration.\")]\n        public bool MemoryRandomization { get; set; }\n\n        [Option(\"wasmEngine\", Required = false, HelpText = \"Specifies the executable (in PATH) or full path to a java script engine used to run the benchmarks, used by Wasm toolchain.\", Default = \"v8\")]\n        public string? WasmJavaScriptEngine { get; set; } = \"v8\";\n\n        [Option(\"wasmArgs\", Required = false, HelpText = \"Arguments for the javascript engine used by Wasm toolchain.\")]\n        public string? WasmJavaScriptEngineArguments { get; set; }\n\n        [Option(\"wasmMainJsTemplate\", Required = false, HelpText = \"Path to main.mjs template.\")]\n        public FileInfo? WasmMainJsTemplate { get; set; }\n\n        [Option(\"customRuntimePack\", Required = false, HelpText = \"Path to a custom runtime pack. Only used for wasm/MonoAotLLVM currently.\")]\n        public string? CustomRuntimePack { get; set; }\n\n        [Option(\"AOTCompilerPath\", Required = false, HelpText = \"Path to Mono AOT compiler, used for MonoAotLLVM.\")]\n        public FileInfo? AOTCompilerPath { get; set; }\n\n        [Option(\"AOTCompilerMode\", Required = false, Default = MonoAotCompilerMode.mini, HelpText = \"Mono AOT compiler mode, either 'mini', 'llvm', or 'wasm'\")]\n        public MonoAotCompilerMode AOTCompilerMode { get; set; }\n\n        [Option(\"wasmRuntimeFlavor\", Required = false, Default = Environments.RuntimeFlavor.Mono, HelpText = \"Runtime flavor for WASM benchmarks: 'Mono' (default) uses the Mono runtime pack, 'CoreCLR' uses the CoreCLR runtime pack.\")]\n        public Environments.RuntimeFlavor WasmRuntimeFlavor { get; set; }\n\n        [Option(\"wasmProcessTimeout\", Required = false, Default = 10, HelpText = \"Maximum time in minutes to wait for a single WASM benchmark process to finish before force killing it.\")]\n        public int WasmProcessTimeoutMinutes { get; set; }\n\n        [Option(\"noForcedGCs\", Required = false, HelpText = \"Specifying would not forcefully induce any GCs.\")]\n        public bool NoForcedGCs { get; set; }\n\n        [Option(\"noOverheadEvaluation\", Required = false, HelpText = \"Specifying would not run the evaluation overhead iterations.\")]\n        public bool NoEvaluationOverhead { get; set; }\n\n        [Option(\"resume\", Required = false, Default = false, HelpText = \"Continue the execution if the last run was stopped.\")]\n        public bool Resume { get; set; }\n\n        internal bool UserProvidedFilters => Filters.Any() || AttributeNames.Any() || AllCategories.Any() || AnyCategories.Any();\n\n        [Usage(ApplicationAlias = \"\")]\n        [PublicAPI]\n        public static IEnumerable<Example> Examples\n        {\n            get\n            {\n                var shortName = new UnParserSettings { PreferShortName = true };\n                var longName = new UnParserSettings { PreferShortName = false };\n\n                yield return new Example(\"Use Job.ShortRun for running the benchmarks\", shortName, new CommandLineOptions { BaseJob = \"short\" });\n                yield return new Example(\"Run benchmarks in process\", shortName, new CommandLineOptions { RunInProcess = true });\n                yield return new Example(\"Run benchmarks for .NET 4.7.2, .NET 8.0 and Mono. .NET 4.7.2 will be baseline because it was first.\", longName, new CommandLineOptions { Runtimes = [\"net472\", \"net8.0\", \"Mono\"] });\n                yield return new Example(\"Run benchmarks for .NET Core 3.1, .NET 6.0 and .NET 8.0. .NET Core 3.1 will be baseline because it was first.\", longName, new CommandLineOptions { Runtimes = [\"netcoreapp3.1\", \"net6.0\", \"net8.0\"] });\n                yield return new Example(\"Use MemoryDiagnoser to get GC stats\", shortName, new CommandLineOptions { UseMemoryDiagnoser = true });\n                yield return new Example(\"Use DisassemblyDiagnoser to get disassembly\", shortName, new CommandLineOptions { UseDisassemblyDiagnoser = true });\n                yield return new Example(\"Use HardwareCountersDiagnoser to get hardware counter info\", longName, new CommandLineOptions { HardwareCounters = [nameof(HardwareCounter.CacheMisses), nameof(HardwareCounter.InstructionRetired)] });\n                yield return new Example(\"Run all benchmarks exactly once\", shortName, new CommandLineOptions { BaseJob = \"Dry\", Filters = [Escape(\"*\")] });\n                yield return new Example(\"Run all benchmarks from System.Memory namespace\", shortName, new CommandLineOptions { Filters = [Escape(\"System.Memory*\")] });\n                yield return new Example(\"Run all benchmarks from ClassA and ClassB using type names\", shortName, new CommandLineOptions { Filters = [\"ClassA\", \"ClassB\"] });\n                yield return new Example(\"Run all benchmarks from ClassA and ClassB using patterns\", shortName, new CommandLineOptions { Filters = [Escape(\"*.ClassA.*\"), Escape(\"*.ClassB.*\")] });\n                yield return new Example(\"Run all benchmarks called `BenchmarkName` and show the results in single summary\", longName, new CommandLineOptions { Join = true, Filters = [Escape(\"*.BenchmarkName\")] });\n                yield return new Example(\"Run selected benchmarks once per iteration\", longName, new CommandLineOptions { RunOncePerIteration = true });\n                yield return new Example(\"Run selected benchmarks 100 times per iteration. Perform single warmup iteration and 5 actual workload iterations\", longName, new CommandLineOptions { InvocationCount = 100, WarmupIterationCount = 1, IterationCount = 5});\n                yield return new Example(\"Run selected benchmarks 250ms per iteration. Perform from 9 to 15 iterations\", longName, new CommandLineOptions { IterationTimeInMilliseconds = 250, MinIterationCount = 9, MaxIterationCount = 15});\n                yield return new Example(\"Run MannWhitney test with relative ratio of 5% for all benchmarks for .NET 6.0 (base) vs .NET 8.0 (diff). .NET Core 6.0 will be baseline because it was provided as first.\", longName,\n                    new CommandLineOptions { Filters = [\"*\"], Runtimes = [\"net6.0\", \"net8.0\"], StatisticalTestThreshold = \"5%\" });\n                yield return new Example(\"Run benchmarks using environment variables 'ENV_VAR_KEY_1' with value 'value_1' and 'ENV_VAR_KEY_2' with value 'value_2'\", longName,\n                    new CommandLineOptions { EnvironmentVariables = [\"ENV_VAR_KEY_1:value_1\", \"ENV_VAR_KEY_2:value_2\"] });\n                yield return new Example(\"Hide Mean and Ratio columns (use double quotes for multi-word columns: \\\"Alloc Ratio\\\")\", shortName, new CommandLineOptions { HiddenColumns = [\"Mean\", \"Ratio\"], });\n            }\n        }\n\n        private static string Escape(string input) => UserInteractionHelper.EscapeCommandExample(input);\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/ConsoleArguments/ConfigParser.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Diagnostics.CodeAnalysis;\nusing System.IO;\nusing System.Linq;\nusing System.Text;\nusing BenchmarkDotNet.Columns;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Diagnosers;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Exporters;\nusing BenchmarkDotNet.Exporters.Csv;\nusing BenchmarkDotNet.Exporters.Json;\nusing BenchmarkDotNet.Exporters.Xml;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Filters;\nusing BenchmarkDotNet.Helpers;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Portability;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Toolchains.CoreRun;\nusing BenchmarkDotNet.Toolchains.CsProj;\nusing BenchmarkDotNet.Toolchains.DotNetCli;\nusing BenchmarkDotNet.Toolchains.Mono;\nusing BenchmarkDotNet.Toolchains.MonoAotLLVM;\nusing BenchmarkDotNet.Toolchains.MonoWasm;\nusing BenchmarkDotNet.Toolchains.NativeAot;\nusing BenchmarkDotNet.Toolchains.R2R;\nusing CommandLine;\nusing Perfolizer.Horology;\nusing Perfolizer.Mathematics.OutlierDetection;\nusing Perfolizer.Metrology;\n\nnamespace BenchmarkDotNet.ConsoleArguments\n{\n    public static class ConfigParser\n    {\n        private const int MinimumDisplayWidth = 80;\n        private const char EnvVarKeyValueSeparator = ':';\n\n        private static readonly IReadOnlyDictionary<string, Job> AvailableJobs = new Dictionary<string, Job>(StringComparer.InvariantCultureIgnoreCase)\n        {\n            { \"default\", Job.Default },\n            { \"dry\", Job.Dry },\n            { \"short\", Job.ShortRun },\n            { \"medium\", Job.MediumRun },\n            { \"long\", Job.LongRun },\n            { \"verylong\", Job.VeryLongRun }\n        };\n\n        [SuppressMessage(\"ReSharper\", \"StringLiteralTypo\")]\n        [SuppressMessage(\"ReSharper\", \"CoVariantArrayConversion\")]\n        private static readonly IReadOnlyDictionary<string, IExporter[]> AvailableExporters =\n            new Dictionary<string, IExporter[]>(StringComparer.InvariantCultureIgnoreCase)\n            {\n                { \"csv\", new[] { CsvExporter.Default } },\n                { \"csvmeasurements\", new[] { CsvMeasurementsExporter.Default } },\n                { \"html\", new[] { HtmlExporter.Default } },\n                { \"markdown\", new[] { MarkdownExporter.Default } },\n                { \"atlassian\", new[] { MarkdownExporter.Atlassian } },\n                { \"stackoverflow\", new[] { MarkdownExporter.StackOverflow } },\n                { \"github\", new[] { MarkdownExporter.GitHub } },\n                { \"plain\", new[] { PlainExporter.Default } },\n                { \"rplot\", new[] { CsvMeasurementsExporter.Default, RPlotExporter.Default } }, // R Plots depends on having the full measurements available\n                { \"json\", new[] { JsonExporter.Default } },\n                { \"briefjson\", new[] { JsonExporter.Brief } },\n                { \"fulljson\", new[] { JsonExporter.Full } },\n                { \"asciidoc\", new[] { AsciiDocExporter.Default } },\n                { \"xml\", new[] { XmlExporter.Default } },\n                { \"briefxml\", new[] { XmlExporter.Brief } },\n                { \"fullxml\", new[] { XmlExporter.Full } }\n            };\n\n        public static (bool isSuccess, IConfig? config, CommandLineOptions? options) Parse(string[] args, ILogger logger, IConfig? globalConfig = null)\n        {\n            (bool isSuccess, IConfig? config, CommandLineOptions? options) result = default;\n\n            var (expandSuccess, expandedArgs) = ExpandResponseFile(args, logger);\n            if (!expandSuccess)\n            {\n                return (false, default, default);\n            }\n\n            args = expandedArgs;\n            using (var parser = CreateParser(logger))\n            {\n                parser\n                    .ParseArguments<CommandLineOptions>(args)\n                    .WithParsed(options => result = Validate(options, logger) ? (true, CreateConfig(options, globalConfig, args), options) : (false, default, default))\n                    .WithNotParsed(errors => result = (false, default, default));\n            }\n\n            return result;\n        }\n\n        private static (bool Success, string[] ExpandedTokens) ExpandResponseFile(string[] args, ILogger logger)\n        {\n            List<string> result = [];\n            foreach (var arg in args)\n            {\n                if (arg.StartsWith(\"@\"))\n                {\n                    var fileName = arg.Substring(1);\n                    try\n                    {\n                        if (File.Exists(fileName))\n                        {\n                            var lines = File.ReadAllLines(fileName);\n                            foreach (var line in lines)\n                            {\n                                result.AddRange(ConsumeTokens(line));\n                            }\n                        }\n                        else\n                        {\n                            logger.WriteLineError($\"Response file {fileName} does not exists.\");\n                            return (false, Array.Empty<string>());\n                        }\n                    }\n                    catch (Exception ex)\n                    {\n                        logger.WriteLineError($\"Failed to parse RSP file: {fileName}, {ex.Message}\");\n                        return (false, Array.Empty<string>());\n                    }\n                }\n                else\n                {\n                    result.Add(arg);\n                }\n            }\n\n            return (true, result.ToArray());\n        }\n\n        private static IEnumerable<string> ConsumeTokens(string line)\n        {\n            bool insideQuotes = false;\n            var token = new StringBuilder();\n            for (int i = 0; i < line.Length; i++)\n            {\n                char currentChar = line[i];\n                if (currentChar == ' ' && !insideQuotes)\n                {\n                    if (token.Length > 0)\n                    {\n                        yield return GetToken();\n                        token = new StringBuilder();\n                    }\n\n                    continue;\n                }\n\n                if (currentChar == '\"')\n                {\n                    insideQuotes = !insideQuotes;\n                    continue;\n                }\n\n                if (currentChar == '\\\\' && insideQuotes)\n                {\n                    if (line[i + 1] == '\"')\n                    {\n                        insideQuotes = false;\n                        i++;\n                        continue;\n                    }\n\n                    if (line[i + 1] == '\\\\')\n                    {\n                        token.Append('\\\\');\n                        i++;\n                        continue;\n                    }\n                }\n\n                token.Append(currentChar);\n            }\n\n            if (token.Length > 0)\n            {\n                yield return GetToken();\n            }\n\n            string GetToken()\n            {\n                var result = token.ToString();\n                if (result.Contains(' '))\n                {\n                    // Workaround for CommandLine library issue with parsing these kind of args.\n                    return \" \" + result;\n                }\n\n                return result;\n            }\n        }\n\n        internal static bool TryUpdateArgs(string[] args, out string[]? updatedArgs, Action<CommandLineOptions> updater)\n        {\n            (bool isSuccess, CommandLineOptions? options) result = default;\n\n            ILogger logger = NullLogger.Instance;\n            using (var parser = CreateParser(logger))\n            {\n                parser\n                    .ParseArguments<CommandLineOptions>(args)\n                    .WithParsed(options => result = Validate(options, logger) ? (true, options) : (false, default))\n                    .WithNotParsed(errors => result = (false, default));\n\n                if (!result.isSuccess)\n                {\n                    updatedArgs = null;\n                    return false;\n                }\n\n                updater(result.options!);\n\n                updatedArgs = parser.FormatCommandLine(result.options, settings => settings.SkipDefault = true).Split();\n                return true;\n            }\n        }\n\n        private static Parser CreateParser(ILogger logger)\n            => new Parser(settings =>\n            {\n                settings.CaseInsensitiveEnumValues = true;\n                settings.CaseSensitive = false;\n                settings.EnableDashDash = true;\n                settings.IgnoreUnknownArguments = false;\n                settings.HelpWriter = new LoggerWrapper(logger);\n                settings.MaximumDisplayWidth = Math.Max(MinimumDisplayWidth, GetMaximumDisplayWidth());\n            });\n\n        private static bool Validate(CommandLineOptions options, ILogger logger)\n        {\n            if (options.BaseJob.IsBlank() || !AvailableJobs.ContainsKey(options.BaseJob))\n            {\n                logger.WriteLineError($\"The provided base job \\\"{options.BaseJob}\\\" is invalid. Available options are: {string.Join(\", \", AvailableJobs.Keys)}.\");\n                return false;\n            }\n\n            foreach (string runtime in options.Runtimes)\n            {\n                if (!TryParse(runtime, out RuntimeMoniker runtimeMoniker))\n                {\n                    logger.WriteLineError($\"The provided runtime \\\"{runtime}\\\" is invalid. Available options are: {string.Join(\", \", Enum.GetNames(typeof(RuntimeMoniker)).Select(name => name.ToLower()))}.\");\n                    return false;\n                }\n                else if (runtimeMoniker == RuntimeMoniker.MonoAOTLLVM && (options.AOTCompilerPath == null || options.AOTCompilerPath.IsNotNullButDoesNotExist()))\n                {\n                    logger.WriteLineError($\"The provided {nameof(options.AOTCompilerPath)} \\\"{options.AOTCompilerPath}\\\" does NOT exist. It MUST be provided.\");\n                }\n                else if (runtimeMoniker >= RuntimeMoniker.WasmNet80 && runtimeMoniker < RuntimeMoniker.MonoAOTLLVM)\n                {\n                    if (!ProcessHelper.TryResolveExecutableInPath(options.WasmJavaScriptEngine, out _))\n                    {\n                        logger.WriteLineError($\"The provided {nameof(options.WasmJavaScriptEngine)} \\\"{options.WasmJavaScriptEngine}\\\" does NOT exist.\");\n                        return false;\n                    }\n                }\n            }\n\n            foreach (string exporter in options.Exporters)\n                if (!AvailableExporters.ContainsKey(exporter))\n                {\n                    logger.WriteLineError($\"The provided exporter \\\"{exporter}\\\" is invalid. Available options are: {string.Join(\", \", AvailableExporters.Keys)}.\");\n                    return false;\n                }\n\n            if (options.CliPath.IsNotNullButDoesNotExist())\n            {\n                logger.WriteLineError($\"The provided {nameof(options.CliPath)} \\\"{options.CliPath}\\\" does NOT exist.\");\n                return false;\n            }\n\n            foreach (var coreRunPath in options.CoreRunPaths)\n                if (coreRunPath.IsNotNullButDoesNotExist())\n                {\n                    if (Directory.Exists(coreRunPath.FullName))\n                    {\n                        logger.WriteLineError($\"The provided path to CoreRun: \\\"{coreRunPath}\\\" exists but it's a directory, not an executable. You need to include CoreRun.exe (corerun on Unix) in the path.\");\n                    }\n                    else\n                    {\n                        logger.WriteLineError($\"The provided path to CoreRun: \\\"{coreRunPath}\\\" does NOT exist.\");\n                    }\n\n                    return false;\n                }\n\n            if (options.MonoPath.IsNotNullButDoesNotExist())\n            {\n                logger.WriteLineError($\"The provided {nameof(options.MonoPath)} \\\"{options.MonoPath}\\\" does NOT exist.\");\n                return false;\n            }\n\n            if (options.IlcPackages.IsNotNullButDoesNotExist())\n            {\n                logger.WriteLineError($\"The provided {nameof(options.IlcPackages)} \\\"{options.IlcPackages}\\\" does NOT exist.\");\n                return false;\n            }\n\n            if (options.HardwareCounters.Count() > 3)\n            {\n                logger.WriteLineError(\"You can't use more than 3 HardwareCounters at the same time.\");\n                return false;\n            }\n\n            foreach (var counterName in options.HardwareCounters)\n                if (!Enum.TryParse(counterName, ignoreCase: true, out HardwareCounter _))\n                {\n                    logger.WriteLineError($\"The provided hardware counter \\\"{counterName}\\\" is invalid. Available options are: {string.Join(\"+\", Enum.GetNames(typeof(HardwareCounter)))}.\");\n                    return false;\n                }\n\n            if (options.StatisticalTestThreshold.IsNotBlank() && !Threshold.TryParse(options.StatisticalTestThreshold, out _))\n            {\n                logger.WriteLineError(\"Invalid Threshold for Statistical Test. Use --help to see examples.\");\n                return false;\n            }\n\n            if (options.EnvironmentVariables.Any(envVar => envVar.IndexOf(EnvVarKeyValueSeparator) <= 0))\n            {\n                logger.WriteLineError($\"Environment variable value must be separated from the key using '{EnvVarKeyValueSeparator}'. Use --help to see examples.\");\n                return false;\n            }\n\n            return true;\n        }\n\n        private static IConfig CreateConfig(CommandLineOptions options, IConfig? globalConfig, string[] args)\n        {\n            var config = new ManualConfig();\n\n            var baseJob = GetBaseJob(options, globalConfig);\n            var expanded = Expand(baseJob.UnfreezeCopy(), options, args).ToArray(); // UnfreezeCopy ensures that each of the expanded jobs will have it's own ID\n            if (expanded.Length > 1)\n                expanded[0] = expanded[0].AsBaseline(); // if the user provides multiple jobs, then the first one should be a baseline\n            config.AddJob(expanded);\n            if (config.GetJobs().IsEmpty() && baseJob != Job.Default)\n                config.AddJob(baseJob);\n\n            config.AddExporter(options.Exporters.SelectMany(exporter => AvailableExporters[exporter]).ToArray());\n\n            config.AddHardwareCounters(options.HardwareCounters\n                .Select(counterName => (HardwareCounter)Enum.Parse(typeof(HardwareCounter), counterName, ignoreCase: true))\n                .ToArray());\n\n            if (options.UseMemoryDiagnoser)\n                config.AddDiagnoser(MemoryDiagnoser.Default);\n            if (options.UseThreadingDiagnoser)\n                config.AddDiagnoser(ThreadingDiagnoser.Default);\n            if (options.UseExceptionDiagnoser)\n                config.AddDiagnoser(ExceptionDiagnoser.Default);\n            if (options.UseDisassemblyDiagnoser)\n                config.AddDiagnoser(new DisassemblyDiagnoser(new DisassemblyDiagnoserConfig(\n                    maxDepth: options.DisassemblerRecursiveDepth,\n                    filters: options.DisassemblerFilters.ToArray(),\n                    exportDiff: options.DisassemblerDiff)));\n            if (options.Profiler.IsNotBlank())\n                config.AddDiagnoser(DiagnosersLoader.GetImplementation<IProfiler>(profiler => profiler.ShortName.EqualsWithIgnoreCase(options.Profiler)));\n\n            if (options.DisplayAllStatistics)\n                config.AddColumn(StatisticColumn.AllStatistics);\n            if (options.StatisticalTestThreshold.IsNotBlank() && Threshold.TryParse(options.StatisticalTestThreshold, out var threshold))\n                config.AddColumn(new StatisticalTestColumn(threshold));\n\n            if (options.ArtifactsDirectory != null)\n                config.ArtifactsPath = options.ArtifactsDirectory.FullName;\n\n            var filters = GetFilters(options).ToArray();\n            if (filters.Length > 1)\n                config.AddFilter(new UnionFilter(filters));\n            else\n                config.AddFilter(filters);\n\n            config.HideColumns(options.HiddenColumns.ToArray());\n\n            config.WithOption(ConfigOptions.JoinSummary, options.Join);\n            config.WithOption(ConfigOptions.KeepBenchmarkFiles, options.KeepBenchmarkFiles);\n            config.WithOption(ConfigOptions.DontOverwriteResults, options.DontOverwriteResults);\n            config.WithOption(ConfigOptions.StopOnFirstError, options.StopOnFirstError);\n            config.WithOption(ConfigOptions.DisableLogFile, options.DisableLogFile);\n            config.WithOption(ConfigOptions.LogBuildOutput, options.LogBuildOutput);\n            config.WithOption(ConfigOptions.GenerateMSBuildBinLog, options.GenerateMSBuildBinLog);\n            config.WithOption(ConfigOptions.ApplesToApples, options.ApplesToApples);\n            config.WithOption(ConfigOptions.Resume, options.Resume);\n\n            if (config.Options.IsSet(ConfigOptions.GenerateMSBuildBinLog))\n                config.Options |= ConfigOptions.KeepBenchmarkFiles;\n\n            if (options.MaxParameterColumnWidth.HasValue)\n                config.WithSummaryStyle(SummaryStyle.Default.WithMaxParameterColumnWidth(options.MaxParameterColumnWidth.Value));\n\n            if (options.TimeOutInSeconds.HasValue)\n                config.WithBuildTimeout(TimeSpan.FromSeconds(options.TimeOutInSeconds.Value));\n\n            if (options.WakeLock.HasValue)\n                config.WithWakeLock(options.WakeLock.Value);\n\n            return config;\n        }\n\n        private static Job GetBaseJob(CommandLineOptions options, IConfig? globalConfig)\n        {\n            var baseJob =\n                globalConfig?.GetJobs().SingleOrDefault(job => job.Meta.IsDefault) // global config might define single custom Default job\n                ?? AvailableJobs[options.BaseJob.ToLowerInvariant()];\n\n            if (baseJob != Job.Dry && options.Outliers != OutlierMode.RemoveUpper)\n                baseJob = baseJob.WithOutlierMode(options.Outliers);\n\n            if (options.Affinity.HasValue)\n                baseJob = baseJob.WithAffinity((IntPtr)options.Affinity.Value);\n\n            if (options.LaunchCount.HasValue)\n                baseJob = baseJob.WithLaunchCount(options.LaunchCount.Value);\n            if (options.WarmupIterationCount.HasValue)\n                baseJob = baseJob.WithWarmupCount(options.WarmupIterationCount.Value);\n            if (options.MinWarmupIterationCount.HasValue)\n                baseJob = baseJob.WithMinWarmupCount(options.MinWarmupIterationCount.Value);\n            if (options.MaxWarmupIterationCount.HasValue)\n                baseJob = baseJob.WithMaxWarmupCount(options.MaxWarmupIterationCount.Value);\n            if (options.IterationTimeInMilliseconds.HasValue)\n                baseJob = baseJob.WithIterationTime(TimeInterval.FromMilliseconds(options.IterationTimeInMilliseconds.Value));\n            if (options.IterationCount.HasValue)\n                baseJob = baseJob.WithIterationCount(options.IterationCount.Value);\n            if (options.MinIterationCount.HasValue)\n                baseJob = baseJob.WithMinIterationCount(options.MinIterationCount.Value);\n            if (options.MaxIterationCount.HasValue)\n                baseJob = baseJob.WithMaxIterationCount(options.MaxIterationCount.Value);\n            if (options.InvocationCount.HasValue)\n                baseJob = baseJob.WithInvocationCount(options.InvocationCount.Value);\n            if (options.UnrollFactor.HasValue)\n                baseJob = baseJob.WithUnrollFactor(options.UnrollFactor.Value);\n            if (options.RunStrategy.HasValue)\n                baseJob = baseJob.WithStrategy(options.RunStrategy.Value);\n            if (options.Platform.HasValue)\n                baseJob = baseJob.WithPlatform(options.Platform.Value);\n            if (options.RunOncePerIteration)\n                baseJob = baseJob.RunOncePerIteration();\n            if (options.MemoryRandomization)\n                baseJob = baseJob.WithMemoryRandomization();\n            if (options.NoForcedGCs)\n                baseJob = baseJob.WithGcForce(false);\n            if (options.NoEvaluationOverhead)\n#pragma warning disable CS0618 // Type or member is obsolete\n                baseJob = baseJob.WithEvaluateOverhead(false);\n#pragma warning restore CS0618 // Type or member is obsolete\n\n            if (options.EnvironmentVariables.Any())\n            {\n                baseJob = baseJob.WithEnvironmentVariables(options.EnvironmentVariables.Select(text =>\n                {\n                    var separated = text.Split([EnvVarKeyValueSeparator], 2);\n                    return new EnvironmentVariable(separated[0], separated[1]);\n                }).ToArray());\n            }\n\n            if (AvailableJobs.Values.Contains(baseJob)) // no custom settings\n                return baseJob;\n\n            return baseJob\n                .AsDefault(false) // after applying all settings from console args the base job is not default anymore\n                .AsMutator(); // we mark it as mutator so it will be applied to other jobs defined via attributes and merged later in GetRunnableJobs method\n        }\n\n        private static IEnumerable<Job> Expand(Job baseJob, CommandLineOptions options, string[] args)\n        {\n            if (options.RunInProcess)\n            {\n                yield return Attributes.InProcessAttribute.GetJob(baseJob, Attributes.InProcessToolchainType.Auto, true);\n            }\n            else if (options.ClrVersion.IsNotBlank())\n            {\n                var runtime = ClrRuntime.CreateForLocalFullNetFrameworkBuild(options.ClrVersion);\n                yield return baseJob.WithRuntime(runtime).WithId(runtime.Name); // local builds of .NET Runtime\n            }\n            else if (options.CliPath != null && options.Runtimes.IsEmpty() && options.CoreRunPaths.IsEmpty())\n            {\n                yield return CreateCoreJobWithCli(baseJob, options);\n            }\n            else\n            {\n                // in case both --runtimes and --corerun are specified, the first one is returned first and becomes a baseline job\n                string? first = args.FirstOrDefault(arg =>\n                    arg.Equals(\"--runtimes\", StringComparison.OrdinalIgnoreCase)\n                    || arg.Equals(\"-r\", StringComparison.OrdinalIgnoreCase)\n\n                    || arg.Equals(\"--corerun\", StringComparison.OrdinalIgnoreCase));\n\n                if (first is null || first.Equals(\"--corerun\", StringComparison.OrdinalIgnoreCase))\n                {\n                    foreach (var coreRunPath in options.CoreRunPaths)\n                        yield return CreateCoreRunJob(baseJob, options, coreRunPath); // local dotnet/runtime builds\n\n                    foreach (string runtime in options.Runtimes) // known runtimes\n                        yield return CreateJobForGivenRuntime(baseJob, runtime, options);\n                }\n                else\n                {\n                    foreach (string runtime in options.Runtimes) // known runtimes\n                        yield return CreateJobForGivenRuntime(baseJob, runtime, options);\n\n                    foreach (var coreRunPath in options.CoreRunPaths)\n                        yield return CreateCoreRunJob(baseJob, options, coreRunPath); // local dotnet/runtime builds\n                }\n            }\n        }\n\n        private static Job CreateJobForGivenRuntime(Job baseJob, string runtimeId, CommandLineOptions options)\n        {\n            if (!TryParse(runtimeId, out RuntimeMoniker runtimeMoniker))\n            {\n                throw new InvalidOperationException(\"Impossible, already validated by the Validate method\");\n            }\n\n            switch (runtimeMoniker)\n            {\n                case RuntimeMoniker.Net461:\n                case RuntimeMoniker.Net462:\n                case RuntimeMoniker.Net47:\n                case RuntimeMoniker.Net471:\n                case RuntimeMoniker.Net472:\n                case RuntimeMoniker.Net48:\n                case RuntimeMoniker.Net481:\n                    {\n                        var runtime = runtimeMoniker.GetRuntime();\n                        return baseJob\n                            .WithRuntime(runtime)\n                            .WithId(runtime.Name)\n                            .WithToolchain(CsProjClassicNetToolchain.From(runtimeId, options.RestorePath?.FullName ?? \"\", options.CliPath?.FullName ?? \"\"));\n                    }\n\n                case RuntimeMoniker.NetCoreApp20:\n                case RuntimeMoniker.NetCoreApp21:\n                case RuntimeMoniker.NetCoreApp22:\n                case RuntimeMoniker.NetCoreApp30:\n                case RuntimeMoniker.NetCoreApp31:\n                case RuntimeMoniker.Net50:\n                case RuntimeMoniker.Net60:\n                case RuntimeMoniker.Net70:\n                case RuntimeMoniker.Net80:\n                case RuntimeMoniker.Net90:\n                case RuntimeMoniker.Net10_0:\n                case RuntimeMoniker.Net11_0:\n                    {\n                        var runtime = runtimeMoniker.GetRuntime();\n                        return baseJob\n                            .WithRuntime(runtime)\n                            .WithId(runtime.Name)\n                            .WithToolchain(CsProjCoreToolchain.From(\n                                new NetCoreAppSettings(\n                                    runtimeId,\n                                    runtimeFrameworkVersion: \"\",\n                                    name: runtimeId,\n                                    options: options)));\n                    }\n\n                case RuntimeMoniker.Mono:\n                    {\n                        var runtime = new MonoRuntime(\"Mono\", options.MonoPath?.FullName ?? \"\");\n                        return baseJob.WithRuntime(runtime).WithId(runtime.Name);\n                    }\n\n                case RuntimeMoniker.NativeAot60:\n                    return CreateAotJob(baseJob, options, runtimeMoniker, \"6.0.0-*\", \"https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-experimental/nuget/v3/index.json\");\n\n                case RuntimeMoniker.NativeAot70:\n                    return CreateAotJob(baseJob, options, runtimeMoniker, \"\", \"https://api.nuget.org/v3/index.json\");\n\n                case RuntimeMoniker.NativeAot80:\n                    return CreateAotJob(baseJob, options, runtimeMoniker, \"\", \"https://api.nuget.org/v3/index.json\");\n\n                case RuntimeMoniker.NativeAot90:\n                    return CreateAotJob(baseJob, options, runtimeMoniker, \"\", \"https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet9/nuget/v3/index.json\");\n\n                case RuntimeMoniker.NativeAot10_0:\n                    return CreateAotJob(baseJob, options, runtimeMoniker, \"\", \"https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet10/nuget/v3/index.json\");\n\n                case RuntimeMoniker.NativeAot11_0:\n                    return CreateAotJob(baseJob, options, runtimeMoniker, \"\", \"https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet11/nuget/v3/index.json\");\n\n                case RuntimeMoniker.WasmNet80:\n                    return MakeWasmJob(baseJob, options, \"net8.0\", runtimeMoniker);\n\n                case RuntimeMoniker.WasmNet90:\n                    return MakeWasmJob(baseJob, options, \"net9.0\", runtimeMoniker);\n\n                case RuntimeMoniker.WasmNet10_0:\n                    return MakeWasmJob(baseJob, options, \"net10.0\", runtimeMoniker);\n\n                case RuntimeMoniker.WasmNet11_0:\n                    return MakeWasmJob(baseJob, options, \"net11.0\", runtimeMoniker);\n\n                case RuntimeMoniker.MonoAOTLLVM:\n                    return MakeMonoAOTLLVMJob(baseJob, options, RuntimeInformation.IsNetCore ? CoreRuntime.GetCurrentVersion().MsBuildMoniker : \"net6.0\", runtimeMoniker);\n\n                case RuntimeMoniker.MonoAOTLLVMNet60:\n                    return MakeMonoAOTLLVMJob(baseJob, options, \"net6.0\", runtimeMoniker);\n\n                case RuntimeMoniker.MonoAOTLLVMNet70:\n                    return MakeMonoAOTLLVMJob(baseJob, options, \"net7.0\", runtimeMoniker);\n\n                case RuntimeMoniker.MonoAOTLLVMNet80:\n                    return MakeMonoAOTLLVMJob(baseJob, options, \"net8.0\", runtimeMoniker);\n\n                case RuntimeMoniker.MonoAOTLLVMNet90:\n                    return MakeMonoAOTLLVMJob(baseJob, options, \"net9.0\", runtimeMoniker);\n\n                case RuntimeMoniker.MonoAOTLLVMNet10_0:\n                    return MakeMonoAOTLLVMJob(baseJob, options, \"net10.0\", runtimeMoniker);\n\n                case RuntimeMoniker.MonoAOTLLVMNet11_0:\n                    return MakeMonoAOTLLVMJob(baseJob, options, \"net11.0\", runtimeMoniker);\n\n                case RuntimeMoniker.Mono60:\n                    return MakeMonoJob(baseJob, options, MonoRuntime.Mono60);\n\n                case RuntimeMoniker.Mono70:\n                    return MakeMonoJob(baseJob, options, MonoRuntime.Mono70);\n\n                case RuntimeMoniker.Mono80:\n                    return MakeMonoJob(baseJob, options, MonoRuntime.Mono80);\n\n                case RuntimeMoniker.R2R80:\n                case RuntimeMoniker.R2R90:\n                case RuntimeMoniker.R2R10_0:\n                case RuntimeMoniker.R2R11_0:\n                    return CreateR2RJob(baseJob, options, runtimeMoniker.GetRuntime());\n\n                default:\n                    throw new NotSupportedException($\"Runtime {runtimeId} is not supported\");\n            }\n        }\n\n        private static Job CreateAotJob(Job baseJob, CommandLineOptions options, RuntimeMoniker runtimeMoniker, string ilCompilerVersion, string nuGetFeedUrl)\n        {\n            var builder = NativeAotToolchain.CreateBuilder();\n\n            if (options.CliPath != null)\n                builder.DotNetCli(options.CliPath.FullName);\n            if (options.RestorePath != null)\n                builder.PackagesRestorePath(options.RestorePath.FullName);\n\n            if (options.IlcPackages != null)\n                builder.UseLocalBuild(options.IlcPackages);\n            else if (options.ILCompilerVersion.IsNotBlank())\n                builder.UseNuGet(options.ILCompilerVersion, nuGetFeedUrl);\n            else\n                builder.UseNuGet(ilCompilerVersion, nuGetFeedUrl);\n\n            var runtime = runtimeMoniker.GetRuntime();\n            builder.TargetFrameworkMoniker(runtime.MsBuildMoniker);\n\n            return baseJob.WithRuntime(runtime).WithToolchain(builder.ToToolchain()).WithId(runtime.Name);\n        }\n\n        private static Job MakeMonoJob(Job baseJob, CommandLineOptions options, MonoRuntime runtime)\n        {\n            return baseJob\n                .WithRuntime(runtime)\n                .WithToolchain(MonoToolchain.From(\n                    new NetCoreAppSettings(\n                        targetFrameworkMoniker: runtime.MsBuildMoniker,\n                        runtimeFrameworkVersion: \"\",\n                        name: runtime.Name,\n                        options: options)));\n        }\n\n        private static Job MakeMonoAOTLLVMJob(Job baseJob, CommandLineOptions options, string msBuildMoniker, RuntimeMoniker moniker)\n        {\n            var monoAotLLVMRuntime = new MonoAotLLVMRuntime(\n                aotCompilerPath: options.AOTCompilerPath,\n                aotCompilerMode: options.AOTCompilerMode,\n                msBuildMoniker: msBuildMoniker,\n                moniker: moniker);\n\n            var toolChain = MonoAotLLVMToolChain.From(\n            new NetCoreAppSettings(\n                targetFrameworkMoniker: monoAotLLVMRuntime.MsBuildMoniker,\n                runtimeFrameworkVersion: \"\",\n                name: monoAotLLVMRuntime.Name,\n                options: options));\n\n            return baseJob.WithRuntime(monoAotLLVMRuntime).WithToolchain(toolChain).WithId(monoAotLLVMRuntime.Name);\n        }\n\n        private static Job CreateR2RJob(Job baseJob, CommandLineOptions options, Runtime runtime)\n        {\n            var toolChain = R2RToolchain.From(\n            new NetCoreAppSettings(\n                targetFrameworkMoniker: runtime.MsBuildMoniker,\n                runtimeFrameworkVersion: \"\",\n                name: runtime.Name,\n                options: options));\n\n            return baseJob.WithRuntime(runtime).WithToolchain(toolChain).WithId(runtime.Name);\n        }\n\n        private static Job MakeWasmJob(Job baseJob, CommandLineOptions options, string msBuildMoniker, RuntimeMoniker moniker)\n        {\n            bool wasmAot = options.AOTCompilerMode == MonoAotCompilerMode.wasm;\n\n            var wasmRuntime = new WasmRuntime(\n                msBuildMoniker: msBuildMoniker,\n                moniker: moniker,\n                displayName: \"Wasm\",\n                javaScriptEngine: options.WasmJavaScriptEngine ?? \"\",\n                javaScriptEngineArguments: options.WasmJavaScriptEngineArguments,\n                aot: wasmAot,\n                runtimeFlavor: options.WasmRuntimeFlavor,\n                mainJsTemplate: options.WasmMainJsTemplate,\n                processTimeoutMinutes: options.WasmProcessTimeoutMinutes);\n\n            var toolChain = WasmToolchain.From(new NetCoreAppSettings(\n                targetFrameworkMoniker: wasmRuntime.MsBuildMoniker,\n                runtimeFrameworkVersion: \"\",\n                name: wasmRuntime.Name,\n                options: options));\n\n            return baseJob.WithRuntime(wasmRuntime).WithToolchain(toolChain).WithId(wasmRuntime.Name);\n        }\n\n        private static IEnumerable<IFilter> GetFilters(CommandLineOptions options)\n        {\n            if (options.Filters.Any())\n                yield return new GlobFilter(options.Filters.ToArray());\n            if (options.AllCategories.Any())\n                yield return new AllCategoriesFilter(options.AllCategories.ToArray());\n            if (options.AnyCategories.Any())\n                yield return new AnyCategoriesFilter(options.AnyCategories.ToArray());\n            if (options.AttributeNames.Any())\n                yield return new AttributesFilter(options.AttributeNames.ToArray());\n        }\n\n        private static int GetMaximumDisplayWidth()\n        {\n            try\n            {\n                return Console.WindowWidth;\n            }\n            catch (IOException)\n            {\n                return MinimumDisplayWidth;\n            }\n        }\n\n        private static Job CreateCoreRunJob(Job baseJob, CommandLineOptions options, FileInfo coreRunPath)\n            => baseJob\n                .WithToolchain(new CoreRunToolchain(\n                    coreRunPath,\n                    createCopy: true,\n                    targetFrameworkMoniker:\n                        RuntimeInformation.IsNetCore\n                            ? RuntimeInformation.GetCurrentRuntime().MsBuildMoniker\n                            : CoreRuntime.Latest.MsBuildMoniker, // use most recent tfm, as the toolchain is being used only by dotnet/runtime contributors\n                    customDotNetCliPath: options.CliPath,\n                    restorePath: options.RestorePath,\n                    displayName: GetCoreRunToolchainDisplayName(options.CoreRunPaths, coreRunPath)));\n\n        private static Job CreateCoreJobWithCli(Job baseJob, CommandLineOptions options)\n            => baseJob\n                .WithToolchain(CsProjCoreToolchain.From(\n                    new NetCoreAppSettings(\n                        targetFrameworkMoniker: RuntimeInformation.GetCurrentRuntime().MsBuildMoniker,\n                        runtimeFrameworkVersion: \"\",\n                        name: RuntimeInformation.GetCurrentRuntime().Name,\n                        options: options)));\n\n        /// <summary>\n        /// we have a limited amount of space when printing the output to the console, so we try to keep things small and simple\n        ///\n        /// for following paths:\n        ///  C:\\Projects\\coreclr_upstream\\bin\\tests\\Windows_NT.x64.Release\\Tests\\Core_Root\\CoreRun.exe\n        ///  C:\\Projects\\coreclr_upstream\\bin\\tests\\Windows_NT.x64.Release\\Tests\\Core_Root_beforeMyChanges\\CoreRun.exe\n        ///\n        /// we get:\n        ///\n        /// \\Core_Root\\CoreRun.exe\n        /// \\Core_Root_beforeMyChanges\\CoreRun.exe\n        /// </summary>\n        private static string GetCoreRunToolchainDisplayName(IReadOnlyList<FileInfo> paths, FileInfo coreRunPath)\n        {\n            if (paths.Count <= 1)\n                return \"CoreRun\";\n\n            int commonLongestPrefixIndex = paths[0].FullName.Length;\n            for (int i = 1; i < paths.Count; i++)\n            {\n                commonLongestPrefixIndex = Math.Min(commonLongestPrefixIndex, paths[i].FullName.Length);\n                for (int j = 0; j < commonLongestPrefixIndex; j++)\n                    if (paths[i].FullName[j] != paths[0].FullName[j])\n                    {\n                        commonLongestPrefixIndex = j;\n                        break;\n                    }\n            }\n\n            if (commonLongestPrefixIndex <= 1)\n                return coreRunPath.FullName;\n\n            var lastCommonDirectorySeparatorIndex = coreRunPath.FullName.LastIndexOf(Path.DirectorySeparatorChar, commonLongestPrefixIndex - 1);\n\n            return coreRunPath.FullName.Substring(lastCommonDirectorySeparatorIndex);\n        }\n\n        internal static bool TryParse(string runtime, out RuntimeMoniker runtimeMoniker)\n        {\n            int index = runtime.IndexOf('-');\n            if (index >= 0)\n            {\n                runtime = runtime.Substring(0, index);\n            }\n\n            // Monikers older than Net 10 don't use any version delimiter, newer monikers use _ delimiter.\n            if (Enum.TryParse(runtime.Replace(\".\", string.Empty), ignoreCase: true, out runtimeMoniker))\n            {\n                return true;\n            }\n            return Enum.TryParse(runtime.Replace('.', '_'), ignoreCase: true, out runtimeMoniker);\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/ConsoleArguments/CorrectionsSuggester.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Exporters;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Running;\n\nnamespace BenchmarkDotNet.ConsoleArguments\n{\n    public class CorrectionsSuggester\n    {\n        // note This is a heuristic value, we suppose that user can make three or fewer typos.\n        private static int PossibleTyposCount => 3;\n        private readonly HashSet<string> possibleBenchmarkNameFilters = [];\n        private readonly HashSet<string> actualFullBenchmarkNames = [];\n\n        public CorrectionsSuggester(IReadOnlyList<Type> types)\n        {\n            foreach (var benchmarkRunInfo in TypeFilter.Filter(DefaultConfig.Instance, types))\n            {\n                foreach (var benchmarkCase in benchmarkRunInfo.BenchmarksCases)\n                {\n                    string fullBenchmarkName = FullNameProvider.GetBenchmarkName(benchmarkCase);\n\n                    actualFullBenchmarkNames.Add(fullBenchmarkName);\n\n                    var names = GetAllPartialNames(fullBenchmarkName.Split('.'));\n                    possibleBenchmarkNameFilters.AddRange(names);\n                }\n            }\n        }\n\n        public string[] SuggestFor(string userInput)\n        {\n            ArgumentNullException.ThrowIfNull(userInput);\n\n            var calculator = new LevenshteinDistanceCalculator();\n            return possibleBenchmarkNameFilters\n                .Select(name => (name: name, distance: calculator.Calculate(userInput, name)))\n                .Where(tuple => tuple.distance <= PossibleTyposCount)\n                .OrderBy(tuple => tuple.distance)\n                .ThenBy(tuple => tuple.name)\n                .Select(tuple => tuple.name)\n                .ToArray();\n        }\n\n        public string[] GetAllBenchmarkNames() => actualFullBenchmarkNames.ToArray();\n\n        // A.B.C should get translated into\n        // A*\n        // A.B*\n        // *B*\n        // *C\n        private static IEnumerable<string> GetAllPartialNames(string[] nameParts)\n        {\n            for (int partLength = 1; partLength <= nameParts.Length; partLength++)\n            {\n                for (int i = 0; i < nameParts.Length - partLength + 1; i++)\n                {\n                    string permutation = string.Join(\".\", nameParts.Skip(i).Take(partLength));\n\n                    if (i == 0 && partLength == nameParts.Length)\n                    {\n                        yield return permutation; // we don't want to offer *fullname*\n                    }\n                    else if (i == 0)\n                    {\n                        yield return $\"{permutation}*\";\n                    }\n                    else\n                    {\n                        yield return $\"*{permutation}*\";\n                    }\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/ConsoleArguments/LevenshteinDistanceCalculator.cs",
    "content": "﻿using System;\n\nnamespace BenchmarkDotNet.ConsoleArguments\n{\n    internal class LevenshteinDistanceCalculator\n    {\n        public int Calculate(string string1, string string2)\n        {\n            var m = new int[string1.Length + 1, string2.Length + 1];\n\n            for (int i = 0; i <= string1.Length; i++)\n            {\n                m[i, 0] = i;\n            }\n\n            for (int j = 0; j <= string2.Length; j++)\n            {\n                m[0, j] = j;\n            }\n\n            for (int i = 1; i <= string1.Length; i++)\n            {\n                for (int j = 1; j <= string2.Length; j++)\n                {\n                    int diff = (string1[i - 1] == string2[j - 1]) ? 0 : 1;\n\n                    m[i, j] = Math.Min(Math.Min(m[i - 1, j] + 1,\n                            m[i, j - 1] + 1),\n                        m[i - 1, j - 1] + diff);\n                }\n            }\n\n            return m[string1.Length, string2.Length];\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/ConsoleArguments/ListBenchmarks/BenchmarkCasesPrinter.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Running;\n\nnamespace BenchmarkDotNet.ConsoleArguments.ListBenchmarks\n{\n    internal class BenchmarkCasesPrinter : IBenchmarkCasesPrinter\n    {\n        private readonly IBenchmarkCasesPrinter printer;\n\n        public BenchmarkCasesPrinter(ListBenchmarkCaseMode listBenchmarkCaseMode)\n        {\n            printer = listBenchmarkCaseMode == ListBenchmarkCaseMode.Tree\n                ? (IBenchmarkCasesPrinter) new TreeBenchmarkCasesPrinter()\n                : new FlatBenchmarkCasesPrinter();\n        }\n\n        public static void PrintList(ILogger nonNullLogger, IConfig effectiveConfig, IReadOnlyList<Type> allAvailableTypesWithRunnableBenchmarks, CommandLineOptions options)\n        {\n            var printer = new BenchmarkCasesPrinter(options.ListBenchmarkCaseMode);\n\n            var testNames = TypeFilter.Filter(effectiveConfig, allAvailableTypesWithRunnableBenchmarks)\n                .SelectMany(p => p.BenchmarksCases)\n                .Select(p => p.Descriptor.GetFilterName())\n                .Distinct();\n\n            printer.Print(testNames, nonNullLogger);\n        }\n\n        public void Print(IEnumerable<string> testNames, ILogger logger) => printer.Print(testNames, logger);\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/ConsoleArguments/ListBenchmarks/FlatBenchmarkCasesPrinter.cs",
    "content": "﻿using System.Collections.Generic;\nusing BenchmarkDotNet.Loggers;\n\nnamespace BenchmarkDotNet.ConsoleArguments.ListBenchmarks\n{\n    internal class FlatBenchmarkCasesPrinter : IBenchmarkCasesPrinter\n    {\n        public void Print(IEnumerable<string> testNames, ILogger logger)\n        {\n            foreach (string test in testNames)\n            {\n                logger.WriteLine(test);\n            }\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/ConsoleArguments/ListBenchmarks/IBenchmarkCasesPrinter.cs",
    "content": "﻿using System.Collections.Generic;\nusing BenchmarkDotNet.Loggers;\n\nnamespace BenchmarkDotNet.ConsoleArguments.ListBenchmarks\n{\n    internal interface IBenchmarkCasesPrinter\n    {\n        void Print(IEnumerable<string> testNames, ILogger logger);\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/ConsoleArguments/ListBenchmarks/ListBechnmarkCaseMode.cs",
    "content": "﻿namespace BenchmarkDotNet.ConsoleArguments.ListBenchmarks\n{\n    public enum ListBenchmarkCaseMode\n    {\n        /// <summary>\n        /// Do not print any of the available full benchmark names.\n        /// </summary>\n        Disabled,\n\n        /// <summary>\n        /// Prints flat list of the available benchmark names.\n        /// </summary>\n        Flat,\n\n        /// <summary>\n        /// Prints tree of the available full benchmark names.\n        /// </summary>\n        Tree\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/ConsoleArguments/ListBenchmarks/Node.cs",
    "content": "﻿using System.Collections.Generic;\n\nnamespace BenchmarkDotNet.ConsoleArguments.ListBenchmarks\n{\n    internal class Node\n    {\n        public required string Name { get; init; }\n\n        public List<Node> Children { get; } = [];\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/ConsoleArguments/ListBenchmarks/TreeBenchmarkCasesPrinter.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Linq;\nusing BenchmarkDotNet.Loggers;\n\nnamespace BenchmarkDotNet.ConsoleArguments.ListBenchmarks\n{\n    internal class TreeBenchmarkCasesPrinter : IBenchmarkCasesPrinter\n    {\n        // Constants for drawing lines and spaces\n        private const string Cross = \" ├─\";\n        private const string Corner = \" └─\";\n        private const string Vertical = \" │ \";\n        private const string Space = \"   \";\n\n        public void Print(IEnumerable<string> testNames, ILogger logger)\n        {\n            List<Node> topLevelNodes = [];\n\n            foreach (string test in testNames)\n            {\n                var partsOfName = test.Split('.');\n                PrepareNodeTree(topLevelNodes, partsOfName);\n            }\n\n            foreach (var node in topLevelNodes)\n            {\n                PrintNode(node, indent: \"\", logger);\n            }\n        }\n\n        private static void PrepareNodeTree(List<Node> nodes, string[] partsOfName, int index = 0)\n        {\n            var node = nodes.FirstOrDefault(p => p.Name == partsOfName[index]);\n            if (node == null)\n            {\n                node = new Node { Name = partsOfName[index] };\n                nodes.Add(node);\n            }\n\n            if (partsOfName.Length > index + 1)\n            {\n                PrepareNodeTree(node.Children, partsOfName, index + 1);\n            }\n        }\n\n        private void PrintNode(Node node, string indent, ILogger logger)\n        {\n            logger.WriteLine(node.Name);\n\n            // Loop through the children recursively, passing in the\n            // indent, and the isLast parameter\n            var numberOfChildren = node.Children.Count;\n            for (var i = 0; i < numberOfChildren; i++)\n            {\n                var child = node.Children[i];\n                var isLast = (i == (numberOfChildren - 1));\n\n                PrintChildNode(child, indent, isLast, logger);\n            }\n        }\n\n        private void PrintChildNode(Node node, string indent, bool isLast, ILogger logger)\n        {\n            logger.Write(indent);\n\n            // Depending if this node is a last child, print the\n            // corner or cross, and calculate the indent that will\n            // be passed to its children\n            if (isLast)\n            {\n                logger.Write(Corner);\n                indent += Space;\n            }\n            else\n            {\n                logger.Write(Cross);\n                indent += Vertical;\n            }\n\n            PrintNode(node, indent, logger);\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/ConsoleArguments/LoggerWrapper.cs",
    "content": "﻿using System.IO;\nusing System.Text;\nusing BenchmarkDotNet.Loggers;\n\nnamespace BenchmarkDotNet.ConsoleArguments\n{\n    internal class LoggerWrapper : TextWriter\n    {\n        private readonly ILogger logger;\n\n        public LoggerWrapper(ILogger logger) => this.logger = logger;\n\n        public override Encoding Encoding { get; } = Encoding.ASCII;\n\n        public override void Write(string? value)\n        {\n            if (value is null)\n                return;\n\n            logger.WriteInfo(value);\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/ConsoleArguments/RuntimeFlavor.cs",
    "content": "namespace BenchmarkDotNet.Environments;\n\n/// <summary>\n/// Specifies the .NET runtime flavor to use for WASM benchmarks.\n/// </summary>\npublic enum RuntimeFlavor\n{\n    /// <summary>Uses the Mono runtime pack (Microsoft.NETCore.App.Runtime.Mono.browser-wasm).</summary>\n    Mono,\n\n    /// <summary>Uses the CoreCLR runtime pack (Microsoft.NETCore.App.Runtime.browser-wasm).</summary>\n    CoreCLR\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Detectors/Cpu/HardwareIntrinsics.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Diagnostics.CodeAnalysis;\nusing System.Numerics;\nusing System.Text;\nusing BenchmarkDotNet.Environments;\n#if NET6_0_OR_GREATER\nusing System.Runtime.Intrinsics.X86;\nusing System.Runtime.Intrinsics.Arm;\n#endif\n\nnamespace BenchmarkDotNet.Detectors.Cpu\n{\n    // based on https://github.com/dotnet/runtime/tree/v10.0.0-rc.1.25451.107/src/coreclr/tools/Common/JitInterface/ThunkGenerator/InstructionSetDesc.txt\n    internal static class HardwareIntrinsics\n    {\n        internal static string GetVectorSize() => Vector.IsHardwareAccelerated ? $\"VectorSize={Vector<byte>.Count * 8}\" : string.Empty;\n\n        internal static string GetShortInfo()\n        {\n            if (IsX86BaseSupported)\n            {\n                if (IsX86Avx512Supported)\n                {\n                    return \"x86-64-v4\";\n                }\n                else if (IsX86Avx2Supported)\n                {\n                    return \"x86-64-v3\";\n                }\n                else if (IsX86Sse42Supported)\n                {\n                    return \"x86-64-v2\";\n                }\n                else\n                {\n                    return \"x86-64-v1\";\n                }\n            }\n            else if (IsArmBaseSupported)\n            {\n                return \"armv8.0-a\";\n            }\n            else\n            {\n                return GetVectorSize(); // Runtimes prior to .NET Core 3.0 (APIs did not exist so we print non-exact Vector info)\n            }\n        }\n\n        internal static string GetFullInfo(Platform platform)\n        {\n            return string.Join(\",\", GetCurrentProcessInstructionSets(platform));\n\n            static IEnumerable<string> GetCurrentProcessInstructionSets(Platform platform)\n            {\n                switch (platform)\n                {\n                    case Platform.X86:\n                    case Platform.X64:\n                    {\n                        if (IsX86Avx10v2Supported) yield return \"AVX10v2\";\n                        if (IsX86Avx10v1Supported)\n                        {\n                            yield return \"AVX10v1\";\n                            yield return \"AVX512 BF16+FP16\";\n                        }\n                        if (IsX86Avx512v3Supported) yield return \"AVX512 BITALG+VBMI2+VNNI+VPOPCNTDQ\";\n                        if (IsX86Avx512v2Supported) yield return \"AVX512 IFMA+VBMI\";\n                        if (IsX86Avx512Supported) yield return \"AVX512 F+BW+CD+DQ+VL\";\n                        if (IsX86Avx2Supported) yield return \"AVX2+BMI1+BMI2+F16C+FMA+LZCNT+MOVBE\";\n                        if (IsX86AvxSupported) yield return \"AVX\";\n                        if (IsX86Sse42Supported) yield return \"SSE3+SSSE3+SSE4.1+SSE4.2+POPCNT\";\n                        if (IsX86BaseSupported) yield return \"X86Base+SSE+SSE2\";\n                        if (IsX86AesSupported) yield return \"AES+PCLMUL\";\n                        if (IsX86AvxVnniSupported) yield return \"AvxVnni\";\n                        if (IsX86SerializeSupported) yield return \"SERIALIZE\";\n                        break;\n                    }\n                    case Platform.Arm64:\n                    {\n                        if (IsArmBaseSupported)\n                        {\n                            yield return \"ArmBase+AdvSimd\";\n                        }\n\n                        if (IsArmAesSupported) yield return \"AES\";\n                        if (IsArmCrc32Supported) yield return \"CRC32\";\n                        if (IsArmDpSupported) yield return \"DP\";\n                        if (IsArmRdmSupported) yield return \"RDM\";\n                        if (IsArmSha1Supported) yield return \"SHA1\";\n                        if (IsArmSha256Supported) yield return \"SHA256\";\n                        break;\n                    }\n\n                    default:\n                        yield break;\n                }\n            }\n        }\n\n#pragma warning disable CA2252 // Some APIs require opting into preview features\n        internal static bool IsX86BaseSupported =>\n#if NET6_0_OR_GREATER\n            X86Base.IsSupported &&\n            Sse.IsSupported &&\n            Sse2.IsSupported;\n#elif NETSTANDARD\n            GetIsSupported(\"System.Runtime.Intrinsics.X86.X86Base\") &&\n            GetIsSupported(\"System.Runtime.Intrinsics.X86.Sse\") &&\n            GetIsSupported(\"System.Runtime.Intrinsics.X86.Sse2\");\n#endif\n\n        internal static bool IsX86Sse42Supported =>\n#if NET6_0_OR_GREATER\n            Sse3.IsSupported &&\n            Ssse3.IsSupported &&\n            Sse41.IsSupported &&\n            Sse42.IsSupported &&\n            Popcnt.IsSupported;\n#elif NETSTANDARD\n            GetIsSupported(\"System.Runtime.Intrinsics.X86.Sse3\") &&\n            GetIsSupported(\"System.Runtime.Intrinsics.X86.Ssse3\") &&\n            GetIsSupported(\"System.Runtime.Intrinsics.X86.Sse41\") &&\n            GetIsSupported(\"System.Runtime.Intrinsics.X86.Sse42\") &&\n            GetIsSupported(\"System.Runtime.Intrinsics.X86.Popcnt\");\n#endif\n\n        internal static bool IsX86AvxSupported =>\n#if NET6_0_OR_GREATER\n            Avx.IsSupported;\n#elif NETSTANDARD\n            GetIsSupported(\"System.Runtime.Intrinsics.X86.Avx\");\n#endif\n\n        internal static bool IsX86Avx2Supported =>\n#if NET6_0_OR_GREATER\n            Avx2.IsSupported &&\n            Bmi1.IsSupported &&\n            Bmi2.IsSupported &&\n            Fma.IsSupported &&\n            Lzcnt.IsSupported;\n#elif NETSTANDARD\n            GetIsSupported(\"System.Runtime.Intrinsics.X86.Avx2\") &&\n            GetIsSupported(\"System.Runtime.Intrinsics.X86.Bmi1\") &&\n            GetIsSupported(\"System.Runtime.Intrinsics.X86.Bmi2\") &&\n            GetIsSupported(\"System.Runtime.Intrinsics.X86.Fma\") &&\n            GetIsSupported(\"System.Runtime.Intrinsics.X86.Lzcnt\");\n#endif\n\n        internal static bool IsX86Avx512Supported =>\n#if NET8_0_OR_GREATER\n            Avx512F.IsSupported &&\n            Avx512F.VL.IsSupported &&\n            Avx512BW.IsSupported &&\n            Avx512BW.VL.IsSupported &&\n            Avx512CD.IsSupported &&\n            Avx512CD.VL.IsSupported &&\n            Avx512DQ.IsSupported &&\n            Avx512DQ.VL.IsSupported;\n#else\n            GetIsSupported(\"System.Runtime.Intrinsics.X86.Avx512F\") &&\n            GetIsSupported(\"System.Runtime.Intrinsics.X86.Avx512F+VL\") &&\n            GetIsSupported(\"System.Runtime.Intrinsics.X86.Avx512BW\") &&\n            GetIsSupported(\"System.Runtime.Intrinsics.X86.Avx512BW+VL\") &&\n            GetIsSupported(\"System.Runtime.Intrinsics.X86.Avx512CD\") &&\n            GetIsSupported(\"System.Runtime.Intrinsics.X86.Avx512CD+VL\") &&\n            GetIsSupported(\"System.Runtime.Intrinsics.X86.Avx512DQ\") &&\n            GetIsSupported(\"System.Runtime.Intrinsics.X86.Avx512DQ+VL\");\n#endif\n\n        internal static bool IsX86Avx512v2Supported =>\n#if NET8_0_OR_GREATER\n            Avx512Vbmi.IsSupported &&\n            Avx512Vbmi.VL.IsSupported;\n#else\n            GetIsSupported(\"System.Runtime.Intrinsics.X86.Avx512Vbmi\") &&\n            GetIsSupported(\"System.Runtime.Intrinsics.X86.Avx512Vbmi+VL\");\n#endif\n\n        internal static bool IsX86Avx512v3Supported =>\n#if NET10_0_OR_GREATER\n            Avx512Vbmi2.IsSupported &&\n            Avx512Vbmi2.VL.IsSupported;\n#else\n            GetIsSupported(\"System.Runtime.Intrinsics.X86.Avx512Vbmi2\") &&\n            GetIsSupported(\"System.Runtime.Intrinsics.X86.Avx512Vbmi2+VL\");\n#endif\n\n        internal static bool IsX86Avx10v1Supported =>\n#if NET9_0_OR_GREATER\n            Avx10v1.IsSupported &&\n            Avx10v1.V512.IsSupported;\n#else\n            GetIsSupported(\"System.Runtime.Intrinsics.X86.Avx10v1\") &&\n            GetIsSupported(\"System.Runtime.Intrinsics.X86.Avx10v1+V512\");\n#endif\n\n        internal static bool IsX86Avx10v2Supported =>\n#if NET10_0_OR_GREATER\n            Avx10v2.IsSupported &&\n            Avx10v2.V512.IsSupported;\n#else\n            GetIsSupported(\"System.Runtime.Intrinsics.X86.Avx10v2\") &&\n            GetIsSupported(\"System.Runtime.Intrinsics.X86.Avx10v2+V512\");\n#endif\n\n        internal static bool IsX86AesSupported =>\n#if NET6_0_OR_GREATER\n            System.Runtime.Intrinsics.X86.Aes.IsSupported &&\n            Pclmulqdq.IsSupported;\n#elif NETSTANDARD\n            GetIsSupported(\"System.Runtime.Intrinsics.X86.Aes\") &&\n            GetIsSupported(\"System.Runtime.Intrinsics.X86.Pclmulqdq\");\n#endif\n\n        internal static bool IsX86AvxVnniSupported =>\n#if NET6_0_OR_GREATER\n            AvxVnni.IsSupported;\n#elif NETSTANDARD\n            GetIsSupported(\"System.Runtime.Intrinsics.X86.AvxVnni\");\n#endif\n\n        internal static bool IsX86SerializeSupported =>\n#if NET7_0_OR_GREATER\n            X86Serialize.IsSupported;\n#else\n            GetIsSupported(\"System.Runtime.Intrinsics.X86.X86Serialize\");\n#endif\n\n        internal static bool IsArmBaseSupported =>\n#if NET6_0_OR_GREATER\n            ArmBase.IsSupported &&\n            AdvSimd.IsSupported;\n#elif NETSTANDARD\n            GetIsSupported(\"System.Runtime.Intrinsics.Arm.ArmBase\") &&\n            GetIsSupported(\"System.Runtime.Intrinsics.Arm.AdvSimd\");\n#endif\n\n        internal static bool IsArmAesSupported =>\n#if NET6_0_OR_GREATER\n            System.Runtime.Intrinsics.Arm.Aes.IsSupported;\n#elif NETSTANDARD\n            GetIsSupported(\"System.Runtime.Intrinsics.Arm.Aes\");\n#endif\n\n        internal static bool IsArmCrc32Supported =>\n#if NET6_0_OR_GREATER\n            Crc32.IsSupported;\n#elif NETSTANDARD\n            GetIsSupported(\"System.Runtime.Intrinsics.Arm.Crc32\");\n#endif\n\n        internal static bool IsArmDpSupported =>\n#if NET6_0_OR_GREATER\n            Dp.IsSupported;\n#elif NETSTANDARD\n            GetIsSupported(\"System.Runtime.Intrinsics.Arm.Dp\");\n#endif\n\n        internal static bool IsArmRdmSupported =>\n#if NET6_0_OR_GREATER\n            Rdm.IsSupported;\n#elif NETSTANDARD\n            GetIsSupported(\"System.Runtime.Intrinsics.Arm.Rdm\");\n#endif\n\n        internal static bool IsArmSha1Supported =>\n#if NET6_0_OR_GREATER\n            Sha1.IsSupported;\n#elif NETSTANDARD\n            GetIsSupported(\"System.Runtime.Intrinsics.Arm.Sha1\");\n#endif\n\n        internal static bool IsArmSha256Supported =>\n#if NET6_0_OR_GREATER\n            Sha256.IsSupported;\n#elif NETSTANDARD\n            GetIsSupported(\"System.Runtime.Intrinsics.Arm.Sha256\");\n#endif\n#pragma warning restore CA2252 // Some APIs require opting into preview features\n\n        private static bool GetIsSupported([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] string typeName)\n        {\n            Type type = Type.GetType(typeName)!;\n            if (type == null) return false;\n\n            return (bool)type.GetProperty(\"IsSupported\", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static)!.GetValue(null, null)!;\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Detectors/Cpu/ICpuDetector.cs",
    "content": "using Perfolizer.Models;\n\nnamespace BenchmarkDotNet.Detectors.Cpu;\n\n/// <summary>\n/// Loads the <see cref=\"CpuInfo\"/> for the current hardware\n/// </summary>\npublic interface ICpuDetector\n{\n    bool IsApplicable();\n    CpuInfo? Detect();\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Detectors/Cpu/Linux/LinuxCpuDetector.cs",
    "content": "﻿using System.Collections.Generic;\nusing BenchmarkDotNet.Helpers;\nusing Perfolizer.Models;\n\nnamespace BenchmarkDotNet.Detectors.Cpu.Linux;\n\n/// <summary>\n/// CPU information from output of the `cat /proc/cpuinfo` and `lscpu` command.\n/// Linux only.\n/// </summary>\ninternal class LinuxCpuDetector : ICpuDetector\n{\n    public bool IsApplicable() => OsDetector.IsLinux();\n\n    public CpuInfo? Detect()\n    {\n        if (!IsApplicable()) return null;\n\n        // lscpu output respects the system locale, so we should force language invariant environment for correct parsing\n        var languageInvariantEnvironment = new Dictionary<string, string>\n        {\n            [\"LC_ALL\"] = \"C\",\n            [\"LANG\"] = \"C\",\n            [\"LANGUAGE\"] = \"C\"\n        };\n\n        string? cpuInfo = ProcessHelper.RunAndReadOutput(\"cat\", \"/proc/cpuinfo\") ?? string.Empty;\n        string? lscpu = ProcessHelper.RunAndReadOutput(\"/bin/bash\", \"-c \\\"lscpu\\\"\", environmentVariables: languageInvariantEnvironment) ?? string.Empty;\n\n        if (cpuInfo == string.Empty && lscpu == string.Empty)\n            return null;\n\n        return LinuxCpuInfoParser.Parse(cpuInfo, lscpu);\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Detectors/Cpu/Linux/LinuxCpuInfoParser.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text.RegularExpressions;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Helpers;\nusing BenchmarkDotNet.Portability;\nusing Perfolizer.Horology;\nusing Perfolizer.Models;\n\nnamespace BenchmarkDotNet.Detectors.Cpu.Linux;\n\ninternal static class LinuxCpuInfoParser\n{\n    private static class ProcCpu\n    {\n        internal const string PhysicalId = \"physical id\";\n        internal const string CpuCores = \"cpu cores\";\n        internal const string ModelName = \"model name\";\n        internal const string MaxFrequency = \"max freq\";\n        internal const string NominalFrequencyBackup = \"nominal freq\";\n        internal const string NominalFrequency = \"cpu MHz\";\n    }\n\n    private static class Lscpu\n    {\n        internal const string MaxFrequency = \"CPU max MHz\";\n        internal const string ModelName = \"Model name\";\n        internal const string CoresPerSocket = \"Core(s) per socket\";\n    }\n\n    /// <param name=\"cpuInfo\">Output of `cat /proc/cpuinfo`</param>\n    /// <param name=\"lscpu\">Output of `lscpu`</param>\n    internal static CpuInfo Parse(string cpuInfo, string lscpu)\n    {\n        var processorModelNames = new HashSet<string>();\n        var processorsToPhysicalCoreCount = new Dictionary<string, int>();\n        int logicalCoreCount = 0;\n        double maxFrequency = 0.0;\n        double nominalFrequency = 0.0;\n\n        var logicalCores = SectionsHelper.ParseSections(cpuInfo, ':');\n        foreach (var logicalCore in logicalCores)\n        {\n            if (logicalCore.TryGetValue(ProcCpu.PhysicalId, out var physicalId) &&\n                logicalCore.TryGetValue(ProcCpu.CpuCores, out var cpuCoresValue) &&\n                int.TryParse(cpuCoresValue, out int cpuCoreCount) &&\n                cpuCoreCount > 0)\n                processorsToPhysicalCoreCount[physicalId] = cpuCoreCount;\n\n            if (logicalCore.TryGetValue(ProcCpu.ModelName, out var modelName))\n            {\n                processorModelNames.Add(modelName);\n                logicalCoreCount++;\n            }\n\n            if (logicalCore.TryGetValue(ProcCpu.MaxFrequency, out var maxCpuFreqValue) &&\n                Frequency.TryParseMHz(maxCpuFreqValue.Replace(',', '.'), out Frequency maxCpuFreq)\n                && maxCpuFreq > 0)\n            {\n                maxFrequency = Math.Max(maxFrequency, maxCpuFreq.ToMHz());\n            }\n\n            bool nominalFrequencyHasValue = logicalCore.TryGetValue(ProcCpu.NominalFrequency, out var nominalFreqValue);\n            bool nominalFrequencyBackupHasValue = logicalCore.TryGetValue(ProcCpu.NominalFrequencyBackup, out var nominalFreqBackupValue);\n\n            double nominalCpuFreq = 0.0;\n            double nominalCpuBackupFreq = 0.0;\n\n            if (nominalFrequencyHasValue &&\n                double.TryParse(nominalFreqValue, out nominalCpuFreq)\n                && nominalCpuFreq > 0)\n            {\n                nominalCpuFreq = nominalFrequency == 0 ? nominalCpuFreq : Math.Min(nominalFrequency, nominalCpuFreq);\n            }\n            if (nominalFrequencyBackupHasValue &&\n                     double.TryParse(nominalFreqBackupValue, out nominalCpuBackupFreq)\n                     && nominalCpuBackupFreq > 0)\n            {\n                nominalCpuBackupFreq = nominalFrequency == 0 ? nominalCpuBackupFreq : Math.Min(nominalFrequency, nominalCpuBackupFreq);\n            }\n\n            if (nominalFrequencyHasValue && nominalFrequencyBackupHasValue)\n            {\n                nominalFrequency = Math.Min(nominalCpuFreq, nominalCpuBackupFreq);\n            }\n            else\n            {\n                nominalFrequency = nominalCpuFreq == 0.0 ? nominalCpuBackupFreq : nominalCpuFreq;\n            }\n        }\n\n        int? coresPerSocket = null;\n        if (lscpu.IsNotBlank())\n        {\n            var lscpuParts = lscpu.Split('\\n')\n                .Where(line => line.Contains(':'))\n                .SelectMany(line => line.Split([':'], 2))\n                .ToList();\n            for (int i = 0; i + 1 < lscpuParts.Count; i += 2)\n            {\n                string name = lscpuParts[i].Trim();\n                string value = lscpuParts[i + 1].Trim();\n\n                if (name.EqualsWithIgnoreCase(Lscpu.MaxFrequency) &&\n                    Frequency.TryParseMHz(value.Replace(',', '.'), out Frequency maxFrequencyParsed)) // Example: `CPU max MHz: 3200,0000`\n                    maxFrequency = Math.Max(maxFrequency, maxFrequencyParsed.ToMHz());\n\n                if (name.EqualsWithIgnoreCase(Lscpu.ModelName))\n                    processorModelNames.Add(value);\n\n                if (name.EqualsWithIgnoreCase(Lscpu.CoresPerSocket) &&\n                    int.TryParse(value, out int coreCount))\n                    coresPerSocket = coreCount;\n            }\n        }\n\n        string? processorName = processorModelNames.Count > 0 ? string.Join(\", \", processorModelNames) : null;\n        int? physicalProcessorCount = processorsToPhysicalCoreCount.Count > 0 ? processorsToPhysicalCoreCount.Count : null;\n        int? physicalCoreCount = processorsToPhysicalCoreCount.Count > 0 ? processorsToPhysicalCoreCount.Values.Sum() : coresPerSocket;\n\n        Frequency? maxFrequencyActual = maxFrequency > 0 && physicalProcessorCount > 0\n            ? Frequency.FromMHz(maxFrequency) : null;\n\n        Frequency? nominalFrequencyActual = nominalFrequency > 0 && physicalProcessorCount > 0\n            ? Frequency.FromMHz(nominalFrequency) : null;\n\n        if (nominalFrequencyActual is null)\n        {\n            bool nominalFrequencyInBrandString = processorModelNames.Any(x => ParseFrequencyFromBrandString(x) is not null);\n\n            if (nominalFrequencyInBrandString)\n                nominalFrequencyActual = processorModelNames.Select(x => ParseFrequencyFromBrandString(x))\n                    .First(x => x is not null);\n        }\n\n        return new CpuInfo\n        {\n            ProcessorName = processorName,\n            PhysicalProcessorCount = physicalProcessorCount,\n            PhysicalCoreCount = physicalCoreCount,\n            LogicalCoreCount = logicalCoreCount > 0 ? logicalCoreCount : null,\n            NominalFrequencyHz = nominalFrequencyActual?.Hertz.RoundToLong(),\n            MaxFrequencyHz = maxFrequencyActual?.Hertz.RoundToLong()\n        };\n    }\n\n    internal static Frequency? ParseFrequencyFromBrandString(string brandString)\n    {\n        const string pattern = \"(\\\\d.\\\\d+)GHz\";\n        var matches = Regex.Matches(brandString, pattern, RegexOptions.IgnoreCase);\n        if (matches.Count > 0 && matches[0].Groups.Count > 1)\n        {\n            string match = Regex.Matches(brandString, pattern, RegexOptions.IgnoreCase)[0].Groups[1].ToString();\n            return Frequency.TryParseGHz(match, out Frequency result) ? result : null;\n        }\n\n        return null;\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Detectors/Cpu/Windows/MosCpuDetector.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Management;\nusing System.Runtime.Versioning;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Portability;\nusing Perfolizer.Horology;\nusing Perfolizer.Models;\n\nnamespace BenchmarkDotNet.Detectors.Cpu.Windows;\n\ninternal class MosCpuDetector : ICpuDetector\n{\n    [SupportedOSPlatform(\"windows\")]\n    public bool IsApplicable() => OsDetector.IsWindows() &&\n                                  RuntimeInformation.IsFullFramework &&\n                                  !RuntimeInformation.IsMono;\n\n    [SupportedOSPlatform(\"windows\")]\n    public CpuInfo? Detect()\n    {\n        if (!IsApplicable()) return null;\n\n        var processorModelNames = new HashSet<string>();\n        int physicalCoreCount = 0;\n        int logicalCoreCount = 0;\n        int processorsCount = 0;\n        double maxFrequency = 0;\n        double nominalFrequency = 0;\n\n        using (var mosProcessor = new ManagementObjectSearcher(\"SELECT * FROM Win32_Processor\"))\n        {\n            foreach (var moProcessor in mosProcessor.Get().Cast<ManagementObject>())\n            {\n                string? name = moProcessor[WmicCpuInfoKeyNames.Name]?.ToString();\n                if (name.IsNotBlank())\n                {\n                    processorModelNames.Add(name);\n                    processorsCount++;\n                    physicalCoreCount += (int)(uint)moProcessor[WmicCpuInfoKeyNames.NumberOfCores];\n                    logicalCoreCount += (int)(uint)moProcessor[WmicCpuInfoKeyNames.NumberOfLogicalProcessors];\n                    double tempMaxFrequency = (uint)moProcessor[WmicCpuInfoKeyNames.MaxClockSpeed];\n\n                    if (tempMaxFrequency > 0)\n                    {\n                        nominalFrequency = nominalFrequency == 0 ? tempMaxFrequency : Math.Min(nominalFrequency, tempMaxFrequency);\n                    }\n                    maxFrequency = Math.Max(maxFrequency, tempMaxFrequency);\n                }\n            }\n        }\n\n        string? processorName = processorModelNames.Count > 0 ? string.Join(\", \", processorModelNames) : null;\n        Frequency? maxFrequencyActual = maxFrequency > 0 && processorsCount > 0\n            ? Frequency.FromMHz(maxFrequency)\n            : null;\n        Frequency? nominalFrequencyActual = nominalFrequency > 0 && processorsCount > 0\n            ? Frequency.FromMHz(nominalFrequency)\n            : null;\n\n        return new CpuInfo\n        {\n            ProcessorName = processorName,\n            PhysicalProcessorCount = processorsCount > 0 ? processorsCount : null,\n            PhysicalCoreCount = physicalCoreCount > 0 ? physicalCoreCount : null,\n            LogicalCoreCount = logicalCoreCount > 0 ? logicalCoreCount : null,\n            NominalFrequencyHz = nominalFrequencyActual?.Hertz.RoundToLong(),\n            MaxFrequencyHz = maxFrequencyActual?.Hertz.RoundToLong()\n        };\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Detectors/Cpu/Windows/PowershellWmiCpuDetector.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Runtime.Versioning;\nusing System.Text.RegularExpressions;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Helpers;\nusing Perfolizer.Models;\n\nnamespace BenchmarkDotNet.Detectors.Cpu.Windows;\n\n/// <summary>\n/// CPU information from output of the `wmic cpu get Name, NumberOfCores, NumberOfLogicalProcessors /Format:List` command.\n/// Windows only.\n/// </summary>\ninternal class PowershellWmiCpuDetector : ICpuDetector\n{\n    private readonly string windowsPowershellPath =\n        $\"{Environment.SystemDirectory}{Path.DirectorySeparatorChar}WindowsPowerShell{Path.DirectorySeparatorChar}\" +\n        $\"v1.0{Path.DirectorySeparatorChar}powershell.exe\";\n\n    public bool IsApplicable() => OsDetector.IsWindows();\n\n    [SupportedOSPlatform(\"windows\")]\n    public CpuInfo? Detect()\n    {\n        if (!IsApplicable()) return null;\n\n        const string argList = $\"{WmicCpuInfoKeyNames.Name}, \" +\n                               $\"{WmicCpuInfoKeyNames.NumberOfCores}, \" +\n                               $\"{WmicCpuInfoKeyNames.NumberOfLogicalProcessors}, \" +\n                               $\"{WmicCpuInfoKeyNames.MaxClockSpeed}\";\n\n        string? output = ProcessHelper.RunAndReadOutput(PowerShellLocator.LocateOnWindows() ?? \"PowerShell\",\n            \"Get-CimInstance Win32_Processor -Property \" + argList);\n\n        if (output.IsBlank())\n            return null;\n\n        return PowershellWmiCpuInfoParser.Parse(output);\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Detectors/Cpu/Windows/PowershellWmiCpuInfoParser.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Helpers;\nusing Perfolizer.Horology;\nusing Perfolizer.Models;\n\nnamespace BenchmarkDotNet.Detectors.Cpu.Windows;\n\ninternal static class PowershellWmiCpuInfoParser\n{\n    internal static CpuInfo Parse(string powershellWmiOutput)\n    {\n        HashSet<string> processorModelNames = [];\n\n        int physicalCoreCount = 0;\n        int logicalCoreCount = 0;\n        int processorCount = 0;\n        double maxFrequency = 0.0;\n        double nominalFrequency = 0.0;\n\n        List<Dictionary<string, string>> processors = SectionsHelper.ParseSectionsForPowershellWmi(powershellWmiOutput, ':');\n        foreach (Dictionary<string, string> processor in processors)\n        {\n            if (processor.TryGetValue(WmicCpuInfoKeyNames.NumberOfCores, out string? numberOfCoresValue) &&\n                int.TryParse(numberOfCoresValue, out int numberOfCores) &&\n                numberOfCores > 0)\n                physicalCoreCount += numberOfCores;\n\n            if (processor.TryGetValue(WmicCpuInfoKeyNames.NumberOfLogicalProcessors, out string? numberOfLogicalValue) &&\n                int.TryParse(numberOfLogicalValue, out int numberOfLogical) &&\n                numberOfLogical > 0)\n                logicalCoreCount += numberOfLogical;\n\n            if (processor.TryGetValue(WmicCpuInfoKeyNames.Name, out string? name))\n            {\n                processorModelNames.Add(name);\n                processorCount++;\n            }\n\n            if (processor.TryGetValue(WmicCpuInfoKeyNames.MaxClockSpeed, out string? frequencyValue)\n                && double.TryParse(frequencyValue, out double frequency)\n                && frequency > 0)\n            {\n               nominalFrequency = nominalFrequency == 0 ? frequency : Math.Min(nominalFrequency, frequency);\n               maxFrequency = Math.Max(maxFrequency, frequency);\n            }\n        }\n\n        string? processorName = processorModelNames.Count > 0 ? string.Join(\", \", processorModelNames) : null;\n        Frequency? maxFrequencyActual = maxFrequency > 0 && processorCount > 0\n            ? Frequency.FromMHz(maxFrequency) : null;\n\n        Frequency? nominalFrequencyActual = nominalFrequency > 0 && processorCount > 0 ?\n            Frequency.FromMHz(nominalFrequency) : null;\n\n        return new CpuInfo\n        {\n            ProcessorName = processorName,\n            PhysicalProcessorCount = processorCount > 0 ? processorCount : null,\n            PhysicalCoreCount = physicalCoreCount > 0 ? physicalCoreCount : null,\n            LogicalCoreCount = logicalCoreCount > 0 ? logicalCoreCount : null,\n            NominalFrequencyHz = nominalFrequencyActual?.Hertz.RoundToLong(),\n            MaxFrequencyHz = maxFrequencyActual?.Hertz.RoundToLong()\n        };\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Detectors/Cpu/Windows/WindowsCpuDetector.cs",
    "content": "namespace BenchmarkDotNet.Detectors.Cpu.Windows;\n\ninternal class WindowsCpuDetector() : CpuDetector(new MosCpuDetector(), new PowershellWmiCpuDetector(),\n    new WmicCpuDetector());"
  },
  {
    "path": "src/BenchmarkDotNet/Detectors/Cpu/Windows/WmicCpuDetector.cs",
    "content": "﻿using System.IO;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Helpers;\nusing BenchmarkDotNet.Portability;\nusing Perfolizer.Models;\n\nnamespace BenchmarkDotNet.Detectors.Cpu.Windows;\n\n/// <summary>\n/// CPU information from output of the `wmic cpu get Name, NumberOfCores, NumberOfLogicalProcessors /Format:List` command.\n/// Windows only.\n/// </summary>\n/// <remarks>WMIC is deprecated by Microsoft starting with Windows 10 21H1 (including Windows Server), and it is not known whether it still ships with Windows by default.\n/// <para>WMIC may be removed in a future version of Windows. See <see href=\"https://learn.microsoft.com/en-us/windows/win32/wmisdk/wmic\"/> </para></remarks>\ninternal class WmicCpuDetector : ICpuDetector\n{\n    private const string DefaultWmicPath = @\"C:\\Windows\\System32\\wbem\\WMIC.exe\";\n\n    public bool IsApplicable() => OsDetector.IsWindows();\n\n    public CpuInfo? Detect()\n    {\n        if (!IsApplicable()) return null;\n\n        const string argList = $\"{WmicCpuInfoKeyNames.Name}, \" +\n                               $\"{WmicCpuInfoKeyNames.NumberOfCores}, \" +\n                               $\"{WmicCpuInfoKeyNames.NumberOfLogicalProcessors}, \" +\n                               $\"{WmicCpuInfoKeyNames.MaxClockSpeed}\";\n        string wmicPath = File.Exists(DefaultWmicPath) ? DefaultWmicPath : \"wmic\";\n        string? wmicOutput = ProcessHelper.RunAndReadOutput(wmicPath, $\"cpu get {argList} /Format:List\");\n\n        if (wmicOutput.IsBlank())\n            return null;\n\n        return WmicCpuInfoParser.Parse(wmicOutput);\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Detectors/Cpu/Windows/WmicCpuInfoKeyNames.cs",
    "content": "﻿namespace BenchmarkDotNet.Detectors.Cpu.Windows;\n\ninternal static class WmicCpuInfoKeyNames\n{\n    internal const string NumberOfLogicalProcessors = \"NumberOfLogicalProcessors\";\n    internal const string NumberOfCores = \"NumberOfCores\";\n    internal const string Name = \"Name\";\n    internal const string MaxClockSpeed = \"MaxClockSpeed\";\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Detectors/Cpu/Windows/WmicCpuInfoParser.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Helpers;\nusing Perfolizer.Horology;\nusing Perfolizer.Models;\n\nnamespace BenchmarkDotNet.Detectors.Cpu.Windows;\n\ninternal static class WmicCpuInfoParser\n{\n    /// <summary>\n    /// Parses wmic output and returns <see cref=\"CpuInfo\"/>\n    /// </summary>\n    /// <param name=\"wmicOutput\">Output of `wmic cpu get Name, NumberOfCores, NumberOfLogicalProcessors /Format:List`</param>\n    internal static CpuInfo Parse(string wmicOutput)\n    {\n        HashSet<string> processorModelNames = [];\n        int physicalCoreCount = 0;\n        int logicalCoreCount = 0;\n        int processorsCount = 0;\n        double maxFrequency = 0.0;\n        double nominalFrequency = 0.0;\n\n        List<Dictionary<string, string>> processors = SectionsHelper.ParseSections(wmicOutput, '=');\n        foreach (var processor in processors)\n        {\n            if (processor.TryGetValue(WmicCpuInfoKeyNames.NumberOfCores, out var numberOfCoresValue) &&\n                int.TryParse(numberOfCoresValue, out int numberOfCores) &&\n                numberOfCores > 0)\n                physicalCoreCount += numberOfCores;\n\n            if (processor.TryGetValue(WmicCpuInfoKeyNames.NumberOfLogicalProcessors, out var numberOfLogicalValue) &&\n                int.TryParse(numberOfLogicalValue, out int numberOfLogical) &&\n                numberOfLogical > 0)\n                logicalCoreCount += numberOfLogical;\n\n            if (processor.TryGetValue(WmicCpuInfoKeyNames.Name, out var name))\n            {\n                processorModelNames.Add(name);\n                processorsCount++;\n            }\n\n            if (processor.TryGetValue(WmicCpuInfoKeyNames.MaxClockSpeed, out var frequencyValue)\n                && double.TryParse(frequencyValue, out double frequency)\n                && frequency > 0)\n            {\n                nominalFrequency = nominalFrequency == 0 ? frequency : Math.Min(nominalFrequency, frequency);\n                maxFrequency = Math.Max(maxFrequency, frequency);\n            }\n        }\n\n        string? processorName = processorModelNames.Count > 0 ? string.Join(\", \", processorModelNames) : null;\n        Frequency? maxFrequencyActual = maxFrequency > 0 && processorsCount > 0\n            ? Frequency.FromMHz(maxFrequency)\n            : null;\n\n        Frequency? nominalFrequencyActual = nominalFrequency > 0 && processorsCount > 0 ? Frequency.FromMHz(nominalFrequency) : null;\n\n        return new CpuInfo\n        {\n            ProcessorName = processorName,\n            PhysicalProcessorCount = processorsCount > 0 ? processorsCount : null,\n            PhysicalCoreCount = physicalCoreCount > 0 ? physicalCoreCount : null,\n            LogicalCoreCount = logicalCoreCount > 0 ? logicalCoreCount : null,\n            NominalFrequencyHz = nominalFrequencyActual?.Hertz.RoundToLong(),\n            MaxFrequencyHz = maxFrequencyActual?.Hertz.RoundToLong()\n        };\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Detectors/Cpu/macOS/MacOsCpuDetector.cs",
    "content": "﻿using BenchmarkDotNet.Helpers;\nusing Perfolizer.Models;\n\nnamespace BenchmarkDotNet.Detectors.Cpu.macOS;\n\n/// <summary>\n/// CPU information from output of the `sysctl -a` command.\n/// MacOSX only.\n/// </summary>\ninternal class MacOsCpuDetector : ICpuDetector\n{\n    public bool IsApplicable() => OsDetector.IsMacOS();\n\n    public CpuInfo? Detect()\n    {\n        if (!IsApplicable()) return null;\n\n        string? sysctlOutput = ProcessHelper.RunAndReadOutput(\"sysctl\", \"-a\");\n\n        if (sysctlOutput is null)\n            return null;\n\n        return SysctlCpuInfoParser.Parse(sysctlOutput);\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Detectors/Cpu/macOS/SysctlCpuInfoParser.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Diagnostics.CodeAnalysis;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Helpers;\nusing Perfolizer.Models;\n\nnamespace BenchmarkDotNet.Detectors.Cpu.macOS;\n\ninternal static class SysctlCpuInfoParser\n{\n    private static class Sysctl\n    {\n        internal const string ProcessorName = \"machdep.cpu.brand_string\";\n        internal const string PhysicalProcessorCount = \"hw.packages\";\n        internal const string PhysicalCoreCount = \"hw.physicalcpu\";\n        internal const string LogicalCoreCount = \"hw.logicalcpu\";\n        internal const string NominalFrequency = \"hw.cpufrequency\";\n        internal const string MaxFrequency = \"hw.cpufrequency_max\";\n    }\n\n    /// <param name=\"sysctlOutput\">Output of `sysctl -a`</param>\n    [SuppressMessage(\"ReSharper\", \"StringLiteralTypo\")]\n    internal static CpuInfo Parse(string sysctlOutput)\n    {\n        var sysctl = SectionsHelper.ParseSection(sysctlOutput, ':');\n        string? processorName = sysctl.GetValueOrDefault(Sysctl.ProcessorName);\n        int? physicalProcessorCount = PositiveIntValue(sysctl, Sysctl.PhysicalProcessorCount);\n        int? physicalCoreCount = PositiveIntValue(sysctl, Sysctl.PhysicalCoreCount);\n        int? logicalCoreCount = PositiveIntValue(sysctl, Sysctl.LogicalCoreCount);\n        long? nominalFrequency = PositiveLongValue(sysctl, Sysctl.NominalFrequency);\n        long? maxFrequency = PositiveLongValue(sysctl, Sysctl.MaxFrequency);\n        return new CpuInfo\n        {\n            ProcessorName = processorName,\n            PhysicalProcessorCount = physicalProcessorCount,\n            PhysicalCoreCount = physicalCoreCount,\n            LogicalCoreCount = logicalCoreCount,\n            NominalFrequencyHz = nominalFrequency,\n            MaxFrequencyHz = maxFrequency\n        };\n    }\n\n    private static int? PositiveIntValue(Dictionary<string, string> sysctl, string keyName)\n    {\n        if (sysctl.TryGetValue(keyName, out var value) &&\n            int.TryParse(value, out int result) &&\n            result > 0)\n            return result;\n        return null;\n    }\n\n    private static long? PositiveLongValue(Dictionary<string, string> sysctl, string keyName)\n    {\n        if (sysctl.TryGetValue(keyName, out var value) &&\n            long.TryParse(value, out long result) &&\n            result > 0)\n            return result;\n        return null;\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Detectors/CpuDetector.cs",
    "content": "using System;\nusing System.Linq;\nusing BenchmarkDotNet.Detectors.Cpu;\nusing BenchmarkDotNet.Detectors.Cpu.Linux;\nusing BenchmarkDotNet.Detectors.Cpu.macOS;\nusing BenchmarkDotNet.Detectors.Cpu.Windows;\nusing BenchmarkDotNet.Extensions;\nusing Perfolizer.Models;\n\nnamespace BenchmarkDotNet.Detectors;\n\npublic class CpuDetector(params ICpuDetector[] detectors) : ICpuDetector\n{\n    public static CpuDetector CrossPlatform => new(\n        new WindowsCpuDetector(),\n        new LinuxCpuDetector(),\n        new MacOsCpuDetector());\n\n    private static readonly Lazy<CpuInfo?> LazyCpu = new(() => CrossPlatform.Detect());\n    public static CpuInfo? Cpu => LazyCpu.Value;\n\n    public bool IsApplicable() => detectors.Any(loader => loader.IsApplicable());\n\n    public CpuInfo? Detect() => detectors\n        .Where(loader => loader.IsApplicable())\n        .Select(loader => loader.Detect())\n        .WhereNotNull()\n        .FirstOrDefault();\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Detectors/OsDetector.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing BenchmarkDotNet.Helpers;\nusing Microsoft.Win32;\nusing System.Runtime.InteropServices;\nusing BenchmarkDotNet.Extensions;\nusing Perfolizer.Models;\nusing static System.Runtime.InteropServices.RuntimeInformation;\nusing RuntimeEnvironment = Microsoft.DotNet.PlatformAbstractions.RuntimeEnvironment;\nusing System.Runtime.Versioning;\n\nnamespace BenchmarkDotNet.Detectors;\n\npublic class OsDetector\n{\n    public static readonly OsDetector Instance = new();\n    private OsDetector() { }\n\n    internal static string ExecutableExtension => IsWindows() ? \".exe\" : string.Empty;\n    internal static string ScriptFileExtension => IsWindows() ? \".bat\" : \".sh\";\n\n    private readonly Lazy<OsInfo> os = new(ResolveOs);\n    public static OsInfo GetOs() => Instance.os.Value;\n\n    private static OsInfo ResolveOs()\n    {\n        if (IsMacOS())\n        {\n            string systemVersion = ExternalToolsHelper.MacSystemProfilerData.Value.GetValueOrDefault(\"System Version\") ?? \"\";\n            string kernelVersion = ExternalToolsHelper.MacSystemProfilerData.Value.GetValueOrDefault(\"Kernel Version\") ?? \"\";\n            return new OsInfo\n            {\n                Name = \"macOS\",\n                Version = systemVersion,\n                KernelVersion = kernelVersion\n            };\n        }\n\n        if (IsLinux())\n        {\n            try\n            {\n                string? version = LinuxOsReleaseHelper.GetNameByOsRelease(File.ReadAllLines(\"/etc/os-release\"));\n                bool wsl = IsUnderWsl();\n                return new OsInfo\n                {\n                    Name = \"Linux\",\n                    Version = version,\n                    Container = wsl ? \"WSL\" : null\n                };\n            }\n            catch (Exception)\n            {\n                // Ignore\n            }\n        }\n\n        string operatingSystem = RuntimeEnvironment.OperatingSystem;\n        string operatingSystemVersion = RuntimeEnvironment.OperatingSystemVersion;\n        if (IsWindows())\n        {\n            int? ubr = GetWindowsUbr();\n            if (ubr != null)\n                operatingSystemVersion += $\".{ubr}\";\n        }\n        return new OsInfo\n        {\n            Name = operatingSystem,\n            Version = operatingSystemVersion\n        };\n    }\n\n    private static bool IsUnderWsl()\n    {\n        if (!IsLinux())\n            return false;\n        try\n        {\n            return File.Exists(\"/proc/sys/fs/binfmt_misc/WSLInterop\"); // https://superuser.com/a/1749811\n        }\n        catch (Exception)\n        {\n            return false;\n        }\n    }\n\n    // TODO: Introduce a common util API for registry calls, use it also in BenchmarkDotNet.Toolchains.CsProj.GetCurrentVersionBasedOnWindowsRegistry\n    /// <summary>\n    /// On Windows, this method returns UBR (Update Build Revision) based on Registry.\n    /// Returns null if the value is not available\n    /// </summary>\n    /// <returns></returns>\n    private static int? GetWindowsUbr()\n    {\n        if (IsWindows())\n        {\n            try\n            {\n                using (var baseKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32))\n                using (var ndpKey = baseKey.OpenSubKey(@\"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\"))\n                {\n                    if (ndpKey == null)\n                        return null;\n\n                    return Convert.ToInt32(ndpKey.GetValue(\"UBR\"));\n                }\n            }\n            catch (Exception)\n            {\n                return null;\n            }\n        }\n        return null;\n    }\n\n    [SupportedOSPlatformGuard(\"windows\")]\n    internal static bool IsWindows() =>\n#if NET6_0_OR_GREATER\n        OperatingSystem.IsWindows(); // prefer linker-friendly OperatingSystem APIs\n#else\n        IsOSPlatform(OSPlatform.Windows);\n#endif\n\n\n    [SupportedOSPlatformGuard(\"linux\")]\n    internal static bool IsLinux() =>\n#if NET6_0_OR_GREATER\n        OperatingSystem.IsLinux();\n#else\n        IsOSPlatform(OSPlatform.Linux);\n#endif\n\n    [SupportedOSPlatformGuard(\"macos\")]\n    // ReSharper disable once InconsistentNaming\n    internal static bool IsMacOS() =>\n#if NET6_0_OR_GREATER\n        OperatingSystem.IsMacOS();\n#else\n        IsOSPlatform(OSPlatform.OSX);\n#endif\n\n    [SupportedOSPlatformGuard(\"android\")]\n    internal static bool IsAndroid() =>\n#if NET6_0_OR_GREATER\n        OperatingSystem.IsAndroid();\n#else\n        Type.GetType(\"Java.Lang.Object, Mono.Android\") != null;\n#endif\n\n    [SupportedOSPlatformGuard(\"ios\")]\n    // ReSharper disable once InconsistentNaming\n    internal static bool IsIOS() =>\n#if NET6_0_OR_GREATER\n        OperatingSystem.IsIOS();\n#else\n        Type.GetType(\"Foundation.NSObject, Xamarin.iOS\") != null;\n#endif\n\n    [SupportedOSPlatformGuard(\"tvos\")]\n    // ReSharper disable once InconsistentNaming\n    internal static bool IsTvOS() =>\n#if NET6_0_OR_GREATER\n        OperatingSystem.IsTvOS();\n#else\n        IsOSPlatform(OSPlatform.Create(\"TVOS\"));\n#endif\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Diagnosers/AllocatedMemoryMetricDescriptor.cs",
    "content": "﻿using System;\nusing BenchmarkDotNet.Columns;\nusing BenchmarkDotNet.Reports;\nusing Perfolizer.Metrology;\n\nnamespace BenchmarkDotNet.Diagnosers\n{\n    internal class AllocatedMemoryMetricDescriptor : IMetricDescriptor\n    {\n        internal static readonly IMetricDescriptor Instance = new AllocatedMemoryMetricDescriptor();\n\n        public string Id => \"Allocated Memory\";\n        public string DisplayName => Column.Allocated;\n        public string Legend => \"Allocated memory per single operation (managed only, inclusive, 1KB = 1024B)\";\n        public string NumberFormat => \"0.##\";\n        public UnitType UnitType => UnitType.Size;\n        public string Unit => SizeUnit.B.Abbreviation;\n        public bool TheGreaterTheBetter => false;\n        public int PriorityInCategory => GC.MaxGeneration + 1;\n        public bool GetIsAvailable(Metric metric) => true;\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Diagnosers/AllocatedNativeMemoryDescriptor.cs",
    "content": "﻿using BenchmarkDotNet.Columns;\nusing BenchmarkDotNet.Reports;\nusing Perfolizer.Metrology;\n\nnamespace BenchmarkDotNet.Diagnosers\n{\n    internal class AllocatedNativeMemoryDescriptor : IMetricDescriptor\n    {\n        internal static readonly IMetricDescriptor Instance = new AllocatedNativeMemoryDescriptor();\n\n        public string Id => nameof(AllocatedNativeMemoryDescriptor);\n        public string DisplayName => Column.AllocatedNativeMemory;\n        public string Legend => $\"Allocated native memory per single operation\";\n        public string NumberFormat => \"N0\";\n        public UnitType UnitType => UnitType.Size;\n        public string Unit => SizeUnit.B.Abbreviation;\n        public bool TheGreaterTheBetter => false;\n        public int PriorityInCategory => 0;\n        public bool GetIsAvailable(Metric metric) => true;\n    }\n\n    internal class NativeMemoryLeakDescriptor : IMetricDescriptor\n    {\n        internal static readonly IMetricDescriptor Instance = new NativeMemoryLeakDescriptor();\n\n        public string Id => nameof(NativeMemoryLeakDescriptor);\n        public string DisplayName => Column.NativeMemoryLeak;\n        public string Legend => $\"Native memory leak size in byte.\";\n        public string NumberFormat => \"N0\";\n        public UnitType UnitType => UnitType.Size;\n        public string Unit => SizeUnit.B.Abbreviation;\n        public bool TheGreaterTheBetter => false;\n        public int PriorityInCategory => 0;\n        public bool GetIsAvailable(Metric metric) => true;\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Diagnosers/CompositeDiagnoser.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Collections.Immutable;\nusing System.ComponentModel;\nusing System.Linq;\nusing System.Runtime.CompilerServices;\nusing BenchmarkDotNet.Analysers;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Exporters;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Portability;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Validators;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Diagnosers\n{\n    public sealed class CompositeDiagnoser : IDiagnoser\n    {\n        internal readonly ImmutableHashSet<IDiagnoser> diagnosers;\n\n        public CompositeDiagnoser(ImmutableHashSet<IDiagnoser> diagnosers)\n            => this.diagnosers = diagnosers;\n\n        public RunMode GetRunMode(BenchmarkCase benchmarkCase)\n            => throw new InvalidOperationException(\"Should never be called for Composite Diagnoser\");\n\n        public IEnumerable<string> Ids\n            => diagnosers.SelectMany(d => d.Ids);\n\n        public IEnumerable<IExporter> Exporters\n            => diagnosers.SelectMany(diagnoser => diagnoser.Exporters);\n\n        public IEnumerable<IAnalyser> Analysers\n            => diagnosers.SelectMany(diagnoser => diagnoser.Analysers);\n\n        [MethodImpl(CodeGenHelper.AggressiveOptimizationOption)]\n        public void Handle(HostSignal signal, DiagnoserActionParameters parameters)\n        {\n            foreach (var diagnoser in diagnosers)\n                diagnoser.Handle(signal, parameters);\n        }\n\n        public IEnumerable<Metric> ProcessResults(DiagnoserResults results)\n            => diagnosers.SelectMany(diagnoser => diagnoser.ProcessResults(results));\n\n        public void DisplayResults(ILogger logger)\n        {\n            foreach (var diagnoser in diagnosers)\n            {\n                logger.WriteLineHeader($\"// * Diagnostic Output - {diagnoser.Ids.Single()} *\");\n                diagnoser.DisplayResults(logger);\n                logger.WriteLine();\n            }\n        }\n\n        public IEnumerable<ValidationError> Validate(ValidationParameters validationParameters)\n            => diagnosers.SelectMany(diagnoser => diagnoser.Validate(validationParameters));\n    }\n\n    public sealed class CompositeInProcessDiagnoser(IReadOnlyList<IInProcessDiagnoser> inProcessDiagnosers)\n    {\n        public const string HeaderKey = \"// InProcessDiagnoser\";\n        public const string ResultsKey = $\"{HeaderKey}Results\";\n\n        public IReadOnlyList<IInProcessDiagnoser> InProcessDiagnosers { get; } = inProcessDiagnosers;\n\n        public void DeserializeResults(int index, BenchmarkCase benchmarkCase, string results)\n            => InProcessDiagnosers[index].DeserializeResults(benchmarkCase, results);\n    }\n\n    [UsedImplicitly]\n    [EditorBrowsable(EditorBrowsableState.Never)]\n    public sealed class CompositeInProcessDiagnoserHandler(IReadOnlyList<InProcessDiagnoserRouter> routers, IHost host, RunMode runMode, InProcessDiagnoserActionArgs parameters)\n    {\n        [MethodImpl(CodeGenHelper.AggressiveOptimizationOption)]\n        public void Handle(BenchmarkSignal signal)\n        {\n            if (runMode == RunMode.None)\n            {\n                return;\n            }\n\n            foreach (var router in routers)\n            {\n                if (router.ShouldHandle(runMode))\n                {\n                    router.handler.Handle(signal, parameters);\n                }\n            }\n\n            if (signal is not (BenchmarkSignal.AfterEngine or BenchmarkSignal.SeparateLogic))\n            {\n                return;\n            }\n\n            foreach (var router in routers)\n            {\n                if (!router.ShouldHandle(runMode))\n                {\n                    continue;\n                }\n\n                var results = router.handler.SerializeResults();\n                // Send header with the diagnoser index for routing, and line count of payload (user handler may include newlines in their serialized results).\n                // Ideally we would simply use results.Length, write it directly to host, then the host reads the exact count of chars.\n                // But WasmExecutor does not use Broker, and reads all output, so we need to instead use line count and prepend every line with CompositeInProcessDiagnoser.ResultsKey.\n                var resultsLines = results.Split([\"\\r\\n\", \"\\r\", \"\\n\"], StringSplitOptions.None);\n                host.WriteLine($\"{CompositeInProcessDiagnoser.HeaderKey} {router.index} {resultsLines.Length}\");\n                foreach (var line in resultsLines)\n                {\n                    host.WriteLine($\"{CompositeInProcessDiagnoser.ResultsKey} {line}\");\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Diagnosers/DiagnoserActionParameters.cs",
    "content": "﻿using System;\nusing System.Diagnostics;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Running;\n\nnamespace BenchmarkDotNet.Diagnosers\n{\n    public class DiagnoserActionParameters\n    {\n        public DiagnoserActionParameters(Process? process, BenchmarkCase benchmarkCase, BenchmarkId benchmarkId)\n        {\n            Process = process;\n            BenchmarkCase = benchmarkCase;\n            BenchmarkId = benchmarkId;\n        }\n\n        public Process? Process { get; }\n\n        public int ProcessId => Process?.Id ?? throw new InvalidOperationException(\"The process instance is not set.\");\n\n        public BenchmarkCase BenchmarkCase { get; }\n\n        public BenchmarkId BenchmarkId { get; }\n\n        public ImmutableConfig Config => BenchmarkCase.Config;\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Diagnosers/DiagnoserResults.cs",
    "content": "﻿using BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Toolchains.Results;\nusing System.Collections.Generic;\n\nnamespace BenchmarkDotNet.Diagnosers\n{\n    public class DiagnoserResults(BenchmarkCase benchmarkCase, ExecuteResult executeResult, BuildResult buildResult)\n    {\n        public BenchmarkCase BenchmarkCase { get; } = benchmarkCase;\n\n        public GcStats GcStats { get; } = executeResult.GcStats;\n\n        public BuildResult BuildResult { get; } = buildResult;\n\n        public IReadOnlyList<Measurement> Measurements { get; } = executeResult.Measurements;\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Diagnosers/DiagnosersLoader.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Reflection;\nusing System.Threading;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Detectors;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Portability;\n\nnamespace BenchmarkDotNet.Diagnosers\n{\n    internal static class DiagnosersLoader\n    {\n        private const string WindowsDiagnosticAssemblyFileName = \"BenchmarkDotNet.Diagnostics.Windows.dll\";\n        private const string WindowsDiagnosticAssemblyName = \"BenchmarkDotNet.Diagnostics.Windows\";\n\n        // Make the Diagnosers lazy-loaded, so they are only instantiated if needed\n        private static readonly Lazy<IDiagnoser[]> LazyLoadedDiagnosers\n            = new Lazy<IDiagnoser[]>(() => LoadDiagnosers().ToArray(), LazyThreadSafetyMode.ExecutionAndPublication);\n\n        internal static IDiagnoser GetImplementation<TDiagnoser>() where TDiagnoser : IDiagnoser\n            => LazyLoadedDiagnosers.Value\n                    .FirstOrDefault(diagnoser => diagnoser is TDiagnoser) // few diagnosers can implement same interface, order matters\n                ?? GetUnresolvedDiagnoser<TDiagnoser>();\n\n        internal static IDiagnoser GetImplementation<TDiagnoser>(Predicate<TDiagnoser> filter) where TDiagnoser : IDiagnoser\n            => LazyLoadedDiagnosers.Value\n                    .FirstOrDefault(diagnoser => diagnoser is TDiagnoser typed && filter(typed)) // few diagnosers can implement same interface, order matters\n               ?? GetUnresolvedDiagnoser<TDiagnoser>();\n\n        private static IDiagnoser GetUnresolvedDiagnoser<TDiagnoser>() => new UnresolvedDiagnoser(typeof(TDiagnoser));\n\n        private static IEnumerable<IDiagnoser> LoadDiagnosers()\n        {\n            yield return MemoryDiagnoser.Default;\n            yield return new DisassemblyDiagnoser(new DisassemblyDiagnoserConfig());\n\n            if (RuntimeInformation.IsNetCore)\n            {\n                yield return EventPipeProfiler.Default;\n\n                if (OsDetector.IsLinux())\n                    yield return PerfCollectProfiler.Default;\n            }\n\n            if (!OsDetector.IsWindows())\n                yield break;\n\n            foreach (var windowsDiagnoser in LoadWindowsDiagnosers())\n                yield return windowsDiagnoser;\n        }\n\n        private static IDiagnoser[] LoadWindowsDiagnosers()\n        {\n            try\n            {\n                var benchmarkDotNetAssembly = typeof(DefaultConfig).GetTypeInfo().Assembly;\n\n                var diagnosticsAssembly = Assembly.Load(new AssemblyName(WindowsDiagnosticAssemblyName));\n\n                if (diagnosticsAssembly.GetName().Version != benchmarkDotNetAssembly.GetName().Version)\n                {\n                    string errorMsg =\n                        $\"Unable to load: {WindowsDiagnosticAssemblyFileName} version {diagnosticsAssembly.GetName().Version}\" +\n                        Environment.NewLine +\n                        $\"Does not match: {Path.GetFileName(benchmarkDotNetAssembly.Location)} version {benchmarkDotNetAssembly.GetName().Version}\";\n                    ConsoleLogger.Default.WriteLineError(errorMsg);\n\n                    return [];\n                }\n\n                return\n                [\n                    CreateDiagnoser(diagnosticsAssembly, \"BenchmarkDotNet.Diagnostics.Windows.InliningDiagnoser\"),\n                    CreateDiagnoser(diagnosticsAssembly, \"BenchmarkDotNet.Diagnostics.Windows.TailCallDiagnoser\"),\n                    CreateDiagnoser(diagnosticsAssembly, \"BenchmarkDotNet.Diagnostics.Windows.JitStatsDiagnoser\"),\n                    CreateDiagnoser(diagnosticsAssembly, \"BenchmarkDotNet.Diagnostics.Windows.EtwProfiler\"),\n                    CreateDiagnoser(diagnosticsAssembly, \"BenchmarkDotNet.Diagnostics.Windows.ConcurrencyVisualizerProfiler\"),\n                    CreateDiagnoser(diagnosticsAssembly, \"BenchmarkDotNet.Diagnostics.Windows.NativeMemoryProfiler\")\n                ];\n            }\n            catch (Exception ex) when (ex is FileNotFoundException || ex is BadImageFormatException)\n            {\n                // Return an array of UnresolvedDiagnoser objects when the assembly does not contain the requested diagnoser\n                return [GetUnresolvedDiagnoser<IDiagnoser>()];\n            }\n            catch (Exception ex) // we're loading a plug-in, better to be safe rather than sorry\n            {\n                ConsoleLogger.Default.WriteLineError($\"Error loading {WindowsDiagnosticAssemblyFileName}: {ex.GetType().Name} - {ex.Message}\");\n\n                return [];\n            }\n        }\n\n        private static IDiagnoser CreateDiagnoser(Assembly loadedAssembly, string typeName)\n            => (IDiagnoser)Activator.CreateInstance(loadedAssembly.GetType(typeName)!)!;\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Diagnosers/EventPipeProfile.cs",
    "content": "﻿namespace BenchmarkDotNet.Diagnosers\n{\n    public enum EventPipeProfile\n    {\n        /// <summary>\n        /// Useful for tracking CPU usage and general .NET runtime information.\n        /// This is the default option if no profile or providers are specified.\n        /// </summary>\n        CpuSampling,\n        /// <summary>\n        /// Tracks GC collections and samples object allocations.\n        /// </summary>\n        GcVerbose,\n        /// <summary>\n        /// Tracks GC collections only at very low overhead.\n        /// </summary>\n        GcCollect,\n        /// <summary>\n        /// Logging when Just in time (JIT) compilation occurs.\n        /// Logging of the internal workings of the Just In Time compiler. This is fairly verbose.\n        /// It details decisions about interesting optimization (like inlining and tail call)\n        /// </summary>\n        Jit\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Diagnosers/EventPipeProfileMapper.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Diagnostics.Tracing;\nusing Microsoft.Diagnostics.NETCore.Client;\nusing Microsoft.Diagnostics.Tracing.Parsers;\n\nnamespace BenchmarkDotNet.Diagnosers\n{\n    internal sealed class EventPipeProfileMapper\n    {\n        private const string DotNetRuntimeProviderName = \"Microsoft-Windows-DotNETRuntime\";\n\n        internal static IReadOnlyDictionary<EventPipeProfile, IReadOnlyList<EventPipeProvider>> DotNetRuntimeProfiles { get; } = new Dictionary<EventPipeProfile, IReadOnlyList<EventPipeProvider>>\n        {\n            { EventPipeProfile.CpuSampling,\n                new[]\n                {\n                    new EventPipeProvider(\"Microsoft-DotNETCore-SampleProfiler\", EventLevel.Informational),\n                    new EventPipeProvider(DotNetRuntimeProviderName, EventLevel.Informational, (long) ClrTraceEventParser.Keywords.Default)\n                }},\n            { EventPipeProfile.GcVerbose,\n                new[]\n                {\n                    new EventPipeProvider(\n                        name: DotNetRuntimeProviderName,\n                        eventLevel: EventLevel.Verbose,\n                        keywords: (long) ClrTraceEventParser.Keywords.GC |\n                                  (long) ClrTraceEventParser.Keywords.GCHandle |\n                                  (long) ClrTraceEventParser.Keywords.Exception\n                    ),\n                }},\n            { EventPipeProfile.GcCollect,\n                new[]\n                {\n                    new EventPipeProvider(\n                        name: DotNetRuntimeProviderName,\n                        eventLevel: EventLevel.Informational,\n                        keywords: (long) ClrTraceEventParser.Keywords.GC |\n                                  (long) ClrTraceEventParser.Keywords.Exception\n                    )\n                }},\n            { EventPipeProfile.Jit,\n                new[]\n                {\n                    new EventPipeProvider(\n                        name: DotNetRuntimeProviderName,\n                        eventLevel: EventLevel.Verbose,\n                        keywords: (long) ClrTraceEventParser.Keywords.Jit |\n                                  (long) ClrTraceEventParser.Keywords.JitTracing |\n                                  (long) ClrTraceEventParser.Keywords.Exception\n                    )\n                }},\n        };\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Diagnosers/EventPipeProfiler.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Collections.Immutable;\nusing System.Diagnostics.Tracing;\nusing System.IO;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing BenchmarkDotNet.Analysers;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Exporters;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Helpers;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Validators;\nusing Microsoft.Diagnostics.NETCore.Client;\n\nnamespace BenchmarkDotNet.Diagnosers\n{\n    public class EventPipeProfiler : IProfiler\n    {\n        public static readonly EventPipeProfiler Default = new EventPipeProfiler();\n\n        private readonly Dictionary<BenchmarkCase, string> benchmarkToTraceFile = [];\n        private readonly ImmutableHashSet<EventPipeProvider> eventPipeProviders;\n        private readonly bool performExtraBenchmarksRun;\n\n        private Task collectingTask = default!;\n\n        // parameterless constructor required by DiagnosersLoader to support creating this profiler via console line args\n        // we use performExtraBenchmarksRun = false for better first user experience\n        public EventPipeProfiler() : this(profile: EventPipeProfile.CpuSampling, performExtraBenchmarksRun: false) { }\n\n        /// <summary>\n        /// Creates a new instance of EventPipeProfiler\n        /// </summary>\n        /// <param name=\"profile\">A named pre-defined set of provider configurations that allows common tracing scenarios to be specified succinctly.</param>\n        /// <param name=\"providers\">A list of EventPipe providers to be enabled.</param>\n        /// <param name=\"performExtraBenchmarksRun\">if set to true, benchmarks will be executed one more time with the profiler attached. If set to false, there will be no extra run but the results will contain overhead. True by default.</param>\n        public EventPipeProfiler(EventPipeProfile profile = EventPipeProfile.CpuSampling, IReadOnlyCollection<EventPipeProvider>? providers = null, bool performExtraBenchmarksRun = true)\n        {\n            this.performExtraBenchmarksRun = performExtraBenchmarksRun;\n            eventPipeProviders = MapToProviders(profile, providers);\n        }\n\n        public string ShortName => \"EP\";\n\n        public IEnumerable<string> Ids => [nameof(EventPipeProfiler)];\n\n        public IEnumerable<IExporter> Exporters => [];\n\n        public IEnumerable<IAnalyser> Analysers => [];\n\n        public RunMode GetRunMode(BenchmarkCase benchmarkCase) => performExtraBenchmarksRun ? RunMode.ExtraRun : RunMode.NoOverhead;\n\n        public IEnumerable<ValidationError> Validate(ValidationParameters validationParameters)\n        {\n            foreach (var benchmark in validationParameters.Benchmarks)\n            {\n                var runtime = benchmark.Job.ResolveValue(EnvironmentMode.RuntimeCharacteristic, EnvironmentResolver.Instance)!;\n\n                if (runtime.RuntimeMoniker < RuntimeMoniker.NetCoreApp30)\n                {\n                    yield return new ValidationError(true, $\"{nameof(EventPipeProfiler)} supports only .NET Core 3.0+\", benchmark);\n                }\n            }\n        }\n\n        public void Handle(HostSignal signal, DiagnoserActionParameters parameters)\n        {\n            if (signal != HostSignal.BeforeAnythingElse)\n                return;\n\n            var diagnosticsClient = new DiagnosticsClient(parameters.ProcessId);\n\n            EventPipeSession session = diagnosticsClient.StartEventPipeSession(eventPipeProviders, true);\n\n            var fileName = ArtifactFileNameHelper.GetTraceFilePath(parameters, DateTime.Now, \"nettrace\").EnsureFolderExists();\n            benchmarkToTraceFile[parameters.BenchmarkCase] = fileName;\n\n            collectingTask = Task.Run(() => CopyEventStreamToFile(session, fileName, parameters.Config.GetCompositeLogger()));\n        }\n\n        private static void CopyEventStreamToFile(EventPipeSession session, string fileName, ILogger logger)\n        {\n            try\n            {\n                using (session)\n                using (var fs = new FileStream(fileName, FileMode.Create, FileAccess.Write))\n                {\n                    byte[] buffer = new byte[16 * 1024];\n                    int bytesRead = 0;\n\n                    while ((bytesRead = session.EventStream.Read(buffer, 0, buffer.Length)) > 0)\n                    {\n                        fs.Write(buffer, 0, bytesRead);\n                    }\n\n                    fs.Flush();\n                }\n            }\n            catch (Exception ex)\n            {\n                logger.WriteLine(LogKind.Error, $\"An exception occurred during reading trace stream: {ex}\");\n            }\n        }\n\n        public IEnumerable<Metric> ProcessResults(DiagnoserResults results)\n        {\n            Task.WaitAll(collectingTask);\n\n            if (benchmarkToTraceFile.TryGetValue(results.BenchmarkCase, out var traceFilePath))\n                benchmarkToTraceFile[results.BenchmarkCase] = SpeedScopeExporter.Convert(traceFilePath, results.BenchmarkCase.Config.GetCompositeLogger());\n\n            return [];\n        }\n\n        public void DisplayResults(ILogger resultLogger)\n        {\n            if (!benchmarkToTraceFile.Any())\n                return;\n\n            resultLogger.WriteLineInfo($\"Exported {benchmarkToTraceFile.Count} trace file(s). Example:\");\n            resultLogger.WriteLineInfo(benchmarkToTraceFile.Values.First());\n        }\n\n        internal static ImmutableHashSet<EventPipeProvider> MapToProviders(EventPipeProfile profile, IReadOnlyCollection<EventPipeProvider>? providers)\n        {\n            var uniqueProviders = ImmutableHashSet.CreateBuilder<EventPipeProvider>(EventPipeProviderEqualityComparer.Instance);\n\n            if (providers != null)\n            {\n                foreach (var userProvidedProfile in providers)\n                {\n                    uniqueProviders.Add(userProvidedProfile);\n                }\n            }\n\n            var selectedProfile = EventPipeProfileMapper.DotNetRuntimeProfiles[profile];\n            foreach (var provider in selectedProfile)\n            {\n                uniqueProviders.Add(provider);\n            }\n\n            // mandatory provider to enable Engine events\n            uniqueProviders.Add(new EventPipeProvider(EngineEventSource.SourceName, EventLevel.Informational, long.MaxValue));\n            return uniqueProviders.ToImmutable();\n        }\n\n        private sealed class EventPipeProviderEqualityComparer : IEqualityComparer<EventPipeProvider>\n        {\n            internal static readonly IEqualityComparer<EventPipeProvider> Instance = new EventPipeProviderEqualityComparer();\n\n            public bool Equals(EventPipeProvider? x, EventPipeProvider? y)\n            {\n                if (ReferenceEquals(x, y))\n                    return true;\n\n                if (x is null || y is null)\n                    return false;\n\n                return x.Name.Equals(y.Name);\n            }\n\n            public int GetHashCode(EventPipeProvider obj) => obj.Name.GetHashCode();\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Diagnosers/ExceptionDiagnoser.cs",
    "content": "﻿using BenchmarkDotNet.Analysers;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Columns;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Exporters;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Portability;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Validators;\nusing JetBrains.Annotations;\nusing System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Linq;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.ExceptionServices;\nusing System.Threading;\n\nnamespace BenchmarkDotNet.Diagnosers\n{\n    public class ExceptionDiagnoser(ExceptionDiagnoserConfig config) : IInProcessDiagnoser\n    {\n        public static readonly ExceptionDiagnoser Default = new(new ExceptionDiagnoserConfig(displayExceptionsIfZeroValue: true));\n\n        private readonly Dictionary<BenchmarkCase, long> results = [];\n\n        public ExceptionDiagnoserConfig Config { get; } = config;\n\n        public IEnumerable<string> Ids => [nameof(ExceptionDiagnoser)];\n\n        public IEnumerable<IExporter> Exporters => [];\n\n        public IEnumerable<IAnalyser> Analysers => [];\n\n        public void DisplayResults(ILogger logger) { }\n\n        public RunMode GetRunMode(BenchmarkCase benchmarkCase) => RunMode.ExtraIteration;\n\n        [MethodImpl(CodeGenHelper.AggressiveOptimizationOption)]\n        public void Handle(HostSignal signal, DiagnoserActionParameters parameters) { }\n\n        public IEnumerable<Metric> ProcessResults(DiagnoserResults diagnoserResults)\n        {\n            if (results.TryGetValue(diagnoserResults.BenchmarkCase, out var exceptionsCount))\n            {\n                double totalOperations = diagnoserResults.Measurements.First(m => m.IterationStage == IterationStage.Extra).Operations;\n                yield return new Metric(new ExceptionsFrequencyMetricDescriptor(Config), exceptionsCount / totalOperations);\n            }\n        }\n\n        public IEnumerable<ValidationError> Validate(ValidationParameters validationParameters) => [];\n\n        void IInProcessDiagnoser.DeserializeResults(BenchmarkCase benchmarkCase, string serializedResults)\n            => results.Add(benchmarkCase, long.Parse(serializedResults));\n\n        InProcessDiagnoserHandlerData IInProcessDiagnoser.GetHandlerData(BenchmarkCase benchmarkCase)\n            => new(typeof(ExceptionDiagnoserInProcessHandler), null);\n\n        internal class ExceptionsFrequencyMetricDescriptor(ExceptionDiagnoserConfig config) : IMetricDescriptor\n        {\n            public string Id => \"ExceptionFrequency\";\n            public string DisplayName => Column.Exceptions;\n            public string Legend => \"Exceptions thrown per single operation\";\n            public string NumberFormat => \"#0.0000\";\n            public UnitType UnitType => UnitType.Dimensionless;\n            public string Unit => \"Count\";\n            public bool TheGreaterTheBetter => false;\n            public int PriorityInCategory => 0;\n            public bool GetIsAvailable(Metric metric)\n                => config?.DisplayExceptionsIfZeroValue == true || metric.Value > 0;\n        }\n    }\n\n    [UsedImplicitly]\n    [EditorBrowsable(EditorBrowsableState.Never)]\n    public sealed class ExceptionDiagnoserInProcessHandler : IInProcessDiagnoserHandler\n    {\n        private long exceptionsCount;\n\n        [MethodImpl(CodeGenHelper.AggressiveOptimizationOption)]\n        void IInProcessDiagnoserHandler.Handle(BenchmarkSignal signal, InProcessDiagnoserActionArgs args)\n        {\n            switch (signal)\n            {\n                case BenchmarkSignal.BeforeExtraIteration:\n                    AppDomain.CurrentDomain.FirstChanceException += OnFirstChanceException;\n                    break;\n                case BenchmarkSignal.AfterExtraIteration:\n                    AppDomain.CurrentDomain.FirstChanceException -= OnFirstChanceException;\n                    break;\n            }\n        }\n\n        void IInProcessDiagnoserHandler.Initialize(string? serializedConfig) { }\n\n        string IInProcessDiagnoserHandler.SerializeResults()\n            => exceptionsCount.ToString();\n\n        [MethodImpl(CodeGenHelper.AggressiveOptimizationOption)]\n        private void OnFirstChanceException(object? sender, FirstChanceExceptionEventArgs e)\n        {\n            Interlocked.Increment(ref exceptionsCount);\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Diagnosers/HardwareCounter.cs",
    "content": "﻿using System;\nusing System.Diagnostics.CodeAnalysis;\n\nnamespace BenchmarkDotNet.Diagnosers\n{\n    // initial list is based on counters available for Windows, run `tracelog.exe -profilesources Help` to get the list\n    [SuppressMessage(\"ReSharper\", \"IdentifierTypo\")]\n    public enum HardwareCounter\n    {\n        NotSet = 0,\n        Timer,\n        TotalIssues,\n        BranchInstructions,\n        CacheMisses,\n        BranchMispredictions,\n        TotalCycles,\n        UnhaltedCoreCycles,\n        InstructionRetired,\n        UnhaltedReferenceCycles,\n        LlcReference,\n        LlcMisses,\n        BranchInstructionRetired,\n        BranchMispredictsRetired\n    }\n\n    public static class HardwareCounterExtensions\n    {\n        [SuppressMessage(\"ReSharper\", \"StringLiteralTypo\")]\n        public static string ToShortName(this HardwareCounter hardwareCounter)\n        {\n            switch (hardwareCounter)\n            {\n                case HardwareCounter.Timer:\n                    return \"timer\";\n                case HardwareCounter.TotalIssues:\n                    return \"issues\";\n                case HardwareCounter.BranchInstructions:\n                    return \"branch\";\n                case HardwareCounter.CacheMisses:\n                    return \"miss\";\n                case HardwareCounter.BranchMispredictions:\n                    return \"mispred\";\n                case HardwareCounter.TotalCycles:\n                    return \"cycles\";\n                case HardwareCounter.UnhaltedCoreCycles:\n                    return \"unCoreCycles\";\n                case HardwareCounter.InstructionRetired:\n                    return \"retired\";\n                case HardwareCounter.UnhaltedReferenceCycles:\n                    return \"unRefCycles\";\n                case HardwareCounter.LlcReference:\n                    return \"llcRef\";\n                case HardwareCounter.LlcMisses:\n                    return \"llcMiss\";\n                case HardwareCounter.BranchInstructionRetired:\n                    return \"branchInst\";\n                case HardwareCounter.BranchMispredictsRetired:\n                    return \"branchMisp\";\n                default:\n                    throw new NotSupportedException($\"{hardwareCounter} has no short name mapping\");\n            }\n        }\n\n        public static bool TheGreaterTheBetter(this HardwareCounter hardwareCounter)\n        {\n            // this method could be just a return false as of today but we want to make sure that when we add new counter it's added here on purpose!\n            switch (hardwareCounter)\n            {\n                case HardwareCounter.Timer:\n                case HardwareCounter.TotalIssues:\n                case HardwareCounter.BranchInstructions:\n                case HardwareCounter.CacheMisses:\n                case HardwareCounter.BranchMispredictions:\n                case HardwareCounter.TotalCycles:\n                case HardwareCounter.UnhaltedCoreCycles:\n                case HardwareCounter.InstructionRetired:\n                case HardwareCounter.UnhaltedReferenceCycles:\n                case HardwareCounter.LlcReference:\n                case HardwareCounter.LlcMisses:\n                case HardwareCounter.BranchInstructionRetired:\n                case HardwareCounter.BranchMispredictsRetired:\n                    return false;\n                default:\n                    throw new NotSupportedException($\"{hardwareCounter} has no TheGreaterTheBetter mapping\");\n            }\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Diagnosers/IDiagnoser.cs",
    "content": "﻿using System.Collections.Generic;\nusing BenchmarkDotNet.Analysers;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Exporters;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Validators;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Diagnosers\n{\n    public interface IDiagnoser\n    {\n        IEnumerable<string> Ids { get; }\n\n        IEnumerable<IExporter> Exporters { get; }\n\n        IEnumerable<IAnalyser> Analysers { get; }\n\n        RunMode GetRunMode(BenchmarkCase benchmarkCase);\n\n        void Handle(HostSignal signal, DiagnoserActionParameters parameters);\n\n        IEnumerable<Metric> ProcessResults(DiagnoserResults results);\n\n        void DisplayResults(ILogger logger);\n\n        IEnumerable<ValidationError> Validate(ValidationParameters validationParameters);\n    }\n\n    public interface IConfigurableDiagnoser<in TConfig> : IDiagnoser\n    {\n        [PublicAPI] IConfigurableDiagnoser<TConfig> Configure(TConfig config);\n    }\n\n    /// <summary>\n    /// Represents a diagnoser that will be handled in the same process as the benchmarks.\n    /// </summary>\n    public interface IInProcessDiagnoser : IDiagnoser\n    {\n        /// <summary>\n        /// Gets the data used to construct the <see cref=\"IInProcessDiagnoserHandler\"/> that will run in the benchmark process.\n        /// </summary>\n        /// <remarks>\n        /// The <see cref=\"InProcessDiagnoserHandlerData.HandlerType\"/> must implement <see cref=\"IInProcessDiagnoserHandler\"/> and have a publicly accessible default constructor.\n        /// <para/>\n        /// Return <see langword=\"default\"/> to not run the diagnoser handler for the <paramref name=\"benchmarkCase\"/>.\n        /// </remarks>\n        InProcessDiagnoserHandlerData GetHandlerData(BenchmarkCase benchmarkCase);\n\n        /// <summary>\n        /// Deserializes the results of the handler.\n        /// </summary>\n        void DeserializeResults(BenchmarkCase benchmarkCase, string serializedResults);\n    }\n\n    /// <summary>\n    /// Represents a handler for an <see cref=\"IInProcessDiagnoser\"/>.\n    /// </summary>\n    public interface IInProcessDiagnoserHandler\n    {\n        /// <summary>\n        /// Initializes the handler with the serialized config from the host <see cref=\"IInProcessDiagnoser\"/>.\n        /// </summary>\n        void Initialize(string? serializedConfig);\n\n        /// <summary>\n        /// Handles the signal from the benchmark.\n        /// </summary>\n        void Handle(BenchmarkSignal signal, InProcessDiagnoserActionArgs args);\n\n        /// <summary>\n        /// Serializes the results to be sent back to the host <see cref=\"IInProcessDiagnoser\"/>.\n        /// </summary>\n        string SerializeResults();\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Diagnosers/IHardwareCounterDiagnoser.cs",
    "content": "﻿using System.Collections.Generic;\nusing BenchmarkDotNet.Running;\n\nnamespace BenchmarkDotNet.Diagnosers\n{\n    internal interface IHardwareCountersDiagnoser : IDiagnoser\n    {\n        IReadOnlyDictionary<BenchmarkCase, PmcStats> Results { get; }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Diagnosers/IProfiler.cs",
    "content": "﻿namespace BenchmarkDotNet.Diagnosers\n{\n    internal interface IProfiler : IDiagnoser\n    {\n        string ShortName { get; }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Diagnosers/InProcessDiagnoserActionParameters.cs",
    "content": "﻿namespace BenchmarkDotNet.Diagnosers;\n\npublic class InProcessDiagnoserActionArgs(object benchmarkInstance)\n{\n    public object BenchmarkInstance { get; } = benchmarkInstance;\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Diagnosers/InProcessDiagnoserHandlerData.cs",
    "content": "﻿using System;\nusing System.Diagnostics.CodeAnalysis;\n\nnamespace BenchmarkDotNet.Diagnosers;\n\n/// <summary>\n/// The data used to construct the <see cref=\"IInProcessDiagnoserHandler\"/> in the benchmark process.\n/// </summary>\n/// <param name=\"handlerType\">The type of the <see cref=\"IInProcessDiagnoserHandler\"/>.</param>\n/// <param name=\"serializedConfig\">The serialized config that will be passed to <see cref=\"IInProcessDiagnoserHandler.Initialize(string?)\"/>.</param>\npublic readonly struct InProcessDiagnoserHandlerData(\n    [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]\n    Type? handlerType,\n    string? serializedConfig)\n{\n    /// <summary>\n    /// The type of the <see cref=\"IInProcessDiagnoserHandler\"/>. If <see langword=\"null\"/>, the handler will not be created.\n    /// </summary>\n    /// <remarks>\n    /// The type must implement <see cref=\"IInProcessDiagnoserHandler\"/> and have a publicly accessible default constructor.\n    /// <para/>\n    /// </remarks>\n    [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]\n    public Type? HandlerType { get; } = handlerType;\n\n    /// <summary>\n    /// The serialized config that will be passed to <see cref=\"IInProcessDiagnoserHandler.Initialize(string?)\"/>.\n    /// </summary>\n    public string? SerializedConfig { get; } = serializedConfig;\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Diagnosers/InProcessDiagnoserRouter.cs",
    "content": "﻿using BenchmarkDotNet.Portability;\nusing BenchmarkDotNet.Running;\nusing JetBrains.Annotations;\nusing System;\nusing System.ComponentModel;\nusing System.Runtime.CompilerServices;\n\nnamespace BenchmarkDotNet.Diagnosers;\n\n[UsedImplicitly]\n[EditorBrowsable(EditorBrowsableState.Never)]\npublic struct InProcessDiagnoserRouter\n{\n    public IInProcessDiagnoserHandler handler;\n    public int index;\n    public RunMode runMode;\n\n    public static IInProcessDiagnoserHandler Init(IInProcessDiagnoserHandler handler, string serializedConfig)\n    {\n        handler.Initialize(serializedConfig);\n        return handler;\n    }\n\n    internal static InProcessDiagnoserRouter Create(IInProcessDiagnoser diagnoser, BenchmarkCase benchmarkCase, int index)\n    {\n        var data = diagnoser.GetHandlerData(benchmarkCase);\n        if (data.HandlerType is null)\n        {\n            return default;\n        }\n        return new()\n        {\n            handler = Init((IInProcessDiagnoserHandler) Activator.CreateInstance(data.HandlerType)!, data.SerializedConfig!),\n            index = index,\n            runMode = diagnoser.GetRunMode(benchmarkCase)\n        };\n    }\n\n    [MethodImpl(CodeGenHelper.AggressiveOptimizationOption)]\n    internal readonly bool ShouldHandle(RunMode runMode)\n        => this.runMode == runMode\n        // ExtraIteration is merged with NoOverhead, so we need to check it explicitly.\n        || (runMode == RunMode.NoOverhead && this.runMode == RunMode.ExtraIteration);\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Diagnosers/MemoryDiagnoser.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing BenchmarkDotNet.Analysers;\nusing BenchmarkDotNet.Columns;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Exporters;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Validators;\n\nnamespace BenchmarkDotNet.Diagnosers\n{\n    public class MemoryDiagnoser : IDiagnoser\n    {\n        private const string DiagnoserId = nameof(MemoryDiagnoser);\n\n        public static readonly MemoryDiagnoser Default = new MemoryDiagnoser(new MemoryDiagnoserConfig(displayGenColumns: true));\n\n        public MemoryDiagnoser(MemoryDiagnoserConfig config) => Config = config;\n\n        public MemoryDiagnoserConfig Config { get; }\n\n        public RunMode GetRunMode(BenchmarkCase benchmarkCase) => RunMode.NoOverhead;\n\n        public IEnumerable<string> Ids => [DiagnoserId];\n        public IEnumerable<IExporter> Exporters => [];\n        public IEnumerable<IAnalyser> Analysers => [];\n        public void DisplayResults(ILogger logger) { }\n        public IEnumerable<ValidationError> Validate(ValidationParameters validationParameters) => [];\n\n        // the action takes places in other process, and the values are gathered by Engine\n        public void Handle(HostSignal signal, DiagnoserActionParameters parameters) { }\n\n        public IEnumerable<Metric> ProcessResults(DiagnoserResults diagnoserResults)\n        {\n            if (Config.DisplayGenColumns)\n            {\n                yield return new Metric(GarbageCollectionsMetricDescriptor.Gen0, diagnoserResults.GcStats.Gen0Collections / (double) diagnoserResults.GcStats.TotalOperations * 1000);\n                yield return new Metric(GarbageCollectionsMetricDescriptor.Gen1, diagnoserResults.GcStats.Gen1Collections / (double) diagnoserResults.GcStats.TotalOperations * 1000);\n                yield return new Metric(GarbageCollectionsMetricDescriptor.Gen2, diagnoserResults.GcStats.Gen2Collections / (double) diagnoserResults.GcStats.TotalOperations * 1000);\n            }\n\n            yield return new Metric(AllocatedMemoryMetricDescriptor.Instance, diagnoserResults.GcStats.GetBytesAllocatedPerOperation(diagnoserResults.BenchmarkCase) ?? double.NaN);\n        }\n\n        private class GarbageCollectionsMetricDescriptor : IMetricDescriptor\n        {\n            internal static readonly IMetricDescriptor Gen0 = new GarbageCollectionsMetricDescriptor(0, Column.Gen0);\n            internal static readonly IMetricDescriptor Gen1 = new GarbageCollectionsMetricDescriptor(1, Column.Gen1);\n            internal static readonly IMetricDescriptor Gen2 = new GarbageCollectionsMetricDescriptor(2, Column.Gen2);\n\n            private GarbageCollectionsMetricDescriptor(int generationId, string columnName)\n            {\n                Id = $\"Gen{generationId}Collects\";\n                DisplayName = columnName;\n                Legend = $\"GC Generation {generationId} collects per 1000 operations\";\n                PriorityInCategory = generationId;\n            }\n\n            public string Id { get; }\n            public string DisplayName { get; }\n            public string Legend { get; }\n            public string NumberFormat => \"#0.0000\";\n            public UnitType UnitType => UnitType.Dimensionless;\n            public string Unit => \"Count\";\n            public bool TheGreaterTheBetter => false;\n            public int PriorityInCategory { get; }\n            public bool GetIsAvailable(Metric metric) => metric.Value > 0;\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Diagnosers/MemoryDiagnoserConfig.cs",
    "content": "﻿using JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Diagnosers\n{\n    public class MemoryDiagnoserConfig\n    {\n        /// <param name=\"displayGenColumns\">Display Garbage Collections per Generation columns (Gen 0, Gen 1, Gen 2). True by default.</param>\n        [PublicAPI]\n        public MemoryDiagnoserConfig(bool displayGenColumns = true)\n        {\n            DisplayGenColumns = displayGenColumns;\n        }\n\n        public bool DisplayGenColumns { get; }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Diagnosers/PerfCollectProfiler.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.IO;\nusing System.Linq;\nusing System.Runtime.InteropServices;\nusing BenchmarkDotNet.Analysers;\nusing BenchmarkDotNet.Detectors;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Exporters;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Helpers;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Portability;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Toolchains;\nusing BenchmarkDotNet.Toolchains.CoreRun;\nusing BenchmarkDotNet.Toolchains.CsProj;\nusing BenchmarkDotNet.Toolchains.DotNetCli;\nusing BenchmarkDotNet.Toolchains.NativeAot;\nusing BenchmarkDotNet.Toolchains.Results;\nusing BenchmarkDotNet.Validators;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Diagnosers\n{\n    public class PerfCollectProfiler : IProfiler\n    {\n        public static readonly IDiagnoser Default = new PerfCollectProfiler(new PerfCollectProfilerConfig(performExtraBenchmarksRun: false));\n\n        private readonly PerfCollectProfilerConfig config;\n        private readonly DateTime creationTime = DateTime.Now;\n        private readonly Dictionary<BenchmarkCase, FileInfo> benchmarkToTraceFile = [];\n        private readonly HashSet<string> cliPathWithSymbolsInstalled = [];\n        private FileInfo perfCollectFile = default!;\n        private Process perfCollectProcess = default!;\n\n        [PublicAPI]\n        public PerfCollectProfiler(PerfCollectProfilerConfig config) => this.config = config;\n\n        public string ShortName => \"perf\";\n\n        public IEnumerable<string> Ids => [nameof(PerfCollectProfiler)];\n\n        public IEnumerable<IExporter> Exporters => [];\n\n        public IEnumerable<IAnalyser> Analysers => [];\n\n        public IEnumerable<Metric> ProcessResults(DiagnoserResults results) => [];\n\n        public RunMode GetRunMode(BenchmarkCase benchmarkCase) => config.RunMode;\n\n        public IEnumerable<ValidationError> Validate(ValidationParameters validationParameters)\n        {\n            if (!OsDetector.IsLinux())\n            {\n                yield return new ValidationError(true, \"The PerfCollectProfiler works only on Linux!\");\n                yield break;\n            }\n\n            if (libc.getuid() != 0)\n            {\n                yield return new ValidationError(true, \"You must run as root to use PerfCollectProfiler.\");\n                yield break;\n            }\n\n            if (validationParameters.Benchmarks.Any() && !TryInstallPerfCollect(validationParameters))\n            {\n                yield return new ValidationError(true, \"Failed to install perfcollect script. Please follow the instructions from https://github.com/dotnet/runtime/blob/main/docs/project/linux-performance-tracing.md\");\n            }\n        }\n\n        public void DisplayResults(ILogger logger)\n        {\n            if (!benchmarkToTraceFile.Any())\n                return;\n\n            logger.WriteLineInfo($\"Exported {benchmarkToTraceFile.Count} trace file(s). Example:\");\n            logger.WriteLineInfo(benchmarkToTraceFile.Values.First().FullName);\n        }\n\n        public void Handle(HostSignal signal, DiagnoserActionParameters parameters)\n        {\n            if (signal == HostSignal.BeforeProcessStart)\n                perfCollectProcess = StartCollection(parameters);\n            else if (signal == HostSignal.AfterProcessExit)\n                StopCollection(parameters);\n        }\n\n        private bool TryInstallPerfCollect(ValidationParameters validationParameters)\n        {\n            var scriptInstallationDirectory = new DirectoryInfo(validationParameters.Config.ArtifactsPath).CreateIfNotExists();\n\n            perfCollectFile = new FileInfo(Path.Combine(scriptInstallationDirectory.FullName, \"perfcollect\"));\n            if (perfCollectFile.Exists)\n            {\n                return true;\n            }\n\n            var logger = validationParameters.Config.GetCompositeLogger();\n\n            string script = ResourceHelper.LoadTemplate(perfCollectFile.Name);\n            File.WriteAllText(perfCollectFile.FullName, script);\n\n            if (libc.chmod(perfCollectFile.FullName, libc.FilePermissions.S_IXUSR) != 0)\n            {\n                int lastError = Marshal.GetLastWin32Error();\n                logger.WriteError($\"Unable to make perfcollect script an executable, the last error was: {lastError}\");\n            }\n            else\n            {\n                (int exitCode, var output) = ProcessHelper.RunAndReadOutputLineByLine(perfCollectFile.FullName, \"install -force\", perfCollectFile.Directory!.FullName, null, includeErrors: true, logger);\n\n                if (exitCode == 0)\n                {\n                    logger.WriteLine(\"Successfully installed perfcollect\");\n                    return true;\n                }\n\n                logger.WriteLineError(\"Failed to install perfcollect\");\n                foreach (var outputLine in output)\n                {\n                    logger.WriteLine(outputLine);\n                }\n            }\n\n            if (perfCollectFile.Exists)\n            {\n                perfCollectFile.Delete(); // if the file exists it means that perfcollect is installed\n            }\n\n            return false;\n        }\n\n        private Process StartCollection(DiagnoserActionParameters parameters)\n        {\n            EnsureSymbolsForNativeRuntime(parameters);\n\n            var traceName = GetTraceFile(parameters, extension: \"\").Name;\n\n            var start = new ProcessStartInfo\n            {\n                FileName = perfCollectFile.FullName,\n                Arguments = $\"collect \\\"{traceName}\\\"\",\n                UseShellExecute = false,\n                RedirectStandardOutput = true,\n                CreateNoWindow = true,\n                WorkingDirectory = perfCollectFile.Directory!.FullName\n            };\n\n            return Process.Start(start)!;\n        }\n\n        private void StopCollection(DiagnoserActionParameters parameters)\n        {\n            var logger = parameters.Config.GetCompositeLogger();\n\n            try\n            {\n                if (!perfCollectProcess.HasExited)\n                {\n                    if (libc.kill(perfCollectProcess.Id, libc.Signals.SIGINT) != 0)\n                    {\n                        int lastError = Marshal.GetLastWin32Error();\n                        logger.WriteLineError($\"kill(perfcollect, SIGINT) failed with {lastError}\");\n                    }\n\n                    if (!perfCollectProcess.WaitForExit((int)config.Timeout.TotalMilliseconds))\n                    {\n                        logger.WriteLineError($\"The perfcollect script did not stop in {config.Timeout.TotalSeconds}s. It's going to be force killed now.\");\n                        logger.WriteLineInfo(\"You can create PerfCollectProfiler providing PerfCollectProfilerConfig with custom timeout value.\");\n\n                        perfCollectProcess.KillTree(); // kill the entire process tree\n                    }\n\n                    FileInfo traceFile = GetTraceFile(parameters, \"trace.zip\");\n                    if (traceFile.Exists)\n                    {\n                        benchmarkToTraceFile[parameters.BenchmarkCase] = traceFile;\n                    }\n                }\n                else\n                {\n                    logger.WriteLineError(\"For some reason the perfcollect script has finished sooner than expected.\");\n                    logger.WriteLineInfo($\"Please run '{perfCollectFile.FullName} install' as root and re-try.\");\n                }\n            }\n            finally\n            {\n                perfCollectProcess.Dispose();\n            }\n        }\n\n        private void EnsureSymbolsForNativeRuntime(DiagnoserActionParameters parameters)\n        {\n            if (parameters.BenchmarkCase.GetToolchain() is CoreRunToolchain)\n            {\n                return; // it's not needed for a local build of dotnet runtime\n            }\n\n            string cliPath = parameters.BenchmarkCase.GetToolchain() switch\n            {\n                CsProjCoreToolchain core => core.CustomDotNetCliPath,\n                NativeAotToolchain nativeAot => nativeAot.CustomDotNetCliPath,\n                _ => DotNetCliCommandExecutor.DefaultDotNetCliPath.Value\n            };\n\n            if (!cliPathWithSymbolsInstalled.Add(cliPath))\n            {\n                return;\n            }\n\n            string sdkPath = DotNetCliCommandExecutor.GetSdkPath(cliPath); // /usr/share/dotnet/sdk/\n            string dotnetPath = Path.GetDirectoryName(sdkPath)!; // /usr/share/dotnet/\n            string[] missingSymbols = Directory.GetFiles(dotnetPath, \"lib*.so\", SearchOption.AllDirectories)\n                .Where(nativeLibPath => !nativeLibPath.Contains(\"FallbackFolder\") && !File.Exists(Path.ChangeExtension(nativeLibPath, \"so.dbg\")))\n                .Select(x => Path.GetDirectoryName(x)!)\n                .Distinct()\n                .ToArray();\n\n            if (!missingSymbols.Any())\n            {\n                return; // the symbol files are already where we need them!\n            }\n\n            ILogger logger = parameters.Config.GetCompositeLogger();\n            // We install the tool in a dedicated directory in order to always use latest version and avoid issues with broken existing configs.\n            string toolPath = Path.Combine(Path.GetTempPath(), \"BenchmarkDotNet\", \"symbols\");\n            DotNetCliCommand cliCommand = new(\n                cliPath: cliPath,\n                filePath: string.Empty,\n                tfm: string.Empty,\n                arguments: $\"tool install dotnet-symbol --tool-path \\\"{toolPath}\\\"\",\n                generateResult: GenerateResult.Success(ArtifactsPaths.Empty, []),\n                logger: logger,\n                buildPartition: BuildPartition.Empty,\n                environmentVariables: [],\n                timeout: TimeSpan.FromMinutes(3),\n                logOutput: true); // the following commands might take a while and fail, let's log them\n\n            var installResult = DotNetCliCommandExecutor.Execute(cliCommand);\n            if (!installResult.IsSuccess)\n            {\n                logger.WriteError(\"Unable to install dotnet symbol.\");\n                return;\n            }\n\n            DotNetCliCommandExecutor.Execute(cliCommand\n                .WithCliPath(Path.Combine(toolPath, \"dotnet-symbol\"))\n                .WithArguments($\"--recurse-subdirectories --symbols \\\"{dotnetPath}/dotnet\\\" \\\"{dotnetPath}/lib*.so\\\"\"));\n\n            DotNetCliCommandExecutor.Execute(cliCommand.WithArguments($\"tool uninstall dotnet-symbol --tool-path \\\"{toolPath}\\\"\"));\n        }\n\n        private FileInfo GetTraceFile(DiagnoserActionParameters parameters, string extension)\n            => new(ArtifactFileNameHelper.GetTraceFilePath(parameters, creationTime, extension)\n                    .Replace(\" \", \"_\")); // perfcollect does not allow for spaces in the trace file name\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Diagnosers/PerfCollectProfilerConfig.cs",
    "content": "﻿using System;\n\nnamespace BenchmarkDotNet.Diagnosers\n{\n    public class PerfCollectProfilerConfig\n    {\n        /// <param name=\"performExtraBenchmarksRun\">When set to true, benchmarks will be executed one more time with the profiler attached. If set to false, there will be no extra run but the results will contain overhead. False by default.</param>\n        /// <param name=\"timeoutInSeconds\">How long should we wait for the perfcollect script to finish processing the trace. 300s by default.</param>\n        public PerfCollectProfilerConfig(bool performExtraBenchmarksRun = false, int timeoutInSeconds = 300)\n        {\n            RunMode = performExtraBenchmarksRun ? RunMode.ExtraRun : RunMode.NoOverhead;\n            Timeout = TimeSpan.FromSeconds(timeoutInSeconds);\n        }\n\n        public TimeSpan Timeout { get; }\n\n        public RunMode RunMode { get; }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Diagnosers/PmcMetricDescriptor.cs",
    "content": "﻿using BenchmarkDotNet.Columns;\nusing BenchmarkDotNet.Reports;\n\nnamespace BenchmarkDotNet.Diagnosers\n{\n    internal class PmcMetricDescriptor : IMetricDescriptor\n    {\n        internal PmcMetricDescriptor(PreciseMachineCounter counter)\n        {\n            Id = counter.Name;\n            DisplayName = $\"{counter.Name}/Op\";\n            Legend = $\"Hardware counter '{counter.Name}' per single operation\";\n            TheGreaterTheBetter = counter.Counter.TheGreaterTheBetter();\n        }\n\n        public string Id { get; }\n        public string DisplayName { get; }\n        public string Legend { get; }\n        public bool TheGreaterTheBetter { get; }\n        public string NumberFormat => \"N0\";\n        public UnitType UnitType => UnitType.Dimensionless;\n        public string Unit => \"Count\";\n        public int PriorityInCategory => 0;\n        public bool GetIsAvailable(Metric metric) => true;\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Diagnosers/PmcStats.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\n\nnamespace BenchmarkDotNet.Diagnosers\n{\n    public class PmcStats\n    {\n        public long TotalOperations { get; set; }\n        public IReadOnlyDictionary<HardwareCounter, PreciseMachineCounter> Counters { get; }\n        private IReadOnlyDictionary<int, PreciseMachineCounter> CountersByProfileSourceId { get; }\n\n        public PmcStats() { throw new InvalidOperationException(\"should never be used\"); }\n\n        public PmcStats(IReadOnlyCollection<HardwareCounter> hardwareCounters, Func<HardwareCounter, PreciseMachineCounter> factory)\n        {\n            CountersByProfileSourceId = hardwareCounters\n                .Select(factory)\n                .ToDictionary\n                (\n                    counter => counter.ProfileSourceId,\n                    counter => counter\n                );\n            Counters = CountersByProfileSourceId.ToDictionary(c => c.Value.Counter, c => c.Value);\n        }\n\n        internal void Handle(int profileSourceId, ulong instructionPointer)\n        {\n            if (CountersByProfileSourceId.TryGetValue(profileSourceId, out var counter))\n                counter.OnSample(instructionPointer);\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Diagnosers/PreciseMachineCounter.cs",
    "content": "using System.Collections.Generic;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Diagnosers\n{\n#pragma warning disable CS3001, CS3003 // ulong is non CLS-compliant\n    public class PreciseMachineCounter\n    {\n        [PublicAPI] public int ProfileSourceId { get; }\n        [PublicAPI] public string Name { get; }\n        [PublicAPI] public HardwareCounter Counter { get; }\n        [PublicAPI] public int Interval { get; }\n        [PublicAPI] public Dictionary<ulong, ulong> PerInstructionPointer { get; }\n\n        public ulong Count { get; private set; }\n\n        internal PreciseMachineCounter(int profileSourceId, string name, HardwareCounter counter, int interval)\n        {\n            ProfileSourceId = profileSourceId;\n            Name = name;\n            Counter = counter;\n            Interval = interval;\n            PerInstructionPointer = new Dictionary<ulong, ulong>(capacity: 10000);\n        }\n\n        public void OnSample(ulong instructionPointer)\n        {\n            checked // if we ever overflow ulong we need to throw!\n            {\n                Count += (ulong)Interval;\n\n                PerInstructionPointer.TryGetValue(instructionPointer, out ulong currentValue);\n                PerInstructionPointer[instructionPointer] = currentValue + (ulong)Interval;\n            }\n        }\n    }\n#pragma warning restore CS3001 // Argument type is not CLS-compliant\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Diagnosers/RunMode.cs",
    "content": "﻿using JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Diagnosers\n{\n    [UsedImplicitly]\n    public enum RunMode : byte\n    {\n        /// <summary>\n        /// given diagnoser should not be executed for given benchmark\n        /// </summary>\n        None,\n        /// <summary>\n        /// needs extra run of the benchmark\n        /// </summary>\n        ExtraRun,\n        /// <summary>\n        /// needs a single extra iteration of the benchmark\n        /// </summary>\n        ExtraIteration,\n        /// <summary>\n        /// no overhead, can be executed without extra run\n        /// </summary>\n        NoOverhead,\n        /// <summary>\n        /// implements some separate logic, that can be executed at any time\n        /// </summary>\n        SeparateLogic\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Diagnosers/SnapshotProfilerBase.cs",
    "content": "using BenchmarkDotNet.Analysers;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Exporters;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Validators;\nusing System;\nusing System.Collections.Generic;\nusing System.Collections.Immutable;\nusing System.Diagnostics;\nusing System.IO;\nusing System.Linq;\nusing System.Threading;\n\nnamespace BenchmarkDotNet.Diagnosers;\n\npublic abstract class SnapshotProfilerBase : IProfiler\n{\n    public abstract string ShortName { get; }\n\n    protected abstract void InitTool(Progress progress);\n    protected abstract void AttachToCurrentProcess(string snapshotFile);\n    protected abstract void AttachToProcessByPid(int pid, string snapshotFile);\n    protected abstract void TakeSnapshot();\n    protected abstract void Detach();\n\n    protected abstract string CreateSnapshotFilePath(DiagnoserActionParameters parameters);\n    protected abstract string GetRunnerPath();\n    internal abstract bool IsSupported(RuntimeMoniker runtimeMoniker);\n\n    private readonly List<string> snapshotFilePaths = [];\n\n    public IEnumerable<string> Ids => [ShortName];\n    public IEnumerable<IExporter> Exporters => [];\n    public IEnumerable<IAnalyser> Analysers => [];\n\n    public RunMode GetRunMode(BenchmarkCase benchmarkCase) =>\n        IsSupported(benchmarkCase.Job.Environment.GetRuntime().RuntimeMoniker) ? RunMode.ExtraRun : RunMode.None;\n\n    public void Handle(HostSignal signal, DiagnoserActionParameters parameters)\n    {\n        var logger = parameters.Config.GetCompositeLogger();\n        var job = parameters.BenchmarkCase.Job;\n\n        var runtimeMoniker = job.Environment.GetRuntime().RuntimeMoniker;\n        if (!IsSupported(runtimeMoniker))\n        {\n            logger.WriteLineError($\"Runtime '{runtimeMoniker}' is not supported by dotMemory\");\n            return;\n        }\n\n        switch (signal)\n        {\n            case HostSignal.BeforeAnythingElse:\n                Init(logger);\n                break;\n            case HostSignal.BeforeActualRun:\n                string snapshotFilePath = Start(logger, parameters);\n                snapshotFilePaths.Add(snapshotFilePath);\n                break;\n            case HostSignal.AfterActualRun:\n                Stop(logger);\n                break;\n        }\n    }\n\n    public IEnumerable<ValidationError> Validate(ValidationParameters validationParameters)\n    {\n        var runtimeMonikers = validationParameters.Benchmarks.Select(b => b.Job.Environment.GetRuntime().RuntimeMoniker).Distinct();\n        foreach (var runtimeMoniker in runtimeMonikers)\n            if (!IsSupported(runtimeMoniker))\n                yield return new ValidationError(true, $\"Runtime '{runtimeMoniker}' is not supported by dotMemory\");\n    }\n\n    public IEnumerable<Metric> ProcessResults(DiagnoserResults results) => [];\n\n    public void DisplayResults(ILogger logger)\n    {\n        if (snapshotFilePaths.Count != 0)\n        {\n            logger.WriteLineInfo($\"The following {ShortName} snapshots were generated:\");\n            foreach (string snapshotFilePath in snapshotFilePaths)\n                logger.WriteLineInfo($\"* {snapshotFilePath}\");\n        }\n    }\n\n    private void Init(ILogger logger)\n    {\n        logger.WriteLineInfo($\"Ensuring that {ShortName} prerequisite is installed...\");\n        var progress = new Progress(logger, $\"Installing {ShortName}\");\n\n        const int MaxRetries = 5;\n        int retryCount = 0;\n\n    Retry:\n        try\n        {\n            InitTool(progress);\n\n            logger.WriteLineInfo($\"{ShortName} prerequisite is installed\");\n            logger.WriteLineInfo($\"{ShortName} runner path: {GetRunnerPath()}\");\n            return;\n        }\n        catch (OperationCanceledException ex)\n        {\n            logger.WriteLineError(ex.ToString());\n            return;\n        }\n        // Following exceptions are expected to be thrown.\n        // https://github.com/JetBrains/profiler-self-api/blob/02f8410d26c184cb50ddaead6fcce89d7f34517c/JetBrains.Profiler.SelfApi/src/Impl/PrerequisiteBase.cs#L188-L202\n        catch (Exception ex)\n        {\n            if (retryCount >= MaxRetries)\n            {\n                logger.WriteLineError(ex.ToString());\n                return;\n            }\n\n            var delaySeconds = retryCount * retryCount;\n            logger.WriteLineWarning($\"InitTool failed with exception: {ex.Message}\");\n            logger.WriteLineWarning($\"Retry {retryCount + 1}/{MaxRetries}  after {delaySeconds} seconds...\");  // Retry after seconds (0, 1, 4, 9, 16)\n            Thread.Sleep(TimeSpan.FromSeconds(delaySeconds));\n            ++retryCount;\n            goto Retry;\n        }\n    }\n\n    private string Start(ILogger logger, DiagnoserActionParameters parameters)\n    {\n        string snapshotFilePath = CreateSnapshotFilePath(parameters);\n        string? snapshotDirectory = Path.GetDirectoryName(snapshotFilePath);\n        logger.WriteLineInfo($\"Target snapshot file: {snapshotFilePath}\");\n        if (!Directory.Exists(snapshotDirectory) && snapshotDirectory != null)\n        {\n            try\n            {\n                Directory.CreateDirectory(snapshotDirectory);\n            }\n            catch (Exception e)\n            {\n                logger.WriteLineError($\"Failed to create directory: {snapshotDirectory}\");\n                logger.WriteLineError(e.ToString());\n            }\n        }\n\n        try\n        {\n            logger.WriteLineInfo($\"Attaching {ShortName} to the process...\");\n            Attach(parameters, snapshotFilePath);\n            logger.WriteLineInfo($\"{ShortName} is successfully attached\");\n        }\n        catch (Exception e)\n        {\n            logger.WriteLineError(e.ToString());\n            return snapshotFilePath;\n        }\n\n        return snapshotFilePath;\n    }\n\n    private void Stop(ILogger logger)\n    {\n        try\n        {\n            logger.WriteLineInfo($\"Taking {ShortName} snapshot...\");\n            TakeSnapshot();\n            logger.WriteLineInfo($\"{ShortName} snapshot is successfully taken\");\n        }\n        catch (Exception e)\n        {\n            logger.WriteLineError(e.ToString());\n        }\n\n        try\n        {\n            logger.WriteLineInfo($\"Detaching {ShortName} from the process...\");\n            Detach();\n            logger.WriteLineInfo($\"{ShortName} is successfully detached\");\n        }\n        catch (Exception e)\n        {\n            logger.WriteLineError(e.ToString());\n        }\n    }\n\n\n    private void Attach(DiagnoserActionParameters parameters, string snapshotFile)\n    {\n        int pid = parameters.ProcessId;\n        int currentPid = Process.GetCurrentProcess().Id;\n        if (pid != currentPid)\n            AttachToProcessByPid(pid, snapshotFile);\n        else\n            AttachToCurrentProcess(snapshotFile);\n    }\n\n    protected class Progress(ILogger logger, string title) : IProgress<double>\n    {\n        private static readonly TimeSpan ReportInterval = TimeSpan.FromSeconds(0.1);\n\n        private int lastProgress;\n        private Stopwatch? stopwatch;\n\n        public void Report(double value)\n        {\n            int progress = (int)Math.Floor(value);\n            bool needToReport = stopwatch == null ||\n                                (stopwatch != null && stopwatch?.Elapsed > ReportInterval) ||\n                                progress == 100;\n\n            if (lastProgress != progress && needToReport)\n            {\n                logger.WriteLineInfo($\"{title}: {progress}%\");\n                lastProgress = progress;\n                stopwatch = Stopwatch.StartNew();\n            }\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Diagnosers/SpeedScopeExporter.cs",
    "content": "﻿using BenchmarkDotNet.Loggers;\nusing Microsoft.Diagnostics.Symbols;\nusing Microsoft.Diagnostics.Tracing;\nusing Microsoft.Diagnostics.Tracing.Etlx;\nusing Microsoft.Diagnostics.Tracing.Stacks;\nusing Microsoft.Diagnostics.Tracing.Stacks.Formats;\nusing System;\nusing System.IO;\n\nnamespace BenchmarkDotNet.Diagnosers\n{\n    internal static class SpeedScopeExporter\n    {\n        internal static string Convert(string traceFilePath, ILogger logger)\n        {\n            var speedscopeFileName = Path.ChangeExtension(traceFilePath, \"speedscope.json\");\n\n            try\n            {\n                ConvertToSpeedscope(traceFilePath, speedscopeFileName);\n\n                return speedscopeFileName;\n            }\n            // Below comment come from https://github.com/dotnet/diagnostics/blob/2c23d3265dd8f642a8d6cf4bb8a135a5ff8b00c2/src/Tools/dotnet-trace/TraceFileFormatConverter.cs#L42\n            // TODO: On a broken/truncated trace, the exception we get from TraceEvent is a plain System.Exception type because it gets caught and rethrown inside TraceEvent.\n            // We should probably modify TraceEvent to throw a better exception.\n            catch (Exception ex) when (ex.ToString().Contains(\"Read past end of stream.\"))\n            {\n                logger.WriteLine(LogKind.Info,\n                    \"Detected a potentially broken trace. Continuing with best-efforts to convert the trace, but resulting speedscope file may contain broken stacks as a result.\");\n                ConvertToSpeedscope(traceFilePath, speedscopeFileName, true);\n\n                return speedscopeFileName;\n            }\n            catch (Exception ex)\n            {\n                logger.WriteLine(LogKind.Error, $\"An exception occurred during converting {traceFilePath} file to speedscope format: {ex}\");\n\n                return traceFilePath;\n            }\n        }\n\n        // Method copied from https://github.com/dotnet/diagnostics/blob/2c23d3265dd8f642a8d6cf4bb8a135a5ff8b00c2/src/Tools/dotnet-trace/TraceFileFormatConverter.cs#L64\n        private static void ConvertToSpeedscope(string fileToConvert, string outputFilename, bool continueOnError = false)\n        {\n            var etlxFilePath = TraceLog.CreateFromEventPipeDataFile(fileToConvert, null, new TraceLogOptions() { ContinueOnError = continueOnError });\n            using (var symbolReader = new SymbolReader(System.IO.TextWriter.Null) { SymbolPath = SymbolPath.MicrosoftSymbolServerPath })\n            using (var eventLog = new TraceLog(etlxFilePath))\n            {\n                var stackSource = new MutableTraceEventStackSource(eventLog)\n                {\n                    OnlyManagedCodeStacks = true // EventPipe currently only has managed code stacks.\n                };\n\n                var computer = new SampleProfilerThreadTimeComputer(eventLog, symbolReader)\n                {\n                    IncludeEventSourceEvents = false // SpeedScope handles only CPU samples, events are not supported\n                };\n                computer.GenerateThreadTimeStacks(stackSource);\n\n                SpeedScopeStackSourceWriter.WriteStackViewAsJson(stackSource, outputFilename);\n            }\n\n            if (File.Exists(etlxFilePath))\n            {\n                File.Delete(etlxFilePath);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Diagnosers/ThreadingDiagnoser.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Linq;\nusing System.Runtime.CompilerServices;\nusing System.Threading;\nusing BenchmarkDotNet.Analysers;\nusing BenchmarkDotNet.Columns;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Exporters;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Portability;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Validators;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Diagnosers\n{\n    public class ThreadingDiagnoser(ThreadingDiagnoserConfig config) : IInProcessDiagnoser\n    {\n        public static readonly ThreadingDiagnoser Default = new(new ThreadingDiagnoserConfig(displayCompletedWorkItemCountWhenZero: true, displayLockContentionWhenZero: true));\n\n        private readonly Dictionary<BenchmarkCase, (long completedWorkItemCount, long lockContentionCount)> results = [];\n\n        public ThreadingDiagnoserConfig Config { get; } = config;\n\n        public IEnumerable<string> Ids => [nameof(ThreadingDiagnoser)];\n\n        public IEnumerable<IExporter> Exporters => [];\n\n        public IEnumerable<IAnalyser> Analysers => [];\n\n        public void DisplayResults(ILogger logger) { }\n\n        public RunMode GetRunMode(BenchmarkCase benchmarkCase) => RunMode.ExtraIteration;\n\n        [MethodImpl(CodeGenHelper.AggressiveOptimizationOption)]\n        public void Handle(HostSignal signal, DiagnoserActionParameters parameters) { }\n\n        public IEnumerable<Metric> ProcessResults(DiagnoserResults diagnoserResults)\n        {\n            if (results.TryGetValue(diagnoserResults.BenchmarkCase, out var counts))\n            {\n                double totalOperations = diagnoserResults.Measurements.First(m => m.IterationStage == IterationStage.Extra).Operations;\n                yield return new Metric(new CompletedWorkItemCountMetricDescriptor(Config), counts.completedWorkItemCount / totalOperations);\n                yield return new Metric(new LockContentionCountMetricDescriptor(Config), counts.lockContentionCount / totalOperations);\n            }\n        }\n\n        public IEnumerable<ValidationError> Validate(ValidationParameters validationParameters)\n        {\n            foreach (var benchmark in validationParameters.Benchmarks)\n            {\n                var runtime = benchmark.Job.ResolveValue(EnvironmentMode.RuntimeCharacteristic, EnvironmentResolver.Instance);\n\n                if (runtime != null && runtime.RuntimeMoniker < RuntimeMoniker.NetCoreApp30)\n                {\n                    yield return new ValidationError(true, $\"{nameof(ThreadingDiagnoser)} supports only .NET Core 3.0+\", benchmark);\n                }\n            }\n        }\n\n        void IInProcessDiagnoser.DeserializeResults(BenchmarkCase benchmarkCase, string serializedResults)\n        {\n            var splitResults = serializedResults.Split([' '], StringSplitOptions.RemoveEmptyEntries);\n            var completedWorkItemCount = long.Parse(splitResults[0]);\n            var lockContentionCount = long.Parse(splitResults[1]);\n            results.Add(benchmarkCase, (completedWorkItemCount, lockContentionCount));\n        }\n\n        InProcessDiagnoserHandlerData IInProcessDiagnoser.GetHandlerData(BenchmarkCase benchmarkCase)\n            => new(typeof(ThreadingDiagnoserInProcessHandler), null);\n\n        internal class CompletedWorkItemCountMetricDescriptor(ThreadingDiagnoserConfig config) : IMetricDescriptor\n        {\n            public string Id => \"CompletedWorkItemCount\";\n            public string DisplayName => Column.CompletedWorkItems;\n            public string Legend => \"The number of work items that have been processed in ThreadPool (per single operation)\";\n            public string NumberFormat => \"#0.0000\";\n            public UnitType UnitType => UnitType.Dimensionless;\n            public string Unit => \"Count\";\n            public bool TheGreaterTheBetter => false;\n            public int PriorityInCategory => 0;\n            public bool GetIsAvailable(Metric metric)\n                => config?.DisplayCompletedWorkItemCountWhenZero == true || metric.Value > 0;\n        }\n\n        internal class LockContentionCountMetricDescriptor(ThreadingDiagnoserConfig config) : IMetricDescriptor\n        {\n            public string Id => \"LockContentionCount\";\n            public string DisplayName => Column.LockContentions;\n            public string Legend => \"The number of times there was contention upon trying to take a Monitor's lock (per single operation)\";\n            public string NumberFormat => \"#0.0000\";\n            public UnitType UnitType => UnitType.Dimensionless;\n            public string Unit => \"Count\";\n            public bool TheGreaterTheBetter => false;\n            public int PriorityInCategory => 0;\n            public bool GetIsAvailable(Metric metric)\n                => config?.DisplayLockContentionWhenZero == true || metric.Value > 0;\n        }\n    }\n\n    [UsedImplicitly]\n    [EditorBrowsable(EditorBrowsableState.Never)]\n    public sealed class ThreadingDiagnoserInProcessHandler : IInProcessDiagnoserHandler\n    {\n#if NETSTANDARD2_0\n        // BDN targets .NET Standard 2.0, these properties are not part of .NET Standard 2.0, were added in .NET Core 3.0\n        private static readonly Func<long> GetCompletedWorkItemCountDelegate = CreateGetterDelegate(typeof(ThreadPool), nameof(CompletedWorkItemCount));\n        private static readonly Func<long> GetLockContentionCountDelegate = CreateGetterDelegate(typeof(Monitor), nameof(LockContentionCount));\n#endif\n        public long CompletedWorkItemCount { get; set; }\n        public long LockContentionCount { get; set; }\n\n        [MethodImpl(CodeGenHelper.AggressiveOptimizationOption)]\n        void IInProcessDiagnoserHandler.Handle(BenchmarkSignal signal, InProcessDiagnoserActionArgs args)\n        {\n            switch (signal)\n            {\n                case BenchmarkSignal.BeforeExtraIteration:\n                    ReadInitial();\n                    break;\n                case BenchmarkSignal.AfterExtraIteration:\n                    ReadFinal();\n                    break;\n            }\n        }\n\n        void IInProcessDiagnoserHandler.Initialize(string? serializedConfig) { }\n\n        string IInProcessDiagnoserHandler.SerializeResults() => $\"{CompletedWorkItemCount} {LockContentionCount}\";\n\n        [MethodImpl(CodeGenHelper.AggressiveOptimizationOption)]\n        private void ReadInitial()\n        {\n#if NETSTANDARD2_0\n            LockContentionCount = GetLockContentionCountDelegate(); // Monitor.LockContentionCount can schedule a work item and needs to be called before ThreadPool.CompletedWorkItemCount\n            CompletedWorkItemCount = GetCompletedWorkItemCountDelegate();\n#else\n            LockContentionCount = Monitor.LockContentionCount;\n            CompletedWorkItemCount = ThreadPool.CompletedWorkItemCount;\n#endif\n        }\n\n        [MethodImpl(CodeGenHelper.AggressiveOptimizationOption)]\n        private void ReadFinal()\n        {\n#if NETSTANDARD2_0\n            LockContentionCount = GetLockContentionCountDelegate() - LockContentionCount; // Monitor.LockContentionCount can schedule a work item and needs to be called before ThreadPool.CompletedWorkItemCount\n            CompletedWorkItemCount = GetCompletedWorkItemCountDelegate() - CompletedWorkItemCount;\n#else\n            LockContentionCount = Monitor.LockContentionCount - LockContentionCount;\n            CompletedWorkItemCount = ThreadPool.CompletedWorkItemCount - CompletedWorkItemCount;\n#endif\n        }\n\n#if NETSTANDARD2_0\n        private static Func<long> CreateGetterDelegate(Type type, string propertyName)\n        {\n            var property = type.GetProperty(propertyName);\n\n            // we create delegate to avoid boxing, IMPORTANT!\n            return property != null\n                ? (Func<long>) property.GetGetMethod()!.CreateDelegate(typeof(Func<long>))\n                : () => 0;\n        }\n#endif\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Diagnosers/ThreadingDiagnoserConfig.cs",
    "content": "﻿using JetBrains.Annotations;\nusing System;\nusing System.Collections.Generic;\nusing System.Text;\n\nnamespace BenchmarkDotNet.Diagnosers\n{\n    public class ThreadingDiagnoserConfig\n    {\n        /// <param name=\"displayLockContentionWhenZero\">Display configuration for 'LockContentionCount' when it is empty. True (displayed) by default.</param>\n        /// <param name=\"displayCompletedWorkItemCountWhenZero\">Display configuration for 'CompletedWorkItemCount' when it is empty. True (displayed) by default.</param>\n\n        [PublicAPI]\n        public ThreadingDiagnoserConfig(bool displayLockContentionWhenZero = true, bool displayCompletedWorkItemCountWhenZero = true)\n        {\n            DisplayLockContentionWhenZero = displayLockContentionWhenZero;\n            DisplayCompletedWorkItemCountWhenZero = displayCompletedWorkItemCountWhenZero;\n        }\n\n        public bool DisplayLockContentionWhenZero { get; }\n        public bool DisplayCompletedWorkItemCountWhenZero { get; }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Diagnosers/UnresolvedDiagnoser.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing BenchmarkDotNet.Analysers;\nusing BenchmarkDotNet.Detectors;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Exporters;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Portability;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Validators;\n\nnamespace BenchmarkDotNet.Diagnosers\n{\n    public class UnresolvedDiagnoser : IDiagnoser\n    {\n        private readonly Type unresolved;\n\n        public UnresolvedDiagnoser(Type unresolved) => this.unresolved = unresolved;\n\n        public RunMode GetRunMode(BenchmarkCase benchmarkCase) => RunMode.None;\n\n        public IEnumerable<string> Ids => [nameof(UnresolvedDiagnoser)];\n        public IEnumerable<IExporter> Exporters => [];\n        public IEnumerable<IAnalyser> Analysers => [];\n        public void Handle(HostSignal signal, DiagnoserActionParameters parameters) { }\n        public IEnumerable<Metric> ProcessResults(DiagnoserResults _) => [];\n\n        public void DisplayResults(ILogger logger) => logger.WriteLineError(GetErrorMessage());\n\n        public IEnumerable<ValidationError> Validate(ValidationParameters validationParameters)\n            => new[] { new ValidationError(false, GetErrorMessage()) };\n\n        private string GetErrorMessage() => $@\"Unable to resolve {unresolved.Name} diagnoser using dynamic assembly loading. \n            {(RuntimeInformation.IsFullFramework || OsDetector.IsWindows()\n                ? \"Please make sure that you have installed the latest BenchmarkDotNet.Diagnostics.Windows package. \" + Environment.NewLine\n                    + \"If you are using `dotnet build` you also need to consume one of its public types to make sure that MSBuild copies it to the output directory. \"\n                    + \"The alternative is to use `<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>` in your project file.\"\n                : $\"Please make sure that it's supported on {OsDetector.GetOs()}\")}\";\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Disassemblers/Arm64Disassembler.cs",
    "content": "﻿using BenchmarkDotNet.Diagnosers;\nusing Gee.External.Capstone;\nusing Gee.External.Capstone.Arm64;\nusing Microsoft.Diagnostics.Runtime;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\n\nnamespace BenchmarkDotNet.Disassemblers\n{\n    internal struct RegisterValueAccumulator\n    {\n        private enum State\n        {\n            LookingForPattern,\n            ExpectingMovk,\n            ExpectingAdd,\n            LookingForPossibleLdr\n        }\n\n        private State _state;\n        private long _value;\n        private int _expectedMovkShift;\n        private Arm64RegisterId _registerId;\n        private ClrRuntime _runtime;\n\n        public void Init(ClrRuntime runtime)\n        {\n            _state = State.LookingForPattern;\n            _expectedMovkShift = 0;\n            _value = 0;\n            _registerId = Arm64RegisterId.Invalid;\n            _runtime = runtime;\n        }\n\n        public void Feed(Arm64Instruction instruction)\n        {\n            Arm64InstructionDetail details = instruction.Details;\n\n            switch (_state)\n            {\n                case State.LookingForPattern:\n                    if (instruction.Id == Arm64InstructionId.ARM64_INS_MOVZ)\n                    {\n                        _registerId = details.Operands[0].Register.Id;\n                        _value = details.Operands[1].Immediate;\n                        _state = State.ExpectingMovk;\n                        _expectedMovkShift = 16;\n                    }\n                    else if (instruction.Id == Arm64InstructionId.ARM64_INS_ADRP)\n                    {\n                        _registerId = details.Operands[0].Register.Id;\n                        _value = details.Operands[1].Immediate;\n                        _state = State.ExpectingAdd;\n                    }\n                    break;\n                case State.ExpectingMovk:\n                    if (instruction.Id == Arm64InstructionId.ARM64_INS_MOVK &&\n                        details.Operands[0].Register.Id == _registerId &&\n                        details.Operands[1].ShiftOperation == Arm64ShiftOperation.ARM64_SFT_LSL &&\n                        details.Operands[1].ShiftValue == _expectedMovkShift)\n                    {\n                        _value = _value | (instruction.Details.Operands[1].Immediate << details.Operands[1].ShiftValue);\n                        _expectedMovkShift += 16;\n                        break;\n                    }\n                    _state = State.LookingForPossibleLdr;\n                    goto case State.LookingForPossibleLdr;\n                case State.ExpectingAdd:\n                    if (instruction.Id == Arm64InstructionId.ARM64_INS_ADD &&\n                        details.Operands[0].Register.Id == _registerId &&\n                        details.Operands[1].Register.Id == _registerId &&\n                        details.Operands[2].Type == Arm64OperandType.Immediate)\n                    {\n                        _value = _value | instruction.Details.Operands[2].Immediate;\n                        _state = State.LookingForPossibleLdr;\n                    }\n                    break;\n                case State.LookingForPossibleLdr:\n                    if (instruction.Id == Arm64InstructionId.ARM64_INS_LDR &&\n                        details.Operands[1].Type == Arm64OperandType.Memory &&\n                        details.Operands[1].Memory.Base.Id == _registerId && // The source address is in the register we are tracking\n                        details.Operands[1].Memory.Displacement == 0 && // There is no displacement\n                        details.Operands[1].Memory.Index == null) // And there is no extra index register\n                    {\n                        // Simulate the LDR instruction.\n                        long newValue = (long)_runtime.DataTarget.DataReader.ReadPointer((ulong)_value);\n                        _value = newValue;\n                        if (_value == 0)\n                        {\n                            _state = State.LookingForPattern;\n                        }\n                        else\n                        {\n                            // The LDR might have loaded the result in another register\n                            _registerId = details.Operands[0].Register.Id;\n                        }\n                    }\n                    else if (instruction.Id == Arm64InstructionId.ARM64_INS_CBZ ||\n                            instruction.Id == Arm64InstructionId.ARM64_INS_CBNZ ||\n                            instruction.Id == Arm64InstructionId.ARM64_INS_B && details.ConditionCode != Arm64ConditionCode.Invalid)\n                    {\n                        // ignore conditional branches\n                    }\n                    else if (details.BelongsToGroup(Arm64InstructionGroupId.ARM64_GRP_BRANCH_RELATIVE) ||\n                             details.BelongsToGroup(Arm64InstructionGroupId.ARM64_GRP_CALL) ||\n                             details.BelongsToGroup(Arm64InstructionGroupId.ARM64_GRP_JUMP))\n                    {\n                        // We've encountered an unconditional jump or call, the accumulated registers value is not valid anymore\n                        _state = State.LookingForPattern;\n                    }\n                    else if (instruction.Id == Arm64InstructionId.ARM64_INS_MOVZ)\n                    {\n                        // Another constant loading is starting\n                        _state = State.LookingForPattern;\n                        goto case State.LookingForPattern;\n                    }\n                    else\n                    {\n                        // Finally check if the current instruction modified the register that was accumulating the constant\n                        // and reset the state machine in case it did.\n                        foreach (Arm64Register reg in details.AllWrittenRegisters)\n                        {\n                            // Some unexpected instruction overwriting the accumulated register\n                            if (reg.Id == _registerId)\n                            {\n                                _state = State.LookingForPattern;\n                            }\n                        }\n                    }\n                    break;\n            }\n        }\n\n        public bool HasValue => _state == State.ExpectingMovk || _state == State.LookingForPossibleLdr;\n\n        public long Value { get { return _value; } }\n\n        public Arm64RegisterId RegisterId {  get {  return _registerId; } }\n    }\n\n    internal class Arm64Disassembler : ClrMdDisassembler\n    {\n        internal sealed class RuntimeSpecificData\n        {\n            // See dotnet/runtime src/coreclr/vm/arm64/thunktemplates.asm/.S for the stub code\n            // ldr  x9, DATA_SLOT(CallCountingStub, RemainingCallCountCell)\n            // ldrh w10, [x9]\n            // subs w10, w10, #0x1\n            internal readonly byte[] callCountingStubTemplate = [0x09, 0x00, 0x00, 0x58, 0x2a, 0x01, 0x40, 0x79, 0x4a, 0x05, 0x00, 0x71];\n            // ldr x10, DATA_SLOT(StubPrecode, Target)\n            // ldr x12, DATA_SLOT(StubPrecode, MethodDesc)\n            // br x10\n            internal readonly byte[] stubPrecodeTemplate = [0x4a, 0x00, 0x00, 0x58, 0xec, 0x00, 0x00, 0x58, 0x40, 0x01, 0x1f, 0xd6];\n            // ldr x11, DATA_SLOT(FixupPrecode, Target)\n            // br  x11\n            // ldr x12, DATA_SLOT(FixupPrecode, MethodDesc)\n            internal readonly byte[] fixupPrecodeTemplate = [0x0b, 0x00, 0x00, 0x58, 0x60, 0x01, 0x1f, 0xd6, 0x0c, 0x00, 0x00, 0x58];\n            internal readonly ulong stubPageSize;\n\n            internal RuntimeSpecificData(State state)\n            {\n                stubPageSize = (ulong)Environment.SystemPageSize;\n                if (state.RuntimeVersion.Major >= 8)\n                {\n                    // In .NET 8, the stub page size was changed to min 16kB\n                    stubPageSize = Math.Max(stubPageSize, 16384);\n                }\n\n                // The stubs code depends on the current OS memory page size, so we need to update the templates to reflect that\n                ulong pageSizeShifted = stubPageSize / 32;\n                // Calculate the ldr x9, #offset instruction with offset based on the page size\n                callCountingStubTemplate[1] = (byte)(pageSizeShifted & 0xff);\n                callCountingStubTemplate[2] = (byte)(pageSizeShifted >> 8);\n\n                // Calculate the ldr x10, #offset instruction with offset based on the page size\n                stubPrecodeTemplate[1] = (byte)(pageSizeShifted & 0xff);\n                stubPrecodeTemplate[2] = (byte)(pageSizeShifted >> 8);\n                // Calculate the ldr x12, #offset instruction with offset based on the page size\n                stubPrecodeTemplate[5] = (byte)((pageSizeShifted - 1) & 0xff);\n                stubPrecodeTemplate[6] = (byte)((pageSizeShifted - 1) >> 8);\n\n                // Calculate the ldr x11, #offset instruction with offset based on the page size\n                fixupPrecodeTemplate[1] = (byte)(pageSizeShifted & 0xff);\n                fixupPrecodeTemplate[2] = (byte)(pageSizeShifted >> 8);\n                // Calculate the ldr x12, #offset instruction with offset based on the page size\n                fixupPrecodeTemplate[9] = (byte)(pageSizeShifted & 0xff);\n                fixupPrecodeTemplate[10] = (byte)(pageSizeShifted >> 8);\n            }\n        }\n\n        private static readonly Dictionary<Version, RuntimeSpecificData> runtimeSpecificData = [];\n\n        protected override IEnumerable<Asm> Decode(byte[] code, ulong startAddress, State state, int depth, ClrMethod currentMethod, DisassemblySyntax syntax)\n        {\n            if (!runtimeSpecificData.TryGetValue(state.RuntimeVersion, out var data))\n            {\n                runtimeSpecificData.Add(state.RuntimeVersion, data = new RuntimeSpecificData(state));\n            }\n\n            const Arm64DisassembleMode disassembleMode = Arm64DisassembleMode.Arm;\n            using (CapstoneArm64Disassembler disassembler = CapstoneDisassembler.CreateArm64Disassembler(disassembleMode))\n            {\n                // Enables disassemble details, which are disabled by default, to provide more detailed information on\n                // disassembled binary code.\n                disassembler.EnableInstructionDetails = true;\n                disassembler.DisassembleSyntax = Map(syntax);\n                RegisterValueAccumulator accumulator = new RegisterValueAccumulator();\n                accumulator.Init(state.Runtime);\n\n                Arm64Instruction[] instructions = disassembler.Disassemble(code, (long)startAddress);\n                foreach (Arm64Instruction instruction in instructions)\n                {\n                    bool isIndirect = false;\n                    bool isPrestubMD = false;\n\n                    ulong address = 0;\n                    if (TryGetReferencedAddress(instruction, accumulator, (uint)state.Runtime.DataTarget.DataReader.PointerSize, out address, out isIndirect))\n                    {\n                        if (isIndirect && state.RuntimeVersion.Major >= 7)\n                        {\n                            // Check if the target is a known stub\n                            // The stubs are allocated in interleaved code / data pages in memory. The data part of the stub\n                            // is at an address one memory page higher than the code.\n                            byte[] buffer = new byte[12];\n\n                            FlushCachedDataIfNeeded(state.Runtime.DataTarget.DataReader, address, buffer);\n\n                            if (state.Runtime.DataTarget.DataReader.Read(address, buffer) == buffer.Length)\n                            {\n                                if (buffer.SequenceEqual(data.callCountingStubTemplate))\n                                {\n                                    const ulong TargetMethodAddressSlotOffset = 8;\n                                    address = state.Runtime.DataTarget.DataReader.ReadPointer(address + data.stubPageSize + TargetMethodAddressSlotOffset);\n                                }\n                                else if (buffer.SequenceEqual(data.stubPrecodeTemplate))\n                                {\n                                    const ulong MethodDescSlotOffset = 0;\n                                    address = state.Runtime.DataTarget.DataReader.ReadPointer(address + data.stubPageSize + MethodDescSlotOffset);\n                                    isPrestubMD = true;\n                                }\n                                else if (buffer.SequenceEqual(data.fixupPrecodeTemplate))\n                                {\n                                    const ulong MethodDescSlotOffset = 8;\n                                    address = state.Runtime.DataTarget.DataReader.ReadPointer(address + data.stubPageSize + MethodDescSlotOffset);\n                                    isPrestubMD = true;\n                                }\n                            }\n                        }\n                        TryTranslateAddressToName(address, isPrestubMD, state, depth, currentMethod);\n                    }\n\n                    accumulator.Feed(instruction);\n\n                    yield return new Arm64Asm()\n                    {\n                        InstructionPointer = (ulong)instruction.Address,\n                        InstructionLength = instruction.Bytes.Length,\n                        Instruction = instruction,\n                        ReferencedAddress = (address > ushort.MaxValue) ? address : null,\n                        IsReferencedAddressIndirect = isIndirect,\n                        DisassembleSyntax = disassembler.DisassembleSyntax\n                    };\n                }\n            }\n        }\n\n        private static bool TryGetReferencedAddress(Arm64Instruction instruction, RegisterValueAccumulator accumulator, uint pointerSize, out ulong referencedAddress, out bool isReferencedAddressIndirect)\n        {\n            if ((instruction.Id == Arm64InstructionId.ARM64_INS_BR || instruction.Id == Arm64InstructionId.ARM64_INS_BLR) && instruction.Details.Operands[0].Register.Id == accumulator.RegisterId && accumulator.HasValue)\n            {\n                // Branch via register where we have extracted the value of the register by parsing the disassembly\n                referencedAddress = (ulong)accumulator.Value;\n                isReferencedAddressIndirect = true;\n                return true;\n            }\n            else if (instruction.Details.BelongsToGroup(Arm64InstructionGroupId.ARM64_GRP_BRANCH_RELATIVE))\n            {\n                // One of the operands is the address\n                for (int i = 0; i < instruction.Details.Operands.Length; i++)\n                {\n                    if (instruction.Details.Operands[i].Type == Arm64OperandType.Immediate)\n                    {\n                        referencedAddress = (ulong)instruction.Details.Operands[i].Immediate;\n                        isReferencedAddressIndirect = false;\n                        return true;\n                    }\n                }\n            }\n            referencedAddress = 0;\n            isReferencedAddressIndirect = false;\n            return false;\n        }\n\n        private static DisassembleSyntax Map(DisassemblySyntax syntax)\n            => syntax switch\n            {\n                DisassemblySyntax.Att => DisassembleSyntax.Att,\n                DisassemblySyntax.Intel => DisassembleSyntax.Intel,\n                _ => DisassembleSyntax.Masm\n            };\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Disassemblers/Arm64InstructionFormatter.cs",
    "content": "﻿using Gee.External.Capstone.Arm64;\nusing Iced.Intel;\nusing System.Collections.Generic;\nusing System.Text;\n\nnamespace BenchmarkDotNet.Disassemblers\n{\n    internal static class Arm64InstructionFormatter\n    {\n        // FormatterOptions is an Intel-specific concept that comes from the Iced library, but since our users can pass custom\n        // Iced Formatter to DisassemblyDiagnoserConfig and it provides all the settings we need, we just reuse it here.\n        internal static string Format(Arm64Asm asm, FormatterOptions formatterOptions,\n            bool printInstructionAddresses, uint pointerSize, IReadOnlyDictionary<ulong, string> symbols)\n        {\n            var instruction = asm.Instruction;\n            if (instruction == null)\n                return \"\";\n\n            StringBuilder output = new();\n\n            if (printInstructionAddresses)\n            {\n                FormatInstructionPointer(instruction, formatterOptions, pointerSize, output);\n            }\n\n            output.Append(instruction.Mnemonic.ToString().PadRight(formatterOptions.FirstOperandCharIndex));\n\n            if (asm.ReferencedAddress.HasValue && !asm.IsReferencedAddressIndirect && symbols.TryGetValue(asm.ReferencedAddress.Value, out var name))\n            {\n                string partToReplace = $\"#0x{asm.ReferencedAddress.Value:x}\";\n                output.Append(instruction.Operand.Replace(partToReplace, name));\n            }\n            else\n            {\n                output.Append(instruction.Operand);\n            }\n\n            return output.ToString();\n        }\n\n        private static void FormatInstructionPointer(Arm64Instruction instruction, FormatterOptions formatterOptions, uint pointerSize, StringBuilder output)\n        {\n            string ipFormat = formatterOptions.LeadingZeroes\n                ? pointerSize == 4 ? \"X8\" : \"X16\"\n                : \"X\";\n\n            output.Append(instruction.Address.ToString(ipFormat));\n            output.Append(' ');\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Disassemblers/ClrMdArgs.cs",
    "content": "﻿using BenchmarkDotNet.Serialization;\nusing System.Linq;\nusing System.Text.Json.Serialization;\n\nnamespace BenchmarkDotNet.Disassemblers\n{\n    internal struct ClrMdArgs(int processId, string typeName, string methodName, bool printSource, int maxDepth, string syntax, string tfm, string[] filters, string resultsPath = \"\")\n    {\n        [JsonIgnore]\n        internal int ProcessId = processId;\n\n        [JsonIgnore]\n        internal string TypeName = typeName ?? \"\";\n\n        [JsonInclude]\n        internal string MethodName = methodName;\n\n        [JsonInclude]\n        internal bool PrintSource = printSource;\n\n        [JsonInclude]\n        internal int MaxDepth = methodName == DisassemblerConstants.DisassemblerEntryMethodName && maxDepth != int.MaxValue ? maxDepth + 1 : maxDepth;\n\n        [JsonInclude]\n        internal string[] Filters = filters;\n\n        [JsonInclude]\n        internal string Syntax = syntax;\n\n        [JsonInclude]\n        internal string TargetFrameworkMoniker = tfm;\n\n        [JsonInclude]\n        internal string ResultsPath = resultsPath;\n\n        internal static ClrMdArgs FromArgs(string[] args)\n            => new(\n                processId: int.Parse(args[0]),\n                typeName: args[1],\n                methodName: args[2],\n                printSource: bool.Parse(args[3]),\n                maxDepth: int.Parse(args[4]),\n                resultsPath: args[5],\n                syntax: args[6],\n                tfm: args[7],\n                filters: [.. args.Skip(8)]\n            );\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Disassemblers/ClrMdDisassembler.cs",
    "content": "﻿using BenchmarkDotNet.Diagnosers;\nusing BenchmarkDotNet.Filters;\nusing Microsoft.Diagnostics.Runtime;\nusing System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Text.RegularExpressions;\nusing BenchmarkDotNet.Detectors;\nusing BenchmarkDotNet.Portability;\nusing Microsoft.Diagnostics.NETCore.Client;\nusing BenchmarkDotNet.Extensions;\n\nnamespace BenchmarkDotNet.Disassemblers\n{\n    internal abstract class ClrMdDisassembler\n\n    {\n        private static readonly ulong MinValidAddress = GetMinValidAddress();\n\n        private static ulong GetMinValidAddress()\n        {\n            // https://github.com/dotnet/BenchmarkDotNet/pull/2413#issuecomment-1688100117\n            if (OsDetector.IsWindows())\n                return ushort.MaxValue + 1;\n            if (OsDetector.IsLinux())\n                return (ulong)Environment.SystemPageSize;\n            if (OsDetector.IsMacOS())\n                return RuntimeInformation.GetCurrentPlatform() switch\n                {\n                    Environments.Platform.X86 or Environments.Platform.X64 => 4096,\n                    Environments.Platform.Arm64 => 0x100000000,\n                    var platform => throw new NotSupportedException($\"{platform} is not supported\")\n                };\n            throw new NotSupportedException($\"{System.Runtime.InteropServices.RuntimeInformation.OSDescription} is not supported\");\n        }\n\n        private static bool IsValidAddress(ulong address)\n            // -1 (ulong.MaxValue) address is invalid, and will crash the runtime in older runtimes. https://github.com/dotnet/runtime/pull/90794\n            // 0 is NULL and therefore never valid.\n            // Addresses less than the minimum virtual address are also invalid.\n            => address != ulong.MaxValue\n                && address != 0\n                && address >= MinValidAddress;\n\n        private DataTarget Attach(int processId)\n        {\n            bool isSelf = processId == System.Diagnostics.Process.GetCurrentProcess().Id;\n            if (OsDetector.IsWindows())\n            {\n                // Windows CoreCLR fails to disassemble generic types when using CreateSnapshotAndAttach, and succeeds with AttachToProcess. https://github.com/microsoft/clrmd/issues/1334\n                return isSelf && !RuntimeInformation.IsNetCore\n                    ? DataTarget.CreateSnapshotAndAttach(processId)\n                    : DataTarget.AttachToProcess(processId, suspend: false);\n            }\n            if (OsDetector.IsLinux())\n            {\n                // Linux crashes when using AttachToProcess in the same process.\n                return isSelf\n                    ? DataTarget.CreateSnapshotAndAttach(processId)\n                    : DataTarget.AttachToProcess(processId, suspend: false);\n            }\n            if (OsDetector.IsMacOS())\n            {\n                // ClrMD does not support CreateSnapshotAndAttach on MacOS, and AttachToProcess is unreliable, so we have to create a dump file and load it.\n                string dumpPath = Path.GetTempFileName();\n                try\n                {\n                    try\n                    {\n                        new DiagnosticsClient(processId).WriteDump(DumpType.Full, dumpPath, logDumpGeneration: false);\n                    }\n                    catch (ServerErrorException sxe)\n                    {\n                        throw new ArgumentException($\"Unable to create a snapshot of process {processId:x}.\", sxe);\n                    }\n                    return DataTarget.LoadDump(dumpPath);\n                }\n                finally\n                {\n                    File.Delete(dumpPath);\n                }\n            }\n            throw new NotSupportedException($\"{System.Runtime.InteropServices.RuntimeInformation.OSDescription} is not supported\");\n        }\n\n        internal DisassemblyResult AttachAndDisassemble(ClrMdArgs args)\n        {\n            using var dataTarget = Attach(args.ProcessId);\n\n            var runtime = dataTarget.ClrVersions.Single().CreateRuntime();\n\n            ConfigureSymbols(dataTarget);\n\n            var state = new State(runtime, args.TargetFrameworkMoniker);\n\n            if (args.Filters.Length > 0)\n            {\n                FilterAndEnqueue(state, args);\n            }\n            else\n            {\n                var typeWithBenchmark = state.Runtime.EnumerateModules().Select(module => module.GetTypeByName(args.TypeName)).WhereNotNull().First();\n\n                state.Todo.Enqueue(\n                    new MethodInfo(\n                        // the Disassembler Entry Method is always parameterless, so check by name is enough\n                        typeWithBenchmark.Methods.Single(method => method.Attributes.HasFlag(System.Reflection.MethodAttributes.Public) && method.Name == args.MethodName),\n                        0));\n            }\n\n            var disassembledMethods = Disassemble(args, state);\n\n            // we don't want to export the disassembler entry point method which is just an artificial method added to get generic types working\n            var filteredMethods = disassembledMethods.Length == 1\n                ? disassembledMethods // if there is only one method we want to return it (most probably benchmark got inlined)\n                : disassembledMethods.Where(method => !method.Name.Contains(DisassemblerConstants.DisassemblerEntryMethodName)).ToArray();\n\n            return new DisassemblyResult\n            {\n                Methods = filteredMethods,\n                AddressToNameMapping = state.AddressToNameMapping,\n                PointerSize = (uint)IntPtr.Size\n            };\n        }\n\n        private static void ConfigureSymbols(DataTarget dataTarget)\n        {\n            // code copied from https://github.com/Microsoft/clrmd/issues/34#issuecomment-161926535\n            dataTarget.SetSymbolPath(\"http://msdl.microsoft.com/download/symbols\");\n        }\n\n        private static void FilterAndEnqueue(State state, ClrMdArgs args)\n        {\n            Regex[] filters = GlobFilter.ToRegex(args.Filters);\n\n            foreach (ClrModule module in state.Runtime.EnumerateModules())\n                foreach (ClrType type in module.EnumerateTypeDefToMethodTableMap().Select(map => state.Runtime.GetTypeByMethodTable(map.MethodTable)).WhereNotNull())\n                    foreach (ClrMethod method in type.Methods.Where(method => method.Signature.IsNotBlank()))\n                    {\n                        if (method.NativeCode > 0)\n                        {\n                            if (!state.AddressToNameMapping.TryGetValue(method.NativeCode, out _))\n                            {\n                                state.AddressToNameMapping.Add(method.NativeCode, method.Signature!);\n                            }\n                        }\n\n                        if (CanBeDisassembled(method))\n                        {\n                            foreach (Regex filter in filters)\n                            {\n                                if (filter.IsMatch(method.Signature!))\n                                {\n                                    state.Todo.Enqueue(new MethodInfo(method,\n                                        depth: args.MaxDepth)); // don't allow for recursive disassembling\n                                    break;\n                                }\n                            }\n                        }\n                    }\n        }\n\n        private DisassembledMethod[] Disassemble(ClrMdArgs args, State state)\n        {\n            var result = new List<DisassembledMethod>();\n            DisassemblySyntax syntax = Enum.Parse<DisassemblySyntax>(args.Syntax);\n\n            using var sourceCodeProvider = new SourceCodeProvider();\n            while (state.Todo.Count != 0)\n            {\n                var methodInfo = state.Todo.Dequeue();\n\n                if (!state.HandledMethods.Add(methodInfo.Method)) // add it now to avoid StackOverflow for recursive methods\n                    continue; // already handled\n\n                if (args.MaxDepth >= methodInfo.Depth)\n                    result.Add(DisassembleMethod(methodInfo, state, args, syntax, sourceCodeProvider));\n            }\n\n            return result.ToArray();\n        }\n\n        private static bool CanBeDisassembled(ClrMethod method) => method.ILOffsetMap.Length > 0 && method.NativeCode > 0;\n\n        private DisassembledMethod DisassembleMethod(MethodInfo methodInfo, State state, ClrMdArgs args, DisassemblySyntax syntax, SourceCodeProvider sourceCodeProvider)\n        {\n            var method = methodInfo.Method;\n\n            if (!CanBeDisassembled(method))\n            {\n                if (method.Attributes.HasFlag(System.Reflection.MethodAttributes.PinvokeImpl))\n                    return CreateEmpty(method, \"PInvoke method\");\n                var ilInfo = method.GetILInfo();\n                if (ilInfo is null || ilInfo.Length == 0)\n                    return CreateEmpty(method, \"Extern method\");\n                if (method.CompilationType == MethodCompilationType.None)\n                    return CreateEmpty(method, \"Method was not JITted yet.\");\n\n                return CreateEmpty(method, $\"No valid {nameof(method.ILOffsetMap)} and {nameof(method.HotColdInfo)}\");\n            }\n\n            var codes = new List<SourceCode>();\n            if (args.PrintSource && method.ILOffsetMap.Length > 0)\n            {\n                // we use HashSet to prevent from duplicates\n                var uniqueSourceCodeLines = new HashSet<Sharp>(new SharpComparer());\n                // for getting C# code we always use the original ILOffsetMap\n                foreach (var map in method.ILOffsetMap.Where(map => map.StartAddress < map.EndAddress && map.ILOffset >= 0).OrderBy(map => map.StartAddress))\n                    foreach (var sharp in sourceCodeProvider.GetSource(method, map))\n                        uniqueSourceCodeLines.Add(sharp);\n\n                codes.AddRange(uniqueSourceCodeLines);\n            }\n\n            foreach (var map in GetCompleteNativeMap(method, state.Runtime))\n            {\n                codes.AddRange(Decode(map, state, methodInfo.Depth, method, syntax));\n            }\n\n            Map[] maps = args.PrintSource\n                ? codes.GroupBy(code => code.InstructionPointer).OrderBy(group => group.Key).Select(group => new Map() { SourceCodes = group.ToArray() }).ToArray()\n                : [new Map() { SourceCodes = codes.ToArray() }];\n\n            return new DisassembledMethod\n            {\n                Maps = maps,\n                Name = method.Signature ?? \"\",\n                NativeCode = method.NativeCode\n            };\n        }\n\n        private IEnumerable<Asm> Decode(ILToNativeMap map, State state, int depth, ClrMethod currentMethod, DisassemblySyntax syntax)\n        {\n            ulong startAddress = map.StartAddress;\n            uint size = (uint)(map.EndAddress - map.StartAddress);\n\n            byte[] code = new byte[size];\n\n            int totalBytesRead = 0;\n            do\n            {\n                int bytesRead = state.Runtime.DataTarget.DataReader.Read(startAddress + (ulong)totalBytesRead, new Span<byte>(code, totalBytesRead, (int)size - totalBytesRead));\n                if (bytesRead <= 0)\n                {\n                    throw new EndOfStreamException($\"Tried to read {size} bytes for {currentMethod.Signature}, got only {totalBytesRead}\");\n                }\n                totalBytesRead += bytesRead;\n            } while (totalBytesRead != size);\n\n            return Decode(code, startAddress, state, depth, currentMethod, syntax);\n        }\n\n        protected abstract IEnumerable<Asm> Decode(byte[] code, ulong startAddress, State state, int depth, ClrMethod currentMethod, DisassemblySyntax syntax);\n\n        private static ILToNativeMap[] GetCompleteNativeMap(ClrMethod method, ClrRuntime runtime)\n        {\n            // it's better to use one single map rather than few small ones\n            // it's simply easier to get next instruction when decoding ;)\n\n            var hotColdInfo = method.HotColdInfo;\n            if (hotColdInfo.HotSize > 0 && hotColdInfo.HotStart > 0)\n            {\n                return hotColdInfo.ColdSize <= 0\n                    ? [new ILToNativeMap() { StartAddress = hotColdInfo.HotStart, EndAddress = hotColdInfo.HotStart + hotColdInfo.HotSize, ILOffset = -1 }]\n                    : [\n                          new ILToNativeMap() { StartAddress = hotColdInfo.HotStart, EndAddress = hotColdInfo.HotStart + hotColdInfo.HotSize, ILOffset = -1 },\n                          new ILToNativeMap() { StartAddress = hotColdInfo.ColdStart, EndAddress = hotColdInfo.ColdStart + hotColdInfo.ColdSize, ILOffset = -1 }\n                      ];\n            }\n\n            return method.ILOffsetMap\n                .Where(map => map.StartAddress < map.EndAddress) // some maps have 0 length?\n                .OrderBy(map => map.StartAddress) // we need to print in the machine code order, not IL! #536\n                .ToArray();\n        }\n\n        private static DisassembledMethod CreateEmpty(ClrMethod method, string reason)\n            => DisassembledMethod.Empty(method.Signature ?? \"\", method.NativeCode, reason);\n\n        protected void TryTranslateAddressToName(ulong address, bool isAddressPrecodeMD, State state, int depth, ClrMethod currentMethod)\n        {\n            if (!IsValidAddress(address) || state.AddressToNameMapping.ContainsKey(address))\n                return;\n\n            var runtime = state.Runtime;\n\n            var jitHelperFunctionName = runtime.GetJitHelperFunctionName(address);\n            if (jitHelperFunctionName.IsNotBlank())\n            {\n                state.AddressToNameMapping.Add(address, jitHelperFunctionName!);\n                return;\n            }\n\n            var method = runtime.GetMethodByInstructionPointer(address);\n            if (method is null && (address & ((uint)runtime.DataTarget.DataReader.PointerSize - 1)) == 0\n                && runtime.DataTarget.DataReader.ReadPointer(address, out ulong newAddress) && IsValidAddress(newAddress))\n            {\n                method = runtime.GetMethodByInstructionPointer(newAddress);\n            }\n\n            if (method is null)\n            {\n                var methodDescriptor = runtime.GetMethodByHandle(address);\n                if (methodDescriptor is not null)\n                {\n                    if (isAddressPrecodeMD)\n                    {\n                        state.AddressToNameMapping.Add(address, $\"Precode of {methodDescriptor.Signature}\");\n                    }\n                    else\n                    {\n                        state.AddressToNameMapping.Add(address, $\"MD_{methodDescriptor.Signature}\");\n                    }\n                    return;\n                }\n\n                var methodTableName = runtime.GetTypeByMethodTable(address)?.Name;\n                if (methodTableName.IsNotBlank())\n                {\n                    state.AddressToNameMapping.Add(address, $\"MT_{methodTableName}\");\n                }\n                return;\n            }\n\n            if (method.NativeCode == currentMethod.NativeCode && method.Signature == currentMethod.Signature)\n                return; // in case of a call which is just a jump within the method or a recursive call\n\n            if (!state.HandledMethods.Contains(method))\n                state.Todo.Enqueue(new MethodInfo(method, depth + 1));\n\n            var methodName = method.Signature!;\n            if (!methodName.Any(c => c == '.')) // the method name does not contain namespace and type name\n                methodName = $\"{method.Type.Name}.{method.Signature}\";\n            state.AddressToNameMapping.Add(address, methodName);\n        }\n\n        protected void FlushCachedDataIfNeeded(IDataReader dataTargetDataReader, ulong address, byte[] buffer)\n        {\n            if (!OsDetector.IsWindows())\n            {\n                if (dataTargetDataReader.Read(address, buffer) <= 0)\n                {\n                    // We don't suspend the benchmark process for the time of disassembling,\n                    // as it would require sudo privileges.\n                    // Because of that, the Tiered JIT thread might still re-compile some methods\n                    // in the meantime when the host process it trying to disassemble the code.\n                    // In such case, Tiered JIT thread might create stubs which requires flushing of the cached data.\n                    dataTargetDataReader.FlushCachedData();\n                }\n            }\n        }\n\n        private class SharpComparer : IEqualityComparer<Sharp>\n        {\n            public bool Equals(Sharp? x, Sharp? y)\n            {\n                if (ReferenceEquals(x, y))\n                    return true;\n                if (x is null || y is null)\n                    return false;\n\n                // sometimes some C# code lines are duplicated because the same line is the best match for multiple ILToNativeMaps\n                // we don't want to confuse the users, so this must also be removed\n                return x.FilePath == y.FilePath && x.LineNumber == y.LineNumber;\n            }\n\n            public int GetHashCode(Sharp obj) => HashCode.Combine(obj.FilePath, obj.LineNumber);\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Disassemblers/DataContracts.cs",
    "content": "﻿using Gee.External.Capstone;\nusing Gee.External.Capstone.Arm64;\nusing Iced.Intel;\nusing Microsoft.Diagnostics.Runtime;\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text.Json;\nusing System.Text.Json.Serialization;\nusing System.ComponentModel;\n\n\n#if NET6_0_OR_GREATER\nusing System.Diagnostics.CodeAnalysis;\n#endif\n\nnamespace BenchmarkDotNet.Disassemblers;\n\n[JsonPolymorphic(TypeDiscriminatorPropertyName = \"$type\")]\n[JsonDerivedType(typeof(Sharp), typeDiscriminator: nameof(Sharp))]\n[JsonDerivedType(typeof(IntelAsm), typeDiscriminator: nameof(IntelAsm))]\n[JsonDerivedType(typeof(Arm64Asm), typeDiscriminator: nameof(Arm64Asm))]\n[JsonDerivedType(typeof(MonoCode), typeDiscriminator: nameof(MonoCode))]\npublic abstract class SourceCode\n{\n    // Closed hierarchy.\n    internal SourceCode() { }\n\n    public ulong InstructionPointer { get; set; }\n}\n\npublic sealed class Sharp : SourceCode\n{\n    public required string Text { get; set; }\n    public required string FilePath { get; set; }\n    public int LineNumber { get; set; }\n}\n\npublic abstract class Asm : SourceCode\n{\n    // Closed hierarchy.\n    internal Asm() { }\n\n    public int InstructionLength { get; set; }\n    public ulong? ReferencedAddress { get; set; }\n    public bool IsReferencedAddressIndirect { get; set; }\n}\n\n#if NET6_0_OR_GREATER\n// There are way too many properties to serialize them manually.\n// Ensure the Instruction's properties are not trimmed.\n[method: DynamicDependency(DynamicallyAccessedMemberTypes.PublicProperties, typeof(Instruction))]\n#endif\npublic sealed class IntelAsm() : Asm\n{\n    public Instruction Instruction { get; set; }\n\n    public override string ToString() => Instruction.ToString();\n}\n\npublic sealed class Arm64Asm : Asm\n{\n    [JsonInclude]\n    [EditorBrowsable(EditorBrowsableState.Never)]\n    internal Arm64AsmData Data { get; set; }\n\n    [JsonIgnore]\n    public Arm64Instruction? Instruction\n    {\n        get => Data.Instruction;\n        set => Data = Data with { Instruction = value };\n    }\n\n    [JsonIgnore]\n    internal DisassembleSyntax DisassembleSyntax\n    {\n        get => Data.DisassembleSyntax;\n        set => Data = Data with { DisassembleSyntax = value };\n    }\n\n    public override string ToString() => Instruction?.ToString() ?? \"\";\n\n    // Wrapper class to hold Arm64 instruction and disassemble syntax.\n    [JsonConverter(typeof(Arm64AsmDataConverter))]\n    internal record struct Arm64AsmData\n    {\n        internal DisassembleSyntax DisassembleSyntax { get; set; }\n\n        public Arm64Instruction? Instruction { get; set; }\n    }\n\n    // Custom JsonConverter for Arm64AsmData.\n    internal class Arm64AsmDataConverter : JsonConverter<Arm64AsmData>\n    {\n        private const string Arm64AddressKey = \"arm64Address\";\n        private const string Arm64BytesKey = \"arm64Bytes\";\n        private const string Arm64SyntaxKey = \"arm64Syntax\";\n\n        public override Arm64AsmData Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)\n        {\n            if (reader.TokenType != JsonTokenType.StartObject)\n                throw new JsonException();\n\n            long instructionAddress = default;\n            byte[] instructionBytes = [];\n            DisassembleSyntax syntax = DisassembleSyntax.Masm;\n\n            while (reader.Read())\n            {\n                if (reader.TokenType == JsonTokenType.EndObject)\n                    break;\n\n                if (reader.TokenType != JsonTokenType.PropertyName)\n                    throw new JsonException();\n\n                string propertyName = reader.GetString()!;\n                reader.Read();\n\n                switch (propertyName)\n                {\n                    case Arm64AddressKey:\n                        instructionAddress = reader.GetInt64();\n                        break;\n\n                    case Arm64BytesKey:\n                        instructionBytes = reader.GetBytesFromBase64();\n                        break;\n\n                    case Arm64SyntaxKey:\n                        var syntaxValue = reader.GetString()!;\n                        syntax = syntaxValue switch\n                        {\n                            \"Intel\" => DisassembleSyntax.Intel,\n                            \"Att\" => DisassembleSyntax.Att,\n                            \"Masm\" => DisassembleSyntax.Masm,\n                            _ => DisassembleSyntax.Masm,\n                        };\n                        break;\n\n                    default:\n                        throw new NotSupportedException($\"Unknown property({propertyName}) found.\");\n                }\n            }\n\n            if (reader.TokenType != JsonTokenType.EndObject)\n                throw new JsonException(\"Invalid JSON\");\n\n            using var disassembler = CapstoneDisassembler.CreateArm64Disassembler(Arm64DisassembleMode.Arm);\n            disassembler.EnableInstructionDetails = true;\n            disassembler.DisassembleSyntax = syntax;\n            var instruction = disassembler.Disassemble(instructionBytes, instructionAddress).SingleOrDefault();\n\n            return new Arm64AsmData\n            {\n                DisassembleSyntax = syntax,\n                Instruction = instruction,\n            };\n        }\n\n        public override void Write(Utf8JsonWriter writer, Arm64AsmData value, JsonSerializerOptions options)\n        {\n            writer.WriteStartObject();\n            writer.WriteString(Arm64SyntaxKey, value.DisassembleSyntax.ToString());\n            var instruction = value.Instruction;\n            if (instruction != null)\n            {\n                writer.WriteNumber(Arm64AddressKey, instruction.Address);\n                writer.WriteBase64String(Arm64BytesKey, instruction.Bytes);\n            }\n            writer.WriteEndObject();\n        }\n    }\n\n}\n\npublic sealed class MonoCode : SourceCode\n{\n    public string Text { get; set; } = \"\";\n}\n\npublic sealed class Map\n{\n    public SourceCode[] SourceCodes { get; set; } = [];\n}\n\npublic sealed class DisassembledMethod\n{\n    public string Name { get; set; } = \"\";\n\n    public ulong NativeCode { get; set; }\n\n    public string Problem { get; set; } = \"\";\n\n    public Map[] Maps { get; set; } = [];\n\n    public string CommandLine { get; set; } = \"\";\n\n    public static DisassembledMethod Empty(string fullSignature, ulong nativeCode, string problem)\n        => new()\n        {\n            Name = fullSignature,\n            NativeCode = nativeCode,\n            Problem = problem\n        };\n}\n\npublic sealed class DisassemblyResult\n{\n    public DisassembledMethod[] Methods { get; set; } = [];\n    public string[] Errors { get; set; } = [];\n\n    public uint PointerSize { get; set; }\n\n    public Dictionary<ulong, string> AddressToNameMapping { get; set; } = [];\n}\n\npublic static class DisassemblerConstants\n{\n    public const string DisassemblerEntryMethodName = \"__ForDisassemblyDiagnoser__\";\n}\n\ninternal sealed class State\n{\n    internal State(ClrRuntime runtime, string targetFrameworkMoniker)\n    {\n        Runtime = runtime;\n        Todo = new Queue<MethodInfo>();\n        HandledMethods = new HashSet<ClrMethod>(new ClrMethodComparer());\n        AddressToNameMapping = [];\n        RuntimeVersion = ParseVersion(targetFrameworkMoniker);\n    }\n\n    internal ClrRuntime Runtime { get; }\n    internal Queue<MethodInfo> Todo { get; }\n    internal HashSet<ClrMethod> HandledMethods { get; }\n    internal Dictionary<ulong, string> AddressToNameMapping { get; }\n    internal Version RuntimeVersion { get; }\n\n    internal static Version ParseVersion(string targetFrameworkMoniker)\n    {\n        int firstDigit = -1, lastDigit = -1;\n        for (int i = 0; i < targetFrameworkMoniker.Length; i++)\n        {\n            if (char.IsDigit(targetFrameworkMoniker[i]))\n            {\n                if (firstDigit == -1)\n                    firstDigit = i;\n\n                lastDigit = i;\n            }\n            else if (targetFrameworkMoniker[i] == '-')\n            {\n                break; // it can be platform specific like net7.0-windows8\n            }\n        }\n\n        string versionToParse = targetFrameworkMoniker.Substring(firstDigit, lastDigit - firstDigit + 1);\n        if (!versionToParse.Contains(\".\")) // Full .NET Framework (net48 etc)\n            versionToParse = string.Join(\".\", versionToParse.ToCharArray());\n\n        return Version.Parse(versionToParse);\n    }\n\n    private sealed class ClrMethodComparer : IEqualityComparer<ClrMethod>\n    {\n        public bool Equals(ClrMethod? x, ClrMethod? y)\n        {\n            if (ReferenceEquals(x, y))\n                return true;\n\n            if (x is null || y is null)\n                return false;\n\n            return x.NativeCode == y.NativeCode;\n        }\n\n        public int GetHashCode(ClrMethod obj) => (int)obj.NativeCode;\n    }\n}\n\ninternal readonly struct MethodInfo // I am not using ValueTuple here (would be perfect) to keep the number of dependencies as low as possible\n{\n    internal ClrMethod Method { get; }\n    internal int Depth { get; }\n\n    internal MethodInfo(ClrMethod method, int depth)\n    {\n        Method = method;\n        Depth = depth;\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Disassemblers/DisassemblyAnalyzer.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Linq;\nusing BenchmarkDotNet.Analysers;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Running;\n\nnamespace BenchmarkDotNet.Disassemblers\n{\n    internal class DisassemblyAnalyzer : IAnalyser\n    {\n        public string Id => \"Disassembly\";\n\n        private readonly IReadOnlyDictionary<BenchmarkCase, DisassemblyResult> results;\n\n        internal DisassemblyAnalyzer(IReadOnlyDictionary<BenchmarkCase, DisassemblyResult> results) => this.results = results;\n\n        public IEnumerable<Conclusion> Analyse(Summary summary)\n            => from pair in results\n                from error in pair.Value.Errors\n                select Conclusion.CreateWarning(Id, error, summary[pair.Key]);\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Disassemblers/DisassemblyDiagnoser.cs",
    "content": "﻿using BenchmarkDotNet.Analysers;\nusing BenchmarkDotNet.Columns;\nusing BenchmarkDotNet.Detectors;\nusing BenchmarkDotNet.Disassemblers;\nusing BenchmarkDotNet.Disassemblers.Exporters;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Exporters;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Helpers;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Portability;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Serialization;\nusing BenchmarkDotNet.Toolchains.InProcess.NoEmit;\nusing BenchmarkDotNet.Validators;\nusing JetBrains.Annotations;\nusing Perfolizer.Metrology;\nusing System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Diagnostics;\nusing System.Linq;\n\nnamespace BenchmarkDotNet.Diagnosers\n{\n    public class DisassemblyDiagnoser : IInProcessDiagnoser\n    {\n        private static readonly Lazy<string> ptrace_scope = new(() => ProcessHelper.RunAndReadOutput(\"cat\", \"/proc/sys/kernel/yama/ptrace_scope\")?.Trim() ?? \"\");\n\n        private ClrMdDisassembler? _clrMdDisassembler;\n\n        // Lazy create to avoid exceptions at Disassembler ctor\n        private ClrMdDisassembler ClrMdDisassembler => _clrMdDisassembler ??= GetClrMdDisassembler();\n\n        internal static ClrMdDisassembler GetClrMdDisassembler() =>\n            RuntimeInformation.GetCurrentPlatform() switch\n            {\n                Platform.X86 or Platform.X64 => new IntelDisassembler(),\n                Platform.Arm64 => new Arm64Disassembler(),\n                var platform => throw new NotSupportedException($\"{platform} is not supported\")\n            };\n\n        private readonly MonoDisassembler monoDisassembler = new();\n        private readonly Dictionary<BenchmarkCase, DisassemblyResult> results = [];\n\n        public DisassemblyDiagnoser(DisassemblyDiagnoserConfig config)\n        {\n            Config = config;\n\n            Exporters = GetExporters(results, config);\n        }\n\n        public DisassemblyDiagnoserConfig Config { get; }\n\n        public IReadOnlyDictionary<BenchmarkCase, DisassemblyResult> Results => results;\n\n        public IEnumerable<string> Ids => [nameof(DisassemblyDiagnoser)];\n\n        public IEnumerable<IExporter> Exporters { get; }\n\n        public IEnumerable<IAnalyser> Analysers => [new DisassemblyAnalyzer(results)];\n\n        public IEnumerable<Metric> ProcessResults(DiagnoserResults diagnoserResults)\n        {\n            if (results.TryGetValue(diagnoserResults.BenchmarkCase, out var disassemblyResult))\n                yield return new Metric(NativeCodeSizeMetricDescriptor.Instance, SumNativeCodeSize(disassemblyResult));\n        }\n\n        public RunMode GetRunMode(BenchmarkCase benchmarkCase)\n        {\n            if (ShouldUseClrMdDisassembler(benchmarkCase))\n                return RunMode.NoOverhead;\n            else if (ShouldUseMonoDisassembler(benchmarkCase))\n                return RunMode.SeparateLogic;\n\n            return RunMode.None;\n        }\n\n        private ClrMdArgs BuildClrMdArgs(BenchmarkCase benchmarkCase, string typeName, int processId)\n            => new(\n                processId: processId,\n                typeName: typeName,\n                methodName: DisassemblerConstants.DisassemblerEntryMethodName,\n                printSource: Config.PrintSource,\n                maxDepth: Config.MaxDepth,\n                filters: Config.Filters,\n                syntax: Config.Syntax.ToString(),\n                tfm: benchmarkCase.Job.Environment.GetRuntime().MsBuildMoniker\n            );\n\n        public void Handle(HostSignal signal, DiagnoserActionParameters parameters)\n        {\n            var benchmark = parameters.BenchmarkCase;\n            bool isInProcess = parameters.BenchmarkCase.Job.Infrastructure.TryGetToolchain(out var toolchain) && toolchain.IsInProcess;\n\n            switch (signal)\n            {\n                case HostSignal.AfterAll when (Config.RunInHost || isInProcess) && ShouldUseClrMdDisassembler(benchmark):\n                    results.Add(benchmark, ClrMdDisassembler.AttachAndDisassemble(\n                        BuildClrMdArgs(parameters.BenchmarkCase, $\"BenchmarkDotNet.Autogenerated.Runnable_{parameters.BenchmarkId.Value}\", parameters.ProcessId))\n                    );\n                    break;\n                case HostSignal.SeparateLogic when ShouldUseMonoDisassembler(benchmark):\n                    results.Add(benchmark, monoDisassembler.Disassemble(benchmark, (MonoRuntime)benchmark.Job.Environment.Runtime!));\n                    break;\n            }\n        }\n\n        public void DisplayResults(ILogger logger)\n            => logger.WriteInfo(\n                results.Count > 0\n                    ? \"Disassembled benchmarks got exported to \\\".\\\\BenchmarkDotNet.Artifacts\\\\results\\\\*asm.md\\\"\"\n                    : \"No benchmarks were disassembled\");\n\n        public IEnumerable<ValidationError> Validate(ValidationParameters validationParameters)\n        {\n            var currentPlatform = RuntimeInformation.GetCurrentPlatform();\n            if (!(currentPlatform is Platform.X64 or Platform.X86 or Platform.Arm64))\n            {\n                yield return new ValidationError(true, $\"DisassemblyDiagnoser does not support {currentPlatform}\");\n                yield break;\n            }\n\n            if (currentPlatform == Platform.Arm64 && OsDetector.IsWindows())\n            {\n                yield return new ValidationError(true, $\"DisassemblyDiagnoser does not support Arm on Windows\");\n                yield break;\n            }\n\n            if (Config.RunInHost && OsDetector.IsMacOS())\n            {\n                yield return new ValidationError(true, \"Disassembling in the host process is not supported on MacOS\");\n                yield break;\n            }\n\n            foreach (var benchmark in validationParameters.Benchmarks)\n            {\n                if (benchmark.Job.Infrastructure.TryGetToolchain(out var toolchain) && toolchain is InProcessNoEmitToolchain)\n                {\n                    yield return new ValidationError(true, \"InProcessToolchain has no DisassemblyDiagnoser support\", benchmark);\n                }\n                else if (benchmark.Job.IsNativeAOT())\n                {\n                    yield return new ValidationError(true, \"Currently NativeAOT has no DisassemblyDiagnoser support\", benchmark);\n                }\n\n                if (ShouldUseClrMdDisassembler(benchmark))\n                {\n                    if (Config.RunInHost && toolchain?.IsInProcess != true && !PlatformsMatch(currentPlatform, benchmark.Job.Environment.Platform))\n                    {\n                        yield return new ValidationError(true, \"DisassemblyDiagnoser cannot run in host for a job that targets a different platform\", benchmark);\n                    }\n\n                    if (OsDetector.IsLinux())\n                    {\n                        var runtime = benchmark.Job.ResolveValue(EnvironmentMode.RuntimeCharacteristic, EnvironmentResolver.Instance)!;\n\n                        if (runtime.RuntimeMoniker < RuntimeMoniker.NetCoreApp30)\n                        {\n                            yield return new ValidationError(true, $\"{nameof(DisassemblyDiagnoser)} supports only .NET Core 3.0+\", benchmark);\n                        }\n\n                        if (ptrace_scope.Value == \"2\")\n                        {\n                            yield return new ValidationError(false, $\"ptrace_scope is set to 2, {nameof(DisassemblyDiagnoser)} is going to work only if you run as sudo\");\n                        }\n                        else if (ptrace_scope.Value == \"3\")\n                        {\n                            yield return new ValidationError(true, $\"ptrace_scope is set to 3, {nameof(DisassemblyDiagnoser)} is not going to work\");\n                        }\n                    }\n                }\n                else if (!ShouldUseMonoDisassembler(benchmark))\n                {\n                    yield return new ValidationError(true, $\"Only Windows and Linux are supported in DisassemblyDiagnoser without Mono. Current OS is {System.Runtime.InteropServices.RuntimeInformation.OSDescription}\");\n                }\n            }\n        }\n\n        private static bool PlatformsMatch(Platform currentPlatform, Platform targetPlatform)\n        {\n            Debug.Assert(currentPlatform != Platform.AnyCpu);\n\n            return targetPlatform == Platform.AnyCpu\n                // AnyCpu compiles to the bit-ness of the operating system.\n                // Legacy Framework also supports <Prefer32Bit> in Visual Studio,\n                // but we don't need to bother checking for it since we use dotnet sdk to build and we don't use or copy that property in generated csproj.\n                ? Environment.Is64BitProcess == Environment.Is64BitOperatingSystem\n                : currentPlatform == targetPlatform;\n        }\n\n        private static bool ShouldUseMonoDisassembler(BenchmarkCase benchmarkCase)\n            => benchmarkCase.Job.Environment.Runtime is MonoRuntime\n            || (RuntimeInformation.IsMono && benchmarkCase.Job.Infrastructure.TryGetToolchain(out var toolchain) && toolchain.IsInProcess);\n\n        private static bool ShouldUseClrMdDisassembler(BenchmarkCase benchmarkCase)\n            => !ShouldUseMonoDisassembler(benchmarkCase) && (OsDetector.IsWindows() || OsDetector.IsLinux() || OsDetector.IsMacOS());\n\n        private static IEnumerable<IExporter> GetExporters(Dictionary<BenchmarkCase, DisassemblyResult> results, DisassemblyDiagnoserConfig config)\n        {\n            if (config.ExportGithubMarkdown)\n            {\n                yield return new GithubMarkdownDisassemblyExporter(results, config);\n            }\n            if (config.ExportHtml)\n            {\n                yield return new HtmlDisassemblyExporter(results, config);\n            }\n            if (config.ExportCombinedDisassemblyReport)\n            {\n                yield return new CombinedDisassemblyExporter(results, config);\n            }\n            if (config.ExportDiff)\n            {\n                yield return new GithubMarkdownDiffDisassemblyExporter(results, config);\n            }\n        }\n\n        private static long SumNativeCodeSize(DisassemblyResult disassembly)\n            => disassembly.Methods.Sum(method => method.Maps.Sum(map => map.SourceCodes.OfType<Asm>().Sum(asm => asm.InstructionLength)));\n\n        InProcessDiagnoserHandlerData IInProcessDiagnoser.GetHandlerData(BenchmarkCase benchmarkCase)\n        {\n            if (GetRunMode(benchmarkCase) == RunMode.None\n                || Config.RunInHost\n                // We don't use handler for InProcess toolchains, the host diagnoser already handles it without needing to serialize data.\n                || (benchmarkCase.Job.Infrastructure.TryGetToolchain(out var toolchain) && toolchain.IsInProcess)\n                // Mono disassembler always runs another process.\n                || ShouldUseMonoDisassembler(benchmarkCase))\n            {\n                return default;\n            }\n\n            var clrMdArgs = BuildClrMdArgs(benchmarkCase, \"\", 0);\n            return new(typeof(DisassemblyDiagnoserInProcessHandler), BdnJsonSerializer.Serialize(clrMdArgs));\n        }\n\n        void IInProcessDiagnoser.DeserializeResults(BenchmarkCase benchmarkCase, string results)\n        {\n            var disassemblyResult = BdnJsonSerializer.Deserialize<DisassemblyResult>(results)!;\n            this.results.Add(benchmarkCase, disassemblyResult);\n        }\n\n        private class NativeCodeSizeMetricDescriptor : IMetricDescriptor\n        {\n            internal static readonly IMetricDescriptor Instance = new NativeCodeSizeMetricDescriptor();\n\n            public string Id => \"Native Code Size\";\n            public string DisplayName => Column.CodeSize;\n            public string Legend => \"Native code size of the disassembled method(s)\";\n            public string NumberFormat => \"N0\";\n            public UnitType UnitType => UnitType.CodeSize;\n            public string Unit => SizeUnit.B.Abbreviation;\n            public bool TheGreaterTheBetter => false;\n            public int PriorityInCategory => 0;\n            public bool GetIsAvailable(Metric metric) => true;\n        }\n    }\n\n    [UsedImplicitly]\n    [EditorBrowsable(EditorBrowsableState.Never)]\n    public sealed class DisassemblyDiagnoserInProcessHandler : IInProcessDiagnoserHandler\n    {\n        private ClrMdArgs _clrMdArgs;\n        private DisassemblyResult _result = default!;\n\n        void IInProcessDiagnoserHandler.Initialize(string? serializedConfig)\n        {\n            _clrMdArgs = BdnJsonSerializer.Deserialize<ClrMdArgs>(serializedConfig!);\n        }\n\n        void IInProcessDiagnoserHandler.Handle(BenchmarkSignal signal, InProcessDiagnoserActionArgs args)\n        {\n            if (signal != BenchmarkSignal.AfterEngine)\n            {\n                return;\n            }\n\n            var clrMdArgs = _clrMdArgs;\n            clrMdArgs.ProcessId = Process.GetCurrentProcess().Id;\n            clrMdArgs.TypeName = args.BenchmarkInstance.GetType().FullName!;\n            _result = DisassemblyDiagnoser.GetClrMdDisassembler().AttachAndDisassemble(clrMdArgs);\n        }\n\n        string IInProcessDiagnoserHandler.SerializeResults()\n        {\n            return BdnJsonSerializer.Serialize(_result);\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Disassemblers/DisassemblyDiagnoserConfig.cs",
    "content": "﻿using BenchmarkDotNet.Disassemblers.Exporters;\nusing Iced.Intel;\nusing JetBrains.Annotations;\nusing System;\nusing System.Collections.Generic;\n\nnamespace BenchmarkDotNet.Diagnosers\n{\n    public class DisassemblyDiagnoserConfig\n    {\n        /// <param name=\"maxDepth\">Includes called methods to given level. 1 by default, indexed from 1. To print just the benchmark set it to 0.</param>\n        /// <param name=\"filters\">Glob patterns applied to full method signatures by the the disassembler.</param>\n        /// <param name=\"syntax\">The disassembly syntax. MASM is the default.</param>\n        /// <param name=\"formatterOptions\">Code formatter options. If not provided, the recommended settings will be used.</param>\n        /// <param name=\"printSource\">C#|F#|VB source code will be printed. False by default.</param>\n        /// <param name=\"printInstructionAddresses\">Print instruction addresses. False by default</param>\n        /// <param name=\"exportGithubMarkdown\">Exports to GitHub markdown. True by default.</param>\n        /// <param name=\"exportHtml\">Exports to HTML with clickable links. False by default.</param>\n        /// <param name=\"exportCombinedDisassemblyReport\">Exports all benchmarks to a single HTML report. Makes it easy to compare different runtimes or methods (each becomes a column in HTML table).</param>\n        /// <param name=\"exportDiff\">Exports a diff of the assembly code to the Github markdown format. False by default.</param>\n        /// <param name=\"runInHost\">\n        /// If <see langword=\"true\"/>, disassembly will be ran in the host process; otherwise it will be ran in the benchmark process.\n        /// Requires host and benchmark processes to target the same platform (must have the same bit-ness).\n        /// </param>\n        [PublicAPI]\n        public DisassemblyDiagnoserConfig(\n            int maxDepth = 1,\n            DisassemblySyntax syntax = DisassemblySyntax.Masm,\n            string[]? filters = null,\n            FormatterOptions? formatterOptions = null,\n            bool printSource = false,\n            bool printInstructionAddresses = false,\n            bool exportGithubMarkdown = true,\n            bool exportHtml = false,\n            bool exportCombinedDisassemblyReport = false,\n            bool exportDiff = false,\n            bool runInHost = false)\n        {\n            if (!(syntax is DisassemblySyntax.Masm or DisassemblySyntax.Intel or DisassemblySyntax.Att))\n            {\n                throw new ArgumentOutOfRangeException(nameof(syntax), syntax, \"Invalid syntax\");\n            }\n\n            MaxDepth = maxDepth;\n            Filters = filters ?? [];\n            Syntax = syntax;\n            Formatting = formatterOptions ?? GetDefaults(syntax);\n            PrintSource = printSource;\n            PrintInstructionAddresses = printInstructionAddresses;\n            ExportGithubMarkdown = exportGithubMarkdown;\n            ExportHtml = exportHtml;\n            ExportCombinedDisassemblyReport = exportCombinedDisassemblyReport;\n            ExportDiff = exportDiff;\n            RunInHost = runInHost;\n        }\n\n        public bool PrintSource { get; }\n        public bool PrintInstructionAddresses { get; }\n        public int MaxDepth { get; }\n        public string[] Filters { get; }\n        public DisassemblySyntax Syntax { get; }\n        public FormatterOptions Formatting { get; }\n        public bool ExportGithubMarkdown { get; }\n        public bool ExportHtml { get; }\n        public bool ExportCombinedDisassemblyReport { get; }\n        public bool ExportDiff { get; }\n        public bool RunInHost { get; }\n\n        // user can specify a formatter without symbol solver\n        // so we need to clone the formatter with settings and provide our symbols solver\n        internal Formatter GetFormatterWithSymbolSolver(IReadOnlyDictionary<ulong, string> addressToNameMapping)\n            => Syntax switch\n            {\n                DisassemblySyntax.Att => new GasFormatter(Formatting, new SymbolResolver(addressToNameMapping)),\n                DisassemblySyntax.Intel => new IntelFormatter(Formatting, new SymbolResolver(addressToNameMapping)),\n                _ => new MasmFormatter(Formatting, new SymbolResolver(addressToNameMapping)),\n            };\n\n        private static FormatterOptions GetDefaults(DisassemblySyntax syntax)\n        {\n            FormatterOptions options = syntax switch\n            {\n                DisassemblySyntax.Att => FormatterOptions.CreateGas(),\n                DisassemblySyntax.Intel => FormatterOptions.CreateIntel(),\n                _ => FormatterOptions.CreateMasm(),\n            };\n\n            options.FirstOperandCharIndex = 10; // pad right the mnemonic\n            options.HexSuffix = default; // don't print \"h\" at the end of every hex address\n            options.TabSize = 0; // use spaces\n            return options;\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Disassemblers/DisassemblySyntax.cs",
    "content": "﻿namespace BenchmarkDotNet.Diagnosers\n{\n    public enum DisassemblySyntax\n    {\n        /// <summary>\n        /// Indicates a disassembler should use MASM syntax for generated assembly code\n        /// </summary>\n        Masm,\n        /// <summary>\n        /// Indicates a disassembler should use Intel syntax for generated assembly code.\n        /// </summary>\n        Intel,\n        /// <summary>\n        /// Indicates a disassembler should use AT&amp;T syntax for generated assembly code.\n        /// </summary>\n        Att\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Disassemblers/Exporters/CombinedDisassemblyExporter.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing BenchmarkDotNet.Diagnosers;\nusing BenchmarkDotNet.Exporters;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Running;\n\nnamespace BenchmarkDotNet.Disassemblers.Exporters\n{\n    internal class CombinedDisassemblyExporter : ExporterBase\n    {\n        internal const string CssDefinition = @\"\n<style type=\"\"text/css\"\">\n    table { border-collapse: collapse; display: block; width: 100%; overflow: auto; }\n    td, th { padding: 6px 13px; border: 1px solid #ddd; text-align: left; }\n    tr { background-color: #fff; border-top: 1px solid #ccc; }\n    tr:nth-child(even) { background: #f8f8f8; }\n</style>\";\n\n        private readonly IReadOnlyDictionary<BenchmarkCase, DisassemblyResult> results;\n        private readonly DisassemblyDiagnoserConfig config;\n\n        internal CombinedDisassemblyExporter(IReadOnlyDictionary<BenchmarkCase, DisassemblyResult> results, DisassemblyDiagnoserConfig config)\n        {\n            this.results = results;\n            this.config = config;\n        }\n\n        protected override string FileExtension => \"html\";\n        protected override string FileCaption => \"disassembly-report\";\n\n        public override void ExportToLog(Summary summary, ILogger logger)\n        {\n            var benchmarksByTarget = summary.BenchmarksCases\n                .Where(benchmark => results.ContainsKey(benchmark))\n                .GroupBy(benchmark => benchmark.Descriptor.WorkloadMethod)\n                .ToArray();\n\n            logger.WriteLine(\"<!DOCTYPE html>\");\n            logger.WriteLine(\"<html lang='en'>\");\n            logger.WriteLine(\"<head>\");\n            logger.WriteLine(\"<meta charset='utf-8' />\");\n            logger.WriteLine($\"<title>DisassemblyDiagnoser Output {summary.Title}</title>\");\n            logger.WriteLine(CssDefinition);\n            logger.WriteLine(\"</head>\");\n\n            logger.WriteLine(\"<body>\");\n\n            if (benchmarksByTarget.Any(group => group.Count() > 1)) // the user is comparing same method for different JITs\n            {\n                foreach (var targetingSameMethod in benchmarksByTarget)\n                {\n                    PrintTable(\n                        targetingSameMethod.ToArray(),\n                        logger,\n                        targetingSameMethod.First().Descriptor.DisplayInfo,\n                        benchmark => summary[benchmark]?.GetRuntimeInfo() ?? \"\");\n                }\n            }\n            else // different methods, same JIT\n            {\n                PrintTable(\n                    summary.BenchmarksCases.Where(results.ContainsKey).ToArray(),\n                    logger,\n                    summary.Title,\n                    benchmark => $\"{benchmark.Descriptor.WorkloadMethod.Name} {summary[benchmark]?.GetRuntimeInfo()}\".TrimEnd());\n            }\n\n            logger.WriteLine(\"</body>\");\n            logger.WriteLine(\"</html>\");\n        }\n\n        private void PrintTable(BenchmarkCase[] benchmarksCase, ILogger logger, string title, Func<BenchmarkCase, string> headerTitleProvider)\n        {\n            logger.WriteLine(\"<table>\");\n            logger.WriteLine(\"<thead>\");\n            logger.WriteLine($\"<tr><th colspan=\\\"{benchmarksCase.Length}\\\">{title}</th></tr>\");\n            logger.WriteLine(\"<tr>\");\n            foreach (var benchmark in benchmarksCase)\n            {\n                logger.WriteLine($\"<th>{headerTitleProvider(benchmark)}</th>\");\n            }\n            logger.WriteLine(\"</tr>\");\n            logger.WriteLine(\"</thead>\");\n\n            logger.WriteLine(\"<tbody>\");\n            logger.WriteLine(\"<tr>\");\n            foreach (var benchmark in benchmarksCase)\n            {\n                var disassemblyResult = results[benchmark];\n                logger.WriteLine(\"<td style=\\\"vertical-align:top;\\\"><pre><code>\");\n                foreach (var method in disassemblyResult.Methods.Where(method => method.Problem.IsBlank()))\n                {\n                    logger.WriteLine(method.Name);\n\n                    var formatter = config.GetFormatterWithSymbolSolver(disassemblyResult.AddressToNameMapping);\n\n                    foreach (var map in method.Maps)\n                        foreach (var sourceCode in map.SourceCodes)\n                            logger.WriteLine(CodeFormatter.Format(sourceCode, formatter, config.PrintInstructionAddresses, disassemblyResult.PointerSize, disassemblyResult.AddressToNameMapping));\n\n                    logger.WriteLine();\n                }\n\n                foreach (var withProblems in results[benchmark].Methods\n                    .Where(method => method.Problem.IsNotBlank())\n                    .GroupBy(method => method.Problem))\n                {\n                    logger.WriteLine(withProblems.Key);\n                    foreach (var withProblem in withProblems)\n                    {\n                        logger.WriteLine(withProblem.Name);\n                    }\n                    logger.WriteLine();\n                }\n                logger.WriteLine(\"</code></pre></td>\");\n            }\n            logger.WriteLine(\"</tr>\");\n            logger.WriteLine(\"</tbody>\");\n            logger.WriteLine(\"</table>\");\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Disassemblers/Exporters/DisassemblyPrettifier.cs",
    "content": "﻿using BenchmarkDotNet.Diagnosers;\nusing System.Collections.Generic;\nusing System.Linq;\n\nnamespace BenchmarkDotNet.Disassemblers.Exporters\n{\n    internal static class DisassemblyPrettifier\n    {\n        internal class Element\n        {\n            internal string TextRepresentation { get; }\n            internal SourceCode? Source { get; }\n\n            public Element(string textRepresentation, SourceCode? source)\n            {\n                TextRepresentation = textRepresentation;\n                Source = source;\n            }\n        }\n\n        internal class Reference : Element\n        {\n            internal string Id { get; }\n\n            public Reference(string textRepresentation, string id, SourceCode source) : base(textRepresentation, source) => Id = id;\n        }\n\n        internal class Label : Element\n        {\n            internal string Id { get; }\n\n            public Label(string label) : base(label, null) => Id = label;\n        }\n\n        internal static IReadOnlyList<Element> Prettify(DisassembledMethod method, DisassemblyResult disassemblyResult, DisassemblyDiagnoserConfig config, string labelPrefix)\n        {\n            var asmInstructions = method.Maps.SelectMany(map => map.SourceCodes.OfType<Asm>()).ToArray();\n\n            // first of all, we search of referenced addresses (jump|calls)\n            var referencedAddresses = new HashSet<ulong>();\n            foreach (var asm in asmInstructions)\n                if (asm.ReferencedAddress != null)\n                {\n                    referencedAddresses.Add(asm.ReferencedAddress.Value);\n                }\n\n            // for every IP that is referenced, we emit a unique label\n            var addressesToLabels = new Dictionary<ulong, string>();\n            int currentLabelIndex = 0;\n            foreach (var instruction in asmInstructions)\n                if (referencedAddresses.Contains(instruction.InstructionPointer) && !addressesToLabels.ContainsKey(instruction.InstructionPointer))\n                    addressesToLabels.Add(instruction.InstructionPointer, $\"{labelPrefix}_L{currentLabelIndex++:00}\");\n\n            var formatterWithLabelsSymbols = config.GetFormatterWithSymbolSolver(addressesToLabels);\n            var formatterWithGlobalSymbols = config.GetFormatterWithSymbolSolver(disassemblyResult.AddressToNameMapping);\n\n            var prettified = new List<Element>();\n            foreach (var map in method.Maps)\n                foreach (var instruction in map.SourceCodes)\n                {\n                    if (instruction is Sharp sharp)\n                    {\n                        prettified.Add(new Element(sharp.Text, sharp));\n                    }\n                    else if (instruction is MonoCode mono)\n                    {\n                        prettified.Add(new Element(mono.Text, mono));\n                    }\n                    else if (instruction is Asm asm)\n                    {\n                        // this IP is referenced by some jump|call, so we add a label\n                        if (addressesToLabels.TryGetValue(asm.InstructionPointer, out var label))\n                        {\n                            prettified.Add(new Label(label));\n                        }\n\n                        if (asm.ReferencedAddress != null)\n                        {\n                            ulong referencedAddress = asm.ReferencedAddress.Value;\n                            // jump or a call within same method\n                            if (addressesToLabels.TryGetValue(referencedAddress, out var translated))\n                            {\n                                prettified.Add(new Reference(CodeFormatter.Format(asm, formatterWithLabelsSymbols, config.PrintInstructionAddresses, disassemblyResult.PointerSize, addressesToLabels), translated, asm));\n                                continue;\n                            }\n\n                            // call to a known method\n                            if (disassemblyResult.AddressToNameMapping.TryGetValue(referencedAddress, out string? referencedName))\n                            {\n                                string comment = string.Empty;\n                                if (asm.IsReferencedAddressIndirect)\n                                {\n                                    comment = \"; \" + referencedName;\n                                }\n                                prettified.Add(new Element(CodeFormatter.Format(asm, formatterWithGlobalSymbols, config.PrintInstructionAddresses, disassemblyResult.PointerSize, disassemblyResult.AddressToNameMapping) + comment, asm));\n                                continue;\n                            }\n                        }\n\n                        prettified.Add(new Element(CodeFormatter.Format(asm, formatterWithGlobalSymbols, config.PrintInstructionAddresses, disassemblyResult.PointerSize, disassemblyResult.AddressToNameMapping), asm));\n                    }\n                }\n\n            return prettified;\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Disassemblers/Exporters/GithubMarkdownDiffDisassemblyExporter.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Text;\nusing BenchmarkDotNet.Diagnosers;\nusing BenchmarkDotNet.Exporters;\nusing BenchmarkDotNet.Helpers;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Running;\n\nnamespace BenchmarkDotNet.Disassemblers.Exporters\n{\n    internal class GithubMarkdownDiffDisassemblyExporter : ExporterBase\n    {\n        private readonly IReadOnlyDictionary<BenchmarkCase, DisassemblyResult> results;\n        private readonly DisassemblyDiagnoserConfig config;\n\n        protected override string FileExtension => \"md\";\n        protected override string FileCaption => \"asm.pretty.diff\";\n\n        internal GithubMarkdownDiffDisassemblyExporter(IReadOnlyDictionary<BenchmarkCase, DisassemblyResult> results, DisassemblyDiagnoserConfig config)\n        {\n            this.results = results;\n            this.config = config;\n        }\n\n        public override void ExportToLog(Summary summary, ILogger logger)\n        {\n            var benchmarksCases = summary.BenchmarksCases.Where(results.ContainsKey).ToArray();\n\n            logger.WriteLine($\"## {summary.Title}\");\n            for (int i = 0; i < benchmarksCases.Length; i++)\n            {\n                var firstBenchmarkCase = benchmarksCases[i];\n                for (int j = i + 1; j < benchmarksCases.Length; j++)\n                {\n                    var secondBenchmarkCase = benchmarksCases[j];\n\n                    ExportDiff(summary, logger, firstBenchmarkCase, secondBenchmarkCase);\n                }\n            }\n        }\n\n        private void ExportDiff(Summary summary, ILogger logger, BenchmarkCase firstBenchmarkCase, BenchmarkCase secondBenchmarkCase)\n        {\n            // We want to get diff for the same method and different JITs\n            if (firstBenchmarkCase.Descriptor.WorkloadMethod == secondBenchmarkCase.Descriptor.WorkloadMethod)\n            {\n                var firstFileName = SaveDisassemblyResult(summary, results[firstBenchmarkCase]);\n                var secondFileName = SaveDisassemblyResult(summary, results[secondBenchmarkCase]);\n                try\n                {\n                    var builder = new StringBuilder();\n\n                    RunGitDiff(firstFileName, secondFileName, builder);\n\n                    logger.WriteLine($\"**Diff for {firstBenchmarkCase.Descriptor.WorkloadMethod.Name} method between:**\");\n                    logger.WriteLine($\"{GetImportantInfo(summary[firstBenchmarkCase]!)}\");\n                    logger.WriteLine($\"{GetImportantInfo(summary[secondBenchmarkCase]!)}\");\n\n                    logger.WriteLine(\"```diff\");\n                    logger.WriteLine(builder.ToString().Trim());\n                    logger.WriteLine(\"```\");\n                }\n                finally\n                {\n                    File.Delete(firstFileName);\n                    File.Delete(secondFileName);\n                }\n            }\n        }\n\n        private string SaveDisassemblyResult(Summary summary, DisassemblyResult disassemblyResult)\n        {\n            string filePath = $\"{Path.Combine(summary.ResultsDirectoryPath, Guid.NewGuid().ToString())}-diff.temp\";\n\n            if (File.Exists(filePath))\n                File.Delete(filePath);\n\n            using (var stream = new StreamWriter(filePath, append: false))\n            {\n                using (var streamLogger = new StreamLogger(stream))\n                {\n                    GithubMarkdownDisassemblyExporter.Export(streamLogger, disassemblyResult, config, quotingCode: false);\n                }\n            }\n\n            return filePath;\n        }\n\n        private static string GetImportantInfo(BenchmarkReport benchmarkReport) =>\n            $\"{benchmarkReport.GetRuntimeInfo()} (Job: {benchmarkReport.BenchmarkCase.Job.DisplayInfo})\";\n\n        private static void RunGitDiff(string firstFile, string secondFile, StringBuilder result)\n        {\n            try\n            {\n                (int exitCode, IReadOnlyList<string> output) = ProcessHelper.RunAndReadOutputLineByLine(\"git\", $\"diff --no-index --no-color --text --function-context {firstFile} {secondFile}\");\n\n                bool canRead = false;\n\n                foreach (string line in output)\n                {\n                    if (!string.IsNullOrEmpty(line) && line.Contains(\"@@\"))\n                    {\n                        canRead = true;\n                        continue;\n                    }\n\n                    if (canRead)\n                    {\n                        result.AppendLine(line);\n                    }\n                }\n            }\n            catch (Exception ex)\n            {\n                result.AppendLine(\"An exception occurred during run Git. Please check if you have Git installed on your system and Git is added to PATH.\");\n                result.AppendLine($\"Exception: {ex.Message}\");\n            }\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Disassemblers/Exporters/GithubMarkdownDisassemblyExporter.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Linq;\nusing BenchmarkDotNet.Diagnosers;\nusing BenchmarkDotNet.Exporters;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Running;\n\nnamespace BenchmarkDotNet.Disassemblers.Exporters\n{\n    internal class GithubMarkdownDisassemblyExporter : ExporterBase\n    {\n        private readonly IReadOnlyDictionary<BenchmarkCase, DisassemblyResult> results;\n        private readonly DisassemblyDiagnoserConfig config;\n\n        internal GithubMarkdownDisassemblyExporter(IReadOnlyDictionary<BenchmarkCase, DisassemblyResult> results, DisassemblyDiagnoserConfig config)\n        {\n            this.results = results;\n            this.config = config;\n        }\n\n        protected override string FileExtension => \"md\";\n        protected override string FileCaption => \"asm\";\n\n        public override void ExportToLog(Summary summary, ILogger logger)\n        {\n            foreach (var benchmarkCase in summary.BenchmarksCases.Where(results.ContainsKey))\n            {\n                logger.WriteLine($\"## {summary[benchmarkCase]!.GetRuntimeInfo()} (Job: {benchmarkCase.Job.DisplayInfo})\");\n                logger.WriteLine();\n\n                Export(logger, results[benchmarkCase], config);\n            }\n        }\n\n        internal static void Export(ILogger logger, DisassemblyResult disassemblyResult, DisassemblyDiagnoserConfig config, bool quotingCode = true)\n        {\n            int methodIndex = 0;\n            foreach (var method in disassemblyResult.Methods.Where(method => method.Problem.IsBlank()))\n            {\n                if (quotingCode)\n                {\n                    logger.WriteLine(\"```assembly\");\n                }\n\n                logger.WriteLine($\"; {method.Name}\");\n\n                var pretty = DisassemblyPrettifier.Prettify(method, disassemblyResult, config, $\"M{methodIndex++:00}\");\n\n                ulong totalSizeInBytes = 0;\n                foreach (var element in pretty)\n                {\n                    if (element is DisassemblyPrettifier.Label label)\n                    {\n                        logger.WriteLine($\"{label.TextRepresentation}:\");\n                    }\n                    else if (element.Source is Sharp sharp)\n                    {\n                        logger.WriteLine($\"; {sharp.Text.Replace(\"\\n\", \"\\n; \")}\"); // they are multiline and we need to add ; for each line\n                    }\n                    else if (element.Source is Asm asm)\n                    {\n                        checked\n                        {\n                            totalSizeInBytes += (uint)asm.InstructionLength;\n                        }\n\n                        logger.WriteLine($\"       {element.TextRepresentation}\");\n                    }\n                    else if (element.Source is MonoCode mono)\n                    {\n                        logger.WriteLine(mono.Text);\n                    }\n                }\n\n                logger.WriteLine($\"; Total bytes of code {totalSizeInBytes}\");\n                if (quotingCode)\n                {\n                    logger.WriteLine(\"```\");\n                }\n            }\n\n            foreach (var withProblems in disassemblyResult.Methods\n                .Where(method => method.Problem.IsNotBlank())\n                .GroupBy(method => method.Problem))\n            {\n                logger.WriteLine($\"**{withProblems.Key}**\");\n                foreach (var withProblem in withProblems)\n                {\n                    logger.WriteLine(withProblem.Name);\n                }\n            }\n\n            logger.WriteLine();\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Disassemblers/Exporters/HtmlDisassemblyExporter.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing BenchmarkDotNet.Diagnosers;\nusing BenchmarkDotNet.Exporters;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Helpers;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Running;\n\nnamespace BenchmarkDotNet.Disassemblers.Exporters\n{\n    internal class HtmlDisassemblyExporter : ExporterBase\n    {\n        private static readonly Lazy<string> HighlightingLabelsScript = new Lazy<string>(() => ResourceHelper.LoadTemplate(\"highlightingLabelsScript.js\"));\n\n        private readonly IReadOnlyDictionary<BenchmarkCase, DisassemblyResult> results;\n        private readonly DisassemblyDiagnoserConfig config;\n\n        internal HtmlDisassemblyExporter(IReadOnlyDictionary<BenchmarkCase, DisassemblyResult> results, DisassemblyDiagnoserConfig config)\n        {\n            this.results = results;\n            this.config = config;\n        }\n\n        protected override string FileExtension => \"html\";\n        protected override string FileCaption => \"asm\";\n\n        public override void ExportToLog(Summary summary, ILogger logger)\n        {\n            logger.WriteLine(\"<!DOCTYPE html><html lang='en'><head><meta charset='utf-8' /><head>\");\n            logger.WriteLine($\"<title>Pretty Output of DisassemblyDiagnoser for {summary.Title}</title>\");\n            logger.WriteLine(InstructionPointerExporter.CssStyle);\n            logger.WriteLine(@\"\n<style type='text/css'>\n    td.label:hover { cursor: pointer; background-color: yellow !important; }\n    td.highlighted { background-color: yellow !important; }\n</style></head><body>\");\n            logger.WriteLine(\"<script src=\\\"https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.2.1.min.js\\\"></script>\");\n            logger.WriteLine($\"<script>{HighlightingLabelsScript.Value}</script>\");\n\n            int referenceIndex = 0;\n\n            foreach (var benchmarkCase in summary.BenchmarksCases.Where(results.ContainsKey))\n            {\n                Export(logger, summary, results[benchmarkCase], benchmarkCase, ref referenceIndex);\n            }\n\n            logger.WriteLine(\"</body></html>\");\n        }\n\n        private void Export(ILogger logger, Summary summary, DisassemblyResult disassemblyResult, BenchmarkCase benchmarkCase, ref int referenceIndex)\n        {\n            logger.WriteLine($\"<h2>{summary[benchmarkCase]!.GetRuntimeInfo()}</h2>\");\n            logger.WriteLine($\"<h3>Job: {benchmarkCase.Job.DisplayInfo}</h3>\");\n            logger.WriteLine(\"<table><tbody>\");\n\n            int methodIndex = 0;\n            foreach (var method in disassemblyResult.Methods.Where(method => method.Problem.IsBlank()))\n            {\n                referenceIndex++;\n                logger.WriteLine($\"<tr><th colspan=\\\"2\\\" style=\\\"text-align: left;\\\">{method.Name}</th><th></th></tr>\");\n\n                var pretty = DisassemblyPrettifier.Prettify(method, disassemblyResult, config, $\"M{methodIndex++:00}\");\n\n                bool even = false, diffTheLabels = pretty.Count > 1;\n                foreach (var element in pretty)\n                {\n                    if (element is DisassemblyPrettifier.Label label)\n                    {\n                        even = !even;\n\n                        logger.WriteLine($\"<tr class=\\\"{(even && diffTheLabels ? \"evenMap\" : string.Empty)}\\\">\");\n                        logger.WriteLine($\"<td id=\\\"{referenceIndex}_{label.Id}\\\" class=\\\"label\\\" data-label=\\\"{referenceIndex}_{label.TextRepresentation}\\\"><pre><code>{label.TextRepresentation}</pre></code></td>\");\n                        logger.WriteLine(\"<td>&nbsp;</td></tr>\");\n\n                        continue;\n                    }\n\n                    logger.WriteLine($\"<tr class=\\\"{(even && diffTheLabels ? \"evenMap\" : string.Empty)}\\\">\");\n                    logger.Write(\"<td></td>\");\n\n                    if (element is DisassemblyPrettifier.Reference reference)\n                        logger.WriteLine($\"<td id=\\\"{referenceIndex}\\\" class=\\\"reference\\\" data-reference=\\\"{referenceIndex}_{reference.Id}\\\"><a href=\\\"#{referenceIndex}_{reference.Id}\\\"><pre><code>{reference.TextRepresentation}</pre></code></a></td>\");\n                    else\n                        logger.WriteLine($\"<td><pre><code>{element.TextRepresentation}</pre></code></td>\");\n\n                    logger.Write(\"</tr>\");\n                }\n\n                logger.WriteLine(\"<tr><td colspan=\\\"{2}\\\">&nbsp;</td></tr>\");\n            }\n\n            foreach (var withProblems in disassemblyResult.Methods\n                .Where(method => method.Problem.IsNotBlank())\n                .GroupBy(method => method.Problem))\n            {\n                logger.WriteLine($\"<tr><td colspan=\\\"{2}\\\"><b>{withProblems.Key}</b></td></tr>\");\n                foreach (var withProblem in withProblems)\n                {\n                    logger.WriteLine($\"<tr><td colspan=\\\"{2}\\\">{withProblem.Name}</td></tr>\");\n                }\n                logger.WriteLine(\"<tr><td colspan=\\\"{2}\\\"></td></tr>\");\n            }\n\n            logger.WriteLine(\"</tbody></table>\");\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Disassemblers/Exporters/SymbolResolver.cs",
    "content": "﻿using Iced.Intel;\nusing System.Collections.Generic;\n\nnamespace BenchmarkDotNet.Disassemblers.Exporters\n{\n    internal sealed class SymbolResolver : ISymbolResolver\n    {\n        private readonly IReadOnlyDictionary<ulong, string> _mappings;\n\n        public SymbolResolver(IReadOnlyDictionary<ulong, string> mappings) => _mappings = mappings;\n\n        public bool TryGetSymbol(in Instruction instruction, int operand, int instructionOperand, ulong address, int addressSize, out SymbolResult symbol)\n        {\n            if (_mappings.TryGetValue(address, out var text))\n            {\n                symbol = new SymbolResult(address, text);\n                return true;\n            }\n\n            symbol = default;\n            return false;\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Disassemblers/InstructionFormatter.cs",
    "content": "﻿using Iced.Intel;\nusing System;\nusing System.Collections.Generic;\n\nnamespace BenchmarkDotNet.Disassemblers\n{\n    internal static class CodeFormatter\n    {\n        internal static string Format(SourceCode sourceCode, Formatter formatter, bool printInstructionAddresses, uint pointerSize, IReadOnlyDictionary<ulong, string> symbols)\n            => sourceCode switch\n            {\n                IntelAsm intel => IntelInstructionFormatter.Format(intel.Instruction, formatter, printInstructionAddresses, pointerSize),\n                Arm64Asm arm64 => Arm64InstructionFormatter.Format(arm64, formatter.Options, printInstructionAddresses, pointerSize, symbols),\n                Sharp sharp => sharp.Text,\n                MonoCode mono => mono.Text,\n                _ => throw new NotSupportedException(),\n            };\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Disassemblers/IntelDisassembler.cs",
    "content": "﻿using BenchmarkDotNet.Diagnosers;\nusing Iced.Intel;\nusing Microsoft.Diagnostics.Runtime;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\n\nnamespace BenchmarkDotNet.Disassemblers\n{\n    internal class IntelDisassembler : ClrMdDisassembler\n    {\n        internal sealed class RuntimeSpecificData\n        {\n            // See dotnet/runtime src/coreclr/vm/amd64/thunktemplates.asm/.S for the stub code\n            // mov    rax,QWORD PTR [rip + DATA_SLOT(CallCountingStub, RemainingCallCountCell)]\n            // dec    WORD PTR [rax]\n            // je     LOCAL_LABEL(CountReachedZero)\n            // jmp    QWORD PTR [rip + DATA_SLOT(CallCountingStub, TargetForMethod)]\n            // LOCAL_LABEL(CountReachedZero):\n            // jmp    QWORD PTR [rip + DATA_SLOT(CallCountingStub, TargetForThresholdReached)]\n            internal readonly byte[] callCountingStubTemplate = [0x48, 0x8b, 0x05, 0xf9, 0x0f, 0x00, 0x00, 0x66, 0xff, 0x08];\n            // mov    r10, [rip + DATA_SLOT(StubPrecode, MethodDesc)]\n            // jmp    [rip + DATA_SLOT(StubPrecode, Target)]\n            internal readonly byte[] stubPrecodeTemplate = [0x4c, 0x8b, 0x15, 0xf9, 0x0f, 0x00, 0x00, 0xff, 0x25, 0xfb, 0x0f, 0x00, 0x00];\n            // jmp    [rip + DATA_SLOT(FixupPrecode, Target)]\n            // mov    r10, [rip + DATA_SLOT(FixupPrecode, MethodDesc)]\n            // jmp    [rip + DATA_SLOT(FixupPrecode, PrecodeFixupThunk)]\n            internal readonly byte[] fixupPrecodeTemplate = [0xff, 0x25, 0xfa, 0x0f, 0x00, 0x00, 0x4c, 0x8b, 0x15, 0xfb, 0x0f, 0x00, 0x00, 0xff, 0x25, 0xfd, 0x0f, 0x00, 0x00];\n            internal readonly ulong stubPageSize;\n\n            internal RuntimeSpecificData(State state)\n            {\n                stubPageSize = (ulong)Environment.SystemPageSize;\n                if (state.RuntimeVersion.Major >= 8)\n                {\n                    // In .NET 8, the stub page size was changed to 16kB\n                    stubPageSize = 16384;\n                    // Update the templates so that the offsets are correct\n                    callCountingStubTemplate[4] = 0x3f;\n                    stubPrecodeTemplate[4] = 0x3f;\n                    stubPrecodeTemplate[10] = 0x3f;\n                    fixupPrecodeTemplate[3] = 0x3f;\n                    fixupPrecodeTemplate[10] = 0x3f;\n                    fixupPrecodeTemplate[16] = 0x3f;\n                }\n            }\n        }\n\n        private static readonly Dictionary<Version, RuntimeSpecificData> runtimeSpecificData = [];\n\n        protected override IEnumerable<Asm> Decode(byte[] code, ulong startAddress, State state, int depth, ClrMethod currentMethod, DisassemblySyntax syntax)\n        {\n            if (!runtimeSpecificData.TryGetValue(state.RuntimeVersion, out var data))\n            {\n                runtimeSpecificData.Add(state.RuntimeVersion, data = new RuntimeSpecificData(state));\n            }\n\n            var reader = new ByteArrayCodeReader(code);\n            var decoder = Decoder.Create(state.Runtime.DataTarget.DataReader.PointerSize * 8, reader);\n            decoder.IP = startAddress;\n\n            while (reader.CanReadByte)\n            {\n                decoder.Decode(out var instruction);\n\n                bool isIndirect = instruction.IsCallFarIndirect || instruction.IsCallNearIndirect || instruction.IsJmpFarIndirect || instruction.IsJmpNearIndirect;\n                bool isPrestubMD = false;\n\n                ulong address = 0;\n                if (TryGetReferencedAddress(instruction, (uint)state.Runtime.DataTarget.DataReader.PointerSize, out address))\n                {\n                    if (isIndirect)\n                    {\n                        address = state.Runtime.DataTarget.DataReader.ReadPointer(address);\n                        if (state.RuntimeVersion.Major >= 7)\n                        {\n                            // Check if the target is a known stub\n                            // The stubs are allocated in interleaved code / data pages in memory. The data part of the stub\n                            // is at an address one memory page higher than the code.\n                            byte[] buffer = new byte[10];\n\n                            FlushCachedDataIfNeeded(state.Runtime.DataTarget.DataReader, address, buffer);\n\n                            if (state.Runtime.DataTarget.DataReader.Read(address, buffer) == buffer.Length && buffer.SequenceEqual(data.callCountingStubTemplate))\n                            {\n                                const ulong TargetMethodAddressSlotOffset = 8;\n                                address = state.Runtime.DataTarget.DataReader.ReadPointer(address + data.stubPageSize + TargetMethodAddressSlotOffset);\n                            }\n                            else\n                            {\n                                buffer = new byte[13];\n                                if (state.Runtime.DataTarget.DataReader.Read(address, buffer) == buffer.Length && buffer.SequenceEqual(data.stubPrecodeTemplate))\n                                {\n                                    const ulong MethodDescSlotOffset = 0;\n                                    address = state.Runtime.DataTarget.DataReader.ReadPointer(address + data.stubPageSize + MethodDescSlotOffset);\n                                    isPrestubMD = true;\n                                }\n                                else\n                                {\n                                    buffer = new byte[19];\n                                    if (state.Runtime.DataTarget.DataReader.Read(address, buffer) == buffer.Length && buffer.SequenceEqual(data.fixupPrecodeTemplate))\n                                    {\n                                        const ulong MethodDescSlotOffset = 8;\n                                        address = state.Runtime.DataTarget.DataReader.ReadPointer(address + data.stubPageSize + MethodDescSlotOffset);\n                                        isPrestubMD = true;\n                                    }\n\n                                }\n                            }\n                        }\n                    }\n                    TryTranslateAddressToName(address, isPrestubMD, state, depth, currentMethod);\n                }\n\n                yield return new IntelAsm\n                {\n                    InstructionPointer = instruction.IP,\n                    InstructionLength = instruction.Length,\n                    Instruction = instruction,\n                    ReferencedAddress = (address > ushort.MaxValue) ? address : null,\n                    IsReferencedAddressIndirect = isIndirect,\n                };\n            }\n        }\n\n        private static bool TryGetReferencedAddress(Instruction instruction, uint pointerSize, out ulong referencedAddress)\n        {\n            for (int i = 0; i < instruction.OpCount; i++)\n            {\n                switch (instruction.GetOpKind(i))\n                {\n                    case OpKind.NearBranch16:\n                    case OpKind.NearBranch32:\n                    case OpKind.NearBranch64:\n                        referencedAddress = instruction.NearBranchTarget;\n                        return referencedAddress > ushort.MaxValue;\n                    case OpKind.Immediate16:\n                    case OpKind.Immediate8to16:\n                    case OpKind.Immediate8to32:\n                    case OpKind.Immediate8to64:\n                    case OpKind.Immediate32to64:\n                    case OpKind.Immediate32 when pointerSize == 4:\n                    case OpKind.Immediate64:\n                        referencedAddress = instruction.GetImmediate(i);\n                        return referencedAddress > ushort.MaxValue;\n                    case OpKind.Memory when instruction.IsIPRelativeMemoryOperand:\n                        referencedAddress = instruction.IPRelativeMemoryAddress;\n                        return referencedAddress > ushort.MaxValue;\n                    case OpKind.Memory:\n                        referencedAddress = instruction.MemoryDisplacement64;\n                        return referencedAddress > ushort.MaxValue;\n                }\n            }\n\n            referencedAddress = default;\n            return false;\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Disassemblers/IntelInstructionFormatter.cs",
    "content": "﻿using Iced.Intel;\n\nnamespace BenchmarkDotNet.Disassemblers\n{\n    internal static class IntelInstructionFormatter\n    {\n        internal static string Format(Instruction instruction, Formatter formatter, bool printInstructionAddresses, uint pointerSize)\n        {\n            var output = new StringOutput();\n\n            if (printInstructionAddresses)\n            {\n                FormatInstructionPointer(instruction, formatter, pointerSize, output);\n            }\n\n            formatter.Format(instruction, output);\n\n            return output.ToString();\n        }\n\n        private static void FormatInstructionPointer(Instruction instruction, Formatter formatter, uint pointerSize, StringOutput output)\n        {\n            string ipFormat = formatter.Options.LeadingZeroes\n                ? pointerSize == 4 ? \"X8\" : \"X16\"\n                : \"X\";\n\n            output.Write(instruction.IP.ToString(ipFormat), FormatterTextKind.Text);\n            output.Write(\" \", FormatterTextKind.Text);\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Disassemblers/MonoDisassembler.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Diagnostics.CodeAnalysis;\nusing System.Linq;\nusing System.Reflection;\nusing System.Text.RegularExpressions;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Helpers;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Portability;\nusing BenchmarkDotNet.Running;\n\nnamespace BenchmarkDotNet.Disassemblers\n{\n    internal sealed class MonoDisassembler\n    {\n        internal DisassemblyResult Disassemble(BenchmarkCase benchmarkCase, MonoRuntime mono)\n        {\n            Debug.Assert(!RuntimeInformation.IsMono, \"Must never be called for Non-Mono benchmarks\");\n\n            var benchmarkTarget = benchmarkCase.Descriptor;\n            string fqnMethod = GetMethodName(benchmarkTarget);\n            string llvmFlag = GetLlvmFlag(benchmarkCase.Job);\n            string exePath = benchmarkTarget.Type.GetTypeInfo().Assembly.Location;\n\n            var environmentVariables = new Dictionary<string, string> { [\"MONO_VERBOSE_METHOD\"] = fqnMethod };\n            string monoPath = mono.CustomPath.IsNotBlank() ? mono.CustomPath : \"mono\";\n            string arguments = $\"--compile {fqnMethod} {llvmFlag} {exePath}\";\n\n            var (exitCode, output) = ProcessHelper.RunAndReadOutputLineByLine(monoPath, arguments, environmentVariables: environmentVariables, includeErrors: true);\n            string commandLine = $\"{GetEnvironmentVariables(environmentVariables)} {monoPath} {arguments}\";\n\n            return OutputParser.Parse(output, benchmarkTarget.WorkloadMethod.Name, commandLine);\n        }\n\n        private static string GetEnvironmentVariables(Dictionary<string, string> environmentVariables)\n            => string.Join(\" \", environmentVariables.Select(e => $\"{e.Key}={e.Value}\"));\n\n        private static string GetMethodName(Descriptor descriptor)\n            => $\"{descriptor.Type.GetTypeInfo().Namespace}.{descriptor.Type.GetTypeInfo().Name}:{descriptor.WorkloadMethod.Name}\";\n\n        // TODO: use resolver\n        // TODO: introduce a global helper method for LlvmFlag\n        private static string GetLlvmFlag(Job job) =>\n            job.ResolveValue(EnvironmentMode.JitCharacteristic, Jit.Default) == Jit.Llvm ? \"--llvm\" : \"--nollvm\";\n\n        internal static class OutputParser\n        {\n            internal static DisassemblyResult Parse(IReadOnlyList<string> input, string methodName, string commandLine)\n            {\n                var instructions = new List<MonoCode>();\n\n                const string windowsHeader = \"Disassembly of section .text:\";\n                const string macOSXHeader = \"(__TEXT,__text) section\";\n                const string windowsWarning = \"is not recognized as an internal or external command\";\n\n                var warningLines = input\n                    .Where(line => line.Contains(windowsWarning))\n                    .Select(line => line.Trim(' ', '.', ','))\n                    .ToList();\n                if (warningLines.Count > 0)\n                {\n                    string message = \"It's impossible to get Mono disasm because you don't have some required tools:\"\n                                     + Environment.NewLine\n                                     + string.Join(Environment.NewLine, warningLines);\n                    return CreateErrorResult(input, methodName, commandLine, message);\n                }\n\n                if (!input.Any(line => line.Contains(windowsHeader) || line.Contains(macOSXHeader)))\n                    return CreateErrorResult(input, methodName, commandLine, \"It's impossible to find assembly instructions in the mono output\");\n\n                var listing = input\n                    .SkipWhile(line => !line.Contains(macOSXHeader) && !line.Contains(windowsHeader))\n                    .Where(line => line.IsNotBlank())\n                    .Skip(2);\n\n                foreach (string line in listing)\n                    if (TryParseInstruction(line, out var instruction))\n                        instructions.Add(instruction);\n\n                while (instructions.Any() && instructions.Last().Text == \"nop\")\n                    instructions.RemoveAt(instructions.Count - 1);\n\n                return new DisassemblyResult\n                {\n                    Methods =\n                    [\n                        new DisassembledMethod\n                        {\n                            Name = methodName,\n                            Maps = [new Map { SourceCodes = instructions.ToArray() }],\n                            CommandLine = commandLine,\n                        },\n                    ]\n                };\n            }\n\n            private static DisassemblyResult CreateErrorResult(IReadOnlyList<string> input,\n                string methodName, string commandLine, string message)\n            {\n                return new DisassemblyResult\n                {\n                    Methods =\n                    [\n                        new DisassembledMethod\n                        {\n                            Name = methodName,\n                            Maps =\n                            [\n                                new Map\n                                {\n                                    SourceCodes = input\n                                        .Where(line => line.IsNotBlank())\n                                        .Select(line => new MonoCode { Text = line })\n                                        .ToArray()\n                                }\n                            ],\n                            CommandLine = commandLine\n                        }\n                    ],\n                    Errors = [message],\n                };\n            }\n\n            //line example 1:  0:   48 83 ec 28             sub    $0x28,%rsp\n            //line example 2: 0000000000000000  subq    $0x28, %rsp\n            private static readonly Regex InstructionRegex = new Regex(@\"\\s*(?<address>[0-9a-f]+)(\\:\\s+([0-9a-f]{2}\\s+)+)?\\s+(?<instruction>.*)\\s*\", RegexOptions.Compiled);\n\n            private static bool TryParseInstruction(string line, [NotNullWhen(true)] out MonoCode? instruction)\n            {\n                instruction = null;\n                var match = InstructionRegex.Match(line);\n                if (!match.Success)\n                    return false;\n\n                instruction = new MonoCode { Text = match.Groups[\"instruction\"].ToString() };\n                return true;\n            }\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Disassemblers/SourceCodeProvider.cs",
    "content": "﻿using BenchmarkDotNet.Extensions;\nusing Microsoft.Diagnostics.Runtime;\nusing Microsoft.Diagnostics.Symbols;\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.IO;\n\nnamespace BenchmarkDotNet.Disassemblers\n{\n    internal class SourceCodeProvider : IDisposable\n    {\n        private readonly Dictionary<SourceFile, string[]> sourceFileCache = [];\n        private readonly Dictionary<SourceFile, string> sourceFilePathsCache = [];\n        private readonly Dictionary<PdbInfo, ManagedSymbolModule?> pdbReaders = [];\n        private readonly SymbolReader symbolReader = new SymbolReader(TextWriter.Null) { SymbolPath = SymbolPath.MicrosoftSymbolServerPath };\n\n        public void Dispose()\n        {\n            symbolReader.Dispose();\n        }\n\n        internal IEnumerable<Sharp> GetSource(ClrMethod method, ILToNativeMap map)\n        {\n            var sourceLocation = GetSourceLocation(method, map.ILOffset);\n            if (sourceLocation is not { LineNumber: > 0 })\n                yield break;\n\n            for (int line = sourceLocation.LineNumber; line <= sourceLocation.LineNumberEnd; ++line)\n            {\n                var sourceLine = ReadSourceLine(sourceLocation.SourceFile, line);\n                if (sourceLine == null)\n                    continue;\n\n                var text = sourceLine + Environment.NewLine\n                    + GetSmartPointer(sourceLine,\n                        start: line == sourceLocation.LineNumber ? sourceLocation.ColumnNumber - 1 : default(int?),\n                        end: line == sourceLocation.LineNumberEnd ? sourceLocation.ColumnNumberEnd - 1 : default(int?));\n\n                yield return new Sharp\n                {\n                    Text = text,\n                    InstructionPointer = map.StartAddress,\n                    FilePath = GetFilePath(sourceLocation.SourceFile),\n                    LineNumber = line\n                };\n            }\n        }\n\n        private string GetFilePath(SourceFile sourceFile)\n            => sourceFilePathsCache.TryGetValue(sourceFile, out var filePath) ? filePath : sourceFile.Url;\n\n        private string? ReadSourceLine(SourceFile file, int line)\n        {\n            if (!sourceFileCache.TryGetValue(file, out var contents))\n            {\n                // GetSourceFile method returns path when file is stored on the same machine\n                // otherwise it downloads it from the Symbol Server and returns the source code ;)\n                string wholeFileOrJustPath = file.GetSourceFile();\n\n                if (wholeFileOrJustPath.IsBlank())\n                    return null;\n\n                if (File.Exists(wholeFileOrJustPath))\n                {\n                    contents = File.ReadAllLines(wholeFileOrJustPath);\n                    sourceFilePathsCache.Add(file, wholeFileOrJustPath);\n                }\n                else\n                {\n                    contents = wholeFileOrJustPath.Split([Environment.NewLine], StringSplitOptions.None);\n                }\n\n                sourceFileCache.Add(file, contents);\n            }\n\n            return line - 1 < contents.Length\n                ? contents[line - 1]\n                : null; // \"nop\" can have no corresponding c# code ;)\n        }\n\n        private static string GetSmartPointer(string sourceLine, int? start, int? end)\n        {\n            Debug.Assert(start is null || start < sourceLine.Length);\n            Debug.Assert(end is null || end <= sourceLine.Length);\n\n            var prefix = new char[end ?? sourceLine.Length];\n            var index = 0;\n\n            // write offset using whitespaces\n            while (index < (start ?? prefix.Length))\n            {\n                prefix[index] =\n                    sourceLine.Length > index &&\n                    sourceLine[index] == '\\t'\n                    ? '\\t'\n                    : ' ';\n                index++;\n            }\n\n            // write smart pointer\n            while (index < prefix.Length)\n            {\n                prefix[index] = '^';\n                index++;\n            }\n\n            return new string(prefix);\n        }\n\n        internal SourceLocation? GetSourceLocation(ClrMethod method, int ilOffset)\n        {\n            var reader = GetReaderForMethod(method);\n            if (reader == null)\n                return null;\n\n            return reader.SourceLocationForManagedCode((uint)method.MetadataToken, ilOffset);\n        }\n\n        private ManagedSymbolModule? GetReaderForMethod(ClrMethod? method)\n        {\n            ClrModule? module = method?.Type?.Module;\n            PdbInfo? info = module?.Pdb;\n\n            ManagedSymbolModule? reader = null;\n            if (info != null)\n            {\n                if (!pdbReaders.TryGetValue(info, out reader))\n                {\n                    string pdbPath = info.Path;\n                    if (pdbPath != null)\n                    {\n                        try\n                        {\n                            reader = symbolReader.OpenSymbolFile(pdbPath);\n                        }\n                        catch (IOException)\n                        {\n                            // This will typically happen when trying to load information\n                            // from public symbols, or symbol files generated by some weird\n                            // compiler. We can ignore this, but there's no need to load\n                            // this PDB anymore, so we will put null in the dictionary and\n                            // be done with it.\n                            reader = null;\n                        }\n                    }\n\n                    pdbReaders[info] = reader;\n                }\n            }\n\n            return reader;\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Engines/AnonymousPipesHost.cs",
    "content": "﻿using BenchmarkDotNet.Validators;\nusing System;\nusing System.IO;\nusing System.Text;\nusing Microsoft.Win32.SafeHandles;\nusing JetBrains.Annotations;\nusing BenchmarkDotNet.Portability;\nusing System.Runtime.CompilerServices;\n\nnamespace BenchmarkDotNet.Engines\n{\n    public class AnonymousPipesHost : IHost\n    {\n        internal const string AnonymousPipesDescriptors = \"--anonymousPipes\";\n        internal static readonly Encoding UTF8NoBOM = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true);\n\n        private readonly StreamWriter outWriter;\n        private readonly StreamReader inReader;\n\n        public AnonymousPipesHost(string writHandle, string readHandle)\n        {\n            outWriter = new StreamWriter(OpenAnonymousPipe(writHandle, FileAccess.Write), UTF8NoBOM);\n            // Flush the data to the Stream after each write, otherwise the host process will wait for input endlessly!\n            outWriter.AutoFlush = true;\n            inReader = new StreamReader(OpenAnonymousPipe(readHandle, FileAccess.Read), UTF8NoBOM, detectEncodingFromByteOrderMarks: false);\n        }\n\n        private Stream OpenAnonymousPipe(string fileHandle, FileAccess access)\n            => new FileStream(new SafeFileHandle(new IntPtr(int.Parse(fileHandle)), ownsHandle: true), access, bufferSize: 1);\n\n        public void Dispose()\n        {\n            outWriter.Dispose();\n            inReader.Dispose();\n        }\n\n        public void Write(string message) => outWriter.Write(message);\n\n        public void WriteLine() => outWriter.WriteLine();\n\n        [MethodImpl(CodeGenHelper.AggressiveOptimizationOption)]\n        public void WriteLine(string message) => outWriter.WriteLine(message);\n\n        [MethodImpl(CodeGenHelper.AggressiveOptimizationOption)]\n        public void SendSignal(HostSignal hostSignal)\n        {\n            if (hostSignal == HostSignal.AfterAll)\n            {\n                // Before the last signal is reported and the benchmark process exits,\n                // add an artificial sleep to increase the chance of host process reading all std output.\n                System.Threading.Thread.Sleep(1);\n            }\n\n            WriteLine(Engine.Signals.ToMessage(hostSignal));\n\n            // read the response from Parent process, make the communication blocking\n            string? acknowledgment = inReader.ReadLine();\n            if (acknowledgment != Engine.Signals.Acknowledgment\n                && !(acknowledgment is null && hostSignal == HostSignal.AfterAll)) // an early EOF, but still valid\n            {\n                throw new NotSupportedException($\"Unknown Acknowledgment: {acknowledgment}\");\n            }\n        }\n\n        public void SendError(string message) => outWriter.WriteLine($\"{ValidationErrorReporter.ConsoleErrorPrefix} {message}\");\n\n        public void ReportResults(RunResults runResults) => runResults.Print(outWriter);\n\n        [PublicAPI] // called from generated code\n        public static bool TryGetFileHandles(string[] args, out string? writeHandle, out string? readHandle)\n        {\n            for (int i = 0; i < args.Length; i++)\n            {\n                if (args[i] == AnonymousPipesDescriptors)\n                {\n                    writeHandle = args[i + 1]; // IndexOutOfRangeException means a bug (incomplete data)\n                    readHandle = args[i + 2];\n                    return true;\n                }\n            }\n\n            writeHandle = readHandle = null;\n            return false;\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Engines/BenchmarkSignal.cs",
    "content": "﻿using JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Engines;\n\n[UsedImplicitly]\npublic enum BenchmarkSignal\n{\n    /// <summary>\n    /// before the engine is created\n    /// </summary>\n    BeforeEngine,\n\n    /// <inheritdoc cref=\"HostSignal.BeforeActualRun\"/>\n    BeforeActualRun,\n\n    /// <inheritdoc cref=\"HostSignal.AfterActualRun\"/>\n    AfterActualRun,\n\n    /// <inheritdoc cref=\"HostSignal.BeforeExtraIteration\"/>\n    BeforeExtraIteration,\n\n    /// <inheritdoc cref=\"HostSignal.AfterExtraIteration\"/>\n    AfterExtraIteration,\n\n    /// <summary>\n    /// after the engine has completed the run\n    /// </summary>\n    AfterEngine,\n\n    /// <summary>\n    /// used to run some code independent of the benchmarks\n    /// </summary>\n    SeparateLogic,\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Engines/Consumer.cs",
    "content": "﻿using System;\nusing System.Runtime.CompilerServices;\nusing System.Threading;\nusing JetBrains.Annotations;\n\n// ReSharper disable NotAccessedField.Local\nnamespace BenchmarkDotNet.Engines\n{\n    public class Consumer\n    {\n#pragma warning disable IDE0052 // Remove unread private members\n        private volatile byte byteHolder;\n        private volatile sbyte sbyteHolder;\n        private volatile short shortHolder;\n        private volatile ushort ushortHolder;\n        private volatile int intHolder;\n        private volatile uint uintHolder;\n        private volatile bool boolHolder;\n        private volatile char charHolder;\n        private volatile float floatHolder;\n        private double doubleHolder;\n        private long longHolder;\n        private ulong ulongHolder;\n        private volatile object? objectHolder;\n        private volatile IntPtr ptrHolder;\n        private volatile UIntPtr uptrHolder;\n#pragma warning restore IDE0052 // Remove unread private members\n\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        [PublicAPI]\n        public void Consume(byte byteValue) => byteHolder = byteValue;\n\n        [CLSCompliant(false)]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        [PublicAPI]\n        public void Consume(sbyte sbyteValue) => sbyteHolder = sbyteValue;\n\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        [PublicAPI]\n        public void Consume(short shortValue) => shortHolder = shortValue;\n\n        [CLSCompliant(false)]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        [PublicAPI]\n        public void Consume(ushort ushortValue) => ushortHolder = ushortValue;\n\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        [PublicAPI]\n        public void Consume(int intValue) => intHolder = intValue;\n\n        [CLSCompliant(false)]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        [PublicAPI]\n        public void Consume(uint uintValue) => uintHolder = uintValue;\n\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        [PublicAPI]\n        public void Consume(bool boolValue) => boolHolder = boolValue;\n\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        [PublicAPI]\n        public void Consume(char charValue) => charHolder = charValue;\n\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        [PublicAPI]\n        public void Consume(float floatValue) => floatHolder = floatValue;\n\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        [PublicAPI]\n        public void Consume(double doubleValue) => Volatile.Write(ref doubleHolder, doubleValue);\n\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        [PublicAPI]\n        public void Consume(long longValue) => Volatile.Write(ref longHolder, longValue);\n\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        [PublicAPI]\n        public void Consume(IntPtr intPtrValue) => ptrHolder = intPtrValue;\n\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        [PublicAPI]\n        public void Consume(UIntPtr uintPtrValue) => uptrHolder = uintPtrValue;\n\n        [CLSCompliant(false)]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        [PublicAPI]\n        public void Consume(ulong ulongValue) => Volatile.Write(ref ulongHolder, ulongValue);\n\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        [PublicAPI]\n        public void Consume(string? stringValue) => Consume((object?)stringValue);\n\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        [PublicAPI]\n        public void Consume(object? objectValue)\n        {\n            // Write to volatile field to prevent dead code elimination and out-of-order execution.\n            objectHolder = objectValue;\n            // Overwrite field to null so we aren't holding onto references to affect GC behavior. (#1942)\n            objectHolder = null;\n        }\n\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        [PublicAPI]\n        public void Consume<T>(T objectValue) where T : class // class constraint prevents from boxing structs\n             => Consume((object) objectValue);\n\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public unsafe void Consume<T>(T* ptrValue) where T : unmanaged => ptrHolder = (IntPtr) ptrValue;\n\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public unsafe void Consume(void* ptrValue) => ptrHolder = (IntPtr) ptrValue;\n\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public void Consume<T>(in T value)\n        {\n            // Suppress CS8600/CS8605 warnings.\n            // Because the value is guaranteed not to be null when comparing typeof(T) with non-nullable type.\n            // And boxing/unboxing is expected to be removed by JIT.\n#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type.\n#pragma warning disable CS8605 // Unboxing a possibly null value.\n            if (typeof(T) == typeof(byte))\n                byteHolder = (byte)(object)value;\n            else if (typeof(T) == typeof(sbyte))\n                sbyteHolder = (sbyte)(object)value;\n            else if (typeof(T) == typeof(short))\n                shortHolder = (short)(object)value;\n            else if (typeof(T) == typeof(ushort))\n                ushortHolder = (ushort)(object)value;\n            else if (typeof(T) == typeof(int))\n                intHolder = (int)(object)value;\n            else if (typeof(T) == typeof(uint))\n                uintHolder = (uint)(object)value;\n            else if (typeof(T) == typeof(bool))\n                boolHolder = (bool)(object)value;\n            else if (typeof(T) == typeof(char))\n                charHolder = (char)(object)value;\n            else if (typeof(T) == typeof(float))\n                floatHolder = (float)(object)value;\n            else if (typeof(T) == typeof(double))\n                Volatile.Write(ref doubleHolder, (double)(object)value);\n            else if (typeof(T) == typeof(long))\n                Volatile.Write(ref longHolder, (long)(object)value);\n            else if (typeof(T) == typeof(ulong))\n                Volatile.Write(ref ulongHolder, (ulong)(object)value);\n#pragma warning restore CS8600\n#pragma warning restore CS8605\n            else if (default(T) == null && !typeof(T).IsValueType)\n                Consume((object?)value);\n            else\n                DeadCodeEliminationHelper.KeepAliveWithoutBoxingReadonly(value); // non-primitive and nullable value types\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Engines/ConsumerExtensions.cs",
    "content": "﻿using System.Collections;\nusing System.Collections.Generic;\nusing System.Linq;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Engines\n{\n    public static class ConsumerExtensions\n    {\n        /// <summary>\n        /// executes and consumes given <see cref=\"IEnumerable\"/>\n        /// <remarks>By using non-generic <see cref=\"IEnumerable\"/> you pay for boxing. Use generic <see cref=\"IEnumerable{T}\"/> if you can.</remarks>\n        /// </summary>\n        /// <param name=\"enumerable\">non-generic <see cref=\"IEnumerable\"/></param>\n        /// <param name=\"consumer\">instance of <see cref=\"Consumer\"/>. Create it on your own once, store it in the field and just pass here</param>\n        [PublicAPI]\n        public static void Consume(this IEnumerable enumerable, Consumer consumer)\n        {\n            foreach (object item in enumerable)\n            {\n                consumer.Consume(item);\n            }\n        }\n\n        /// <summary>\n        /// executes and consumes given <see cref=\"IQueryable\"/>\n        /// <remarks>By using non-generic <see cref=\"IQueryable\"/> you pay for boxing. Use generic <see cref=\"IQueryable{T}\"/> if you can.</remarks>\n        /// </summary>\n        /// <param name=\"queryable\">non-generic <see cref=\"IQueryable\"/></param>\n        /// <param name=\"consumer\">instance of <see cref=\"Consumer\"/>. Create it on your own once, store it in the field and just pass here</param>\n        [PublicAPI]\n        public static void Consume(this IQueryable queryable, Consumer consumer)\n        {\n            foreach (object item in queryable)\n            {\n                consumer.Consume(item);\n            }\n        }\n\n        /// <summary>\n        /// executes and consumes given <see cref=\"IEnumerable{T}\"/>\n        /// </summary>\n        /// <param name=\"enumerable\">generic <see cref=\"IEnumerable{T}\"/></param>\n        /// <param name=\"consumer\">instance of <see cref=\"Consumer\"/>. Create it on your own once, store it in the field and just pass here</param>\n        [PublicAPI]\n        public static void Consume<T>(this IEnumerable<T> enumerable, Consumer consumer)\n        {\n            foreach (T item in enumerable)\n            {\n                consumer.Consume<T>(in item);\n            }\n        }\n\n        /// <summary>\n        /// executes and consumes given <see cref=\"IQueryable{T}\"/>\n        /// </summary>\n        /// <param name=\"queryable\">generic <see cref=\"IQueryable{T}\"/></param>\n        /// <param name=\"consumer\">instance of <see cref=\"Consumer\"/>. Create it on your own once, store it in the field and just pass here</param>\n        [PublicAPI]\n        public static void Consume<T>(this IQueryable<T> queryable, Consumer consumer)\n        {\n            foreach (T item in queryable)\n            {\n                consumer.Consume<T>(in item);\n            }\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Engines/DeadCodeEliminationHelper.cs",
    "content": "﻿using System.Runtime.CompilerServices;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Engines\n{\n    public static class DeadCodeEliminationHelper\n    {\n        /// <summary>\n        /// This method can't get inlined, so any value send to it\n        /// will not get eliminated by the dead code elimination\n        /// </summary>\n        [MethodImpl(MethodImplOptions.NoInlining)]\n        [UsedImplicitly] // Used in generated benchmarks\n        public static void KeepAliveWithoutBoxing<T>(T value) { }\n\n        /// <summary>\n        /// This method can't get inlined, so any value send to it\n        /// will not get eliminated by the dead code elimination\n        /// </summary>\n        [MethodImpl(MethodImplOptions.NoInlining)]\n        [UsedImplicitly] // Used in generated benchmarks\n        public static void KeepAliveWithoutBoxing<T>(ref T value) { }\n\n        /// <summary>\n        /// This method can't get inlined, so any value send to it\n        /// will not get eliminated by the dead code elimination\n        /// it's not called KeepAliveWithoutBoxing because compiler would not be able to diff `ref` and `in`\n        /// </summary>\n        [MethodImpl(MethodImplOptions.NoInlining)]\n        [UsedImplicitly] // Used in generated benchmarks\n        public static void KeepAliveWithoutBoxingReadonly<T>(in T value) { }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Engines/Engine.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Runtime.CompilerServices;\nusing System.Threading;\nusing BenchmarkDotNet.Characteristics;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Portability;\nusing BenchmarkDotNet.Reports;\nusing JetBrains.Annotations;\nusing Perfolizer.Horology;\n\nnamespace BenchmarkDotNet.Engines\n{\n    [UsedImplicitly]\n    public class Engine : IEngine\n    {\n        internal EngineParameters Parameters { get; }\n\n        private IClock Clock { get; }\n        private bool ForceGcCleanups { get; }\n        private bool MemoryRandomization { get; }\n\n        private readonly Random random;\n\n        private IHost Host => Parameters.Host;\n        private Job TargetJob => Parameters.TargetJob;\n        private IResolver Resolver => Parameters.Resolver;\n\n        internal Engine(EngineParameters engineParameters)\n        {\n            // EngineParameters properties are mutable, so we copy/freeze them all.\n            var job = engineParameters.TargetJob ?? throw new ArgumentNullException(nameof(EngineParameters.TargetJob));\n            Parameters = new()\n            {\n                WorkloadActionNoUnroll = engineParameters.WorkloadActionNoUnroll ?? throw new ArgumentNullException(nameof(EngineParameters.WorkloadActionNoUnroll)),\n                WorkloadActionUnroll = engineParameters.WorkloadActionUnroll ?? throw new ArgumentNullException(nameof(EngineParameters.WorkloadActionUnroll)),\n                OverheadActionNoUnroll = engineParameters.OverheadActionNoUnroll ?? throw new ArgumentNullException(nameof(EngineParameters.OverheadActionNoUnroll)),\n                OverheadActionUnroll = engineParameters.OverheadActionUnroll ?? throw new ArgumentNullException(nameof(EngineParameters.OverheadActionUnroll)),\n                GlobalSetupAction = engineParameters.GlobalSetupAction ?? throw new ArgumentNullException(nameof(EngineParameters.GlobalSetupAction)),\n                GlobalCleanupAction = engineParameters.GlobalCleanupAction ?? throw new ArgumentNullException(nameof(EngineParameters.GlobalCleanupAction)),\n                IterationSetupAction = engineParameters.IterationSetupAction ?? throw new ArgumentNullException(nameof(EngineParameters.IterationSetupAction)),\n                IterationCleanupAction = engineParameters.IterationCleanupAction ?? throw new ArgumentNullException(nameof(EngineParameters.IterationCleanupAction)),\n                TargetJob = new Job(job).Freeze(),\n                BenchmarkName = engineParameters.BenchmarkName,\n                RunExtraIteration = engineParameters.RunExtraIteration,\n                Host = engineParameters.Host,\n                OperationsPerInvoke = engineParameters.OperationsPerInvoke,\n                Resolver = engineParameters.Resolver,\n                InProcessDiagnoserHandler = engineParameters.InProcessDiagnoserHandler ?? throw new ArgumentNullException(nameof(EngineParameters.InProcessDiagnoserHandler)),\n            };\n\n            Clock = TargetJob.ResolveValue(InfrastructureMode.ClockCharacteristic, Resolver)!;\n            ForceGcCleanups = TargetJob.ResolveValue(GcMode.ForceCharacteristic, Resolver);\n            MemoryRandomization = TargetJob.ResolveValue(RunMode.MemoryRandomizationCharacteristic, Resolver);\n\n            random = new Random(12345); // we are using constant seed to try to get repeatable results\n        }\n\n        public RunResults Run()\n        {\n            Parameters.GlobalSetupAction.Invoke();\n            bool didThrow = false;\n            try\n            {\n                return RunCore();\n            }\n            catch\n            {\n                didThrow = true;\n                throw;\n            }\n            finally\n            {\n                try\n                {\n                    Parameters.GlobalCleanupAction.Invoke();\n                }\n                // We only catch if the benchmark threw to not overwrite the exception. #1045\n                catch (Exception e) when (didThrow)\n                {\n                    Host.SendError($\"Exception during GlobalCleanup!{Environment.NewLine}{e}\");\n                }\n            }\n        }\n\n        // AggressiveOptimization forces the method to go straight to tier1 JIT, and will never be re-jitted,\n        // eliminating tiered JIT as a potential variable in measurements.\n        [MethodImpl(CodeGenHelper.AggressiveOptimizationOption)]\n        private RunResults RunCore()\n        {\n            var measurements = new List<Measurement>();\n\n            if (EngineEventSource.Log.IsEnabled())\n                EngineEventSource.Log.BenchmarkStart(Parameters.BenchmarkName);\n\n            IterationData extraStatsIterationData = default;\n            // Enumerate the stages and run iterations in a loop to ensure each benchmark invocation is called with a constant stack size.\n            // #1120\n            foreach (var stage in EngineStage.EnumerateStages(Parameters))\n            {\n                if (stage.Stage == IterationStage.Actual && stage.Mode == IterationMode.Workload)\n                {\n                    Host.BeforeMainRun();\n                    Parameters.InProcessDiagnoserHandler.Handle(BenchmarkSignal.BeforeActualRun);\n                }\n\n                var stageMeasurements = stage.GetMeasurementList();\n                while (stage.GetShouldRunIteration(stageMeasurements, out var iterationData))\n                {\n                    var measurement = RunIteration(iterationData);\n                    stageMeasurements.Add(measurement);\n                    // Actual Workload is always the last stage, so we use the same data to run extra stats.\n                    extraStatsIterationData = iterationData;\n                }\n                measurements.AddRange(stageMeasurements);\n\n                Host.WriteLine();\n\n                if (stage.Stage == IterationStage.Actual && stage.Mode == IterationMode.Workload)\n                {\n                    Host.AfterMainRun();\n                    Parameters.InProcessDiagnoserHandler.Handle(BenchmarkSignal.AfterActualRun);\n                }\n            }\n\n            GcStats workGcHasDone = default;\n            if (Parameters.RunExtraIteration)\n            {\n                (workGcHasDone, var extraMeasurement) = RunExtraIteration(extraStatsIterationData);\n                measurements.Add(extraMeasurement);\n            }\n\n            if (EngineEventSource.Log.IsEnabled())\n                EngineEventSource.Log.BenchmarkStop(Parameters.BenchmarkName);\n\n            var outlierMode = TargetJob.ResolveValue(AccuracyMode.OutlierModeCharacteristic, Resolver);\n\n            return new RunResults(measurements, outlierMode, workGcHasDone);\n        }\n\n        [MethodImpl(CodeGenHelper.AggressiveOptimizationOption)]\n        private Measurement RunIteration(IterationData data)\n        {\n            // Initialization\n            long invokeCount = data.invokeCount;\n            int unrollFactor = data.unrollFactor;\n            if (invokeCount % unrollFactor != 0)\n                throw new ArgumentOutOfRangeException(nameof(data), $\"InvokeCount({invokeCount}) should be a multiple of UnrollFactor({unrollFactor}).\");\n\n            long totalOperations = invokeCount * Parameters.OperationsPerInvoke;\n            bool randomizeMemory = data.mode == IterationMode.Workload && MemoryRandomization;\n\n            data.setupAction();\n\n            GcCollect();\n\n            if (EngineEventSource.Log.IsEnabled())\n                EngineEventSource.Log.IterationStart(data.mode, data.stage, totalOperations);\n\n            var clockSpan = randomizeMemory\n                ? MeasureWithRandomStack(data.workloadAction, invokeCount / unrollFactor)\n                : Measure(data.workloadAction, invokeCount / unrollFactor);\n\n            if (EngineEventSource.Log.IsEnabled())\n                EngineEventSource.Log.IterationStop(data.mode, data.stage, totalOperations);\n\n            data.cleanupAction();\n\n            if (randomizeMemory)\n                RandomizeManagedHeapMemory();\n\n            GcCollect();\n\n            // Results\n            var measurement = new Measurement(0, data.mode, data.stage, data.index, totalOperations, clockSpan.GetNanoseconds());\n            Host.WriteLine(measurement.ToString());\n            return measurement;\n        }\n\n        // This is in a separate method, because stackalloc can affect code alignment,\n        // resulting in unexpected measurements on some AMD cpus,\n        // even if the stackalloc branch isn't executed. (#2366)\n        [MethodImpl(MethodImplOptions.NoInlining | CodeGenHelper.AggressiveOptimizationOption)]\n        private unsafe ClockSpan MeasureWithRandomStack(Action<long> action, long invokeCount)\n        {\n            byte* stackMemory = stackalloc byte[random.Next(32)];\n            var clockSpan = Measure(action, invokeCount);\n            Consume(stackMemory);\n            return clockSpan;\n        }\n\n        [MethodImpl(MethodImplOptions.NoInlining | CodeGenHelper.AggressiveOptimizationOption)]\n        private unsafe void Consume(byte* _) { }\n\n        [MethodImpl(MethodImplOptions.NoInlining | CodeGenHelper.AggressiveOptimizationOption)]\n        private ClockSpan Measure(Action<long> action, long invokeCount)\n        {\n            var clock = Clock.Start();\n            action(invokeCount);\n            return clock.GetElapsed();\n        }\n\n        [MethodImpl(CodeGenHelper.AggressiveOptimizationOption)]\n        private (GcStats, Measurement) RunExtraIteration(IterationData data)\n        {\n            // Warm up the GC measurement functions before starting the actual measurement.\n            DeadCodeEliminationHelper.KeepAliveWithoutBoxing(GcStats.ReadInitial());\n            DeadCodeEliminationHelper.KeepAliveWithoutBoxing(GcStats.ReadFinal());\n\n            data.setupAction(); // we run iteration setup first, so even if it allocates, it is not included in the results\n\n            Host.SendSignal(HostSignal.BeforeExtraIteration);\n            Parameters.InProcessDiagnoserHandler.Handle(BenchmarkSignal.BeforeExtraIteration);\n\n            // GC collect before measuring allocations.\n            ForceGcCollect();\n\n            // #1542\n            // If the jit is tiered, we put the current thread to sleep so it can kick in, compile its stuff,\n            // and NOT allocate anything on the background thread when we are measuring allocations.\n            SleepIfPositive(JitInfo.BackgroundCompilationDelay);\n\n            GcStats gcStats;\n            ClockSpan clockSpan;\n            using (FinalizerBlocker.MaybeStart())\n            {\n                (gcStats, clockSpan) = MeasureWithGc(data.workloadAction, data.invokeCount / data.unrollFactor);\n            }\n\n            Parameters.InProcessDiagnoserHandler.Handle(BenchmarkSignal.AfterExtraIteration);\n            Host.SendSignal(HostSignal.AfterExtraIteration);\n\n            data.cleanupAction(); // we run iteration cleanup after diagnosers are complete.\n\n            var totalOperations = data.invokeCount * Parameters.OperationsPerInvoke;\n            var measurement = new Measurement(0, IterationMode.Workload, IterationStage.Extra, 1, totalOperations, clockSpan.GetNanoseconds());\n            Host.WriteLine(measurement.ToString());\n            return (gcStats.WithTotalOperations(totalOperations), measurement);\n        }\n\n        [MethodImpl(CodeGenHelper.AggressiveOptimizationOption)]\n        internal static void SleepIfPositive(TimeSpan timeSpan)\n        {\n            if (timeSpan > TimeSpan.Zero)\n            {\n                Thread.Sleep(timeSpan);\n            }\n        }\n\n        // Isolate the allocation measurement and skip tier0 jit to make sure we don't get any unexpected allocations.\n        [MethodImpl(MethodImplOptions.NoInlining | CodeGenHelper.AggressiveOptimizationOption)]\n        private (GcStats, ClockSpan) MeasureWithGc(Action<long> action, long invokeCount)\n        {\n            var initialGcStats = GcStats.ReadInitial();\n            var clockSpan = Measure(action, invokeCount);\n            var finalGcStats = GcStats.ReadFinal();\n            return (finalGcStats - initialGcStats, clockSpan);\n        }\n\n        [MethodImpl(CodeGenHelper.AggressiveOptimizationOption)]\n        private void RandomizeManagedHeapMemory()\n        {\n            // invoke global cleanup before global setup\n            Parameters.GlobalCleanupAction.Invoke();\n\n            var gen0object = new byte[random.Next(32)];\n            var lohObject = new byte[85 * 1024 + random.Next(32)];\n\n            // we expect the key allocations to happen in global setup (not ctor)\n            // so we call it while keeping the random-size objects alive\n            Parameters.GlobalSetupAction.Invoke();\n\n            GC.KeepAlive(gen0object);\n            GC.KeepAlive(lohObject);\n\n            // we don't enforce GC.Collects here as engine does it later anyway\n        }\n\n        [MethodImpl(CodeGenHelper.AggressiveOptimizationOption)]\n        private void GcCollect()\n        {\n            if (!ForceGcCleanups)\n                return;\n\n            ForceGcCollect();\n        }\n\n        [MethodImpl(CodeGenHelper.AggressiveOptimizationOption)]\n        internal static void ForceGcCollect()\n        {\n            GC.Collect();\n            GC.WaitForPendingFinalizers();\n            GC.Collect();\n        }\n\n        [UsedImplicitly]\n        public static class Signals\n        {\n            public const string Acknowledgment = \"Acknowledgment\";\n\n            private static readonly Dictionary<HostSignal, string> SignalsToMessages = new()\n            {\n                [HostSignal.BeforeAnythingElse] = \"// BeforeAnythingElse\",\n                [HostSignal.BeforeActualRun] = \"// BeforeActualRun\",\n                [HostSignal.AfterActualRun] = \"// AfterActualRun\",\n                [HostSignal.AfterAll] = \"// AfterAll\",\n                [HostSignal.BeforeExtraIteration] = \"// BeforeExtraIteration\",\n                [HostSignal.AfterExtraIteration] = \"// AfterExtraIteration\"\n            };\n\n            private static readonly Dictionary<string, HostSignal> MessagesToSignals\n                = SignalsToMessages.ToDictionary(p => p.Value, p => p.Key);\n\n            [MethodImpl(CodeGenHelper.AggressiveOptimizationOption)]\n            public static string ToMessage(HostSignal signal) => SignalsToMessages[signal];\n\n            [MethodImpl(CodeGenHelper.AggressiveOptimizationOption)]\n            public static bool TryGetSignal(string message, out HostSignal signal)\n                => MessagesToSignals.TryGetValue(message, out signal);\n        }\n\n        // Very long key and value so this shouldn't be used outside of unit tests.\n        internal const string UnitTestBlockFinalizerEnvKey = \"BENCHMARKDOTNET_UNITTEST_BLOCK_FINALIZER_FOR_MEMORYDIAGNOSER\";\n        internal const string UnitTestBlockFinalizerEnvValue = UnitTestBlockFinalizerEnvKey + \"_ACTIVE\";\n\n        // To prevent finalizers interfering with allocation measurements for unit tests,\n        // we block the finalizer thread until we've completed the measurement.\n        // https://github.com/dotnet/runtime/issues/101536#issuecomment-2077647417\n        private readonly struct FinalizerBlocker : IDisposable\n        {\n            private readonly object hangLock;\n\n            private FinalizerBlocker(object hangLock) => this.hangLock = hangLock;\n\n            private sealed class Impl\n            {\n                // ManualResetEvent(Slim) allocates when it is waited and yields the thread,\n                // so we use Monitor.Wait instead which does not allocate managed memory.\n                // This behavior is not documented, but was observed with the VS Profiler.\n                private readonly object hangLock = new();\n                private readonly ManualResetEventSlim enteredFinalizerEvent = new(false);\n\n                [MethodImpl(CodeGenHelper.AggressiveOptimizationOption)]\n                ~Impl()\n                {\n                    lock (hangLock)\n                    {\n                        enteredFinalizerEvent.Set();\n                        Monitor.Wait(hangLock);\n                    }\n                }\n\n                [MethodImpl(MethodImplOptions.NoInlining | CodeGenHelper.AggressiveOptimizationOption)]\n                internal static (object hangLock, ManualResetEventSlim enteredFinalizerEvent) CreateWeakly()\n                {\n                    var impl = new Impl();\n                    return (impl.hangLock, impl.enteredFinalizerEvent);\n                }\n            }\n\n            [MethodImpl(CodeGenHelper.AggressiveOptimizationOption)]\n            internal static FinalizerBlocker MaybeStart()\n            {\n                if (Environment.GetEnvironmentVariable(UnitTestBlockFinalizerEnvKey) != UnitTestBlockFinalizerEnvValue)\n                {\n                    return default;\n                }\n                var (hangLock, enteredFinalizerEvent) = Impl.CreateWeakly();\n                do\n                {\n                    GC.Collect();\n                    // Do NOT call GC.WaitForPendingFinalizers.\n                }\n                while (!enteredFinalizerEvent.IsSet);\n                return new FinalizerBlocker(hangLock);\n            }\n\n            [MethodImpl(CodeGenHelper.AggressiveOptimizationOption)]\n            public void Dispose()\n            {\n                if (hangLock is not null)\n                {\n                    lock (hangLock)\n                    {\n                        Monitor.Pulse(hangLock);\n                    }\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Engines/EngineActualStage.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Mathematics;\nusing BenchmarkDotNet.Reports;\nusing Perfolizer.Horology;\nusing Perfolizer.Mathematics.OutlierDetection;\n\nnamespace BenchmarkDotNet.Engines\n{\n    internal abstract class EngineActualStage(IterationMode iterationMode, long invokeCount, int unrollFactor, EngineParameters parameters) : EngineStage(IterationStage.Actual, iterationMode, parameters)\n    {\n        internal const int MaxOverheadIterationCount = 20;\n\n        internal readonly long invokeCount = invokeCount;\n        internal readonly int unrollFactor = unrollFactor;\n\n        internal static EngineActualStage GetOverhead(long invokeCount, int unrollFactor, EngineParameters parameters)\n            => new EngineActualStageAuto(IterationMode.Overhead, invokeCount, unrollFactor, parameters);\n\n        internal static EngineActualStage GetWorkload(RunStrategy strategy, long invokeCount, int unrollFactor, EngineParameters parameters)\n        {\n            var targetJob = parameters.TargetJob;\n            int? iterationCount = targetJob.ResolveValueAsNullable(RunMode.IterationCountCharacteristic);\n            const int DefaultWorkloadCount = 10;\n            return iterationCount == null && strategy != RunStrategy.Monitoring\n                ? new EngineActualStageAuto(IterationMode.Workload, invokeCount, unrollFactor, parameters)\n                : new EngineActualStageSpecific(iterationCount ?? DefaultWorkloadCount, IterationMode.Workload, invokeCount, unrollFactor, parameters);\n        }\n\n        protected IterationData GetIterationData()\n            => new(Mode, Stage, ++iterationIndex, invokeCount, unrollFactor, parameters.IterationSetupAction, parameters.IterationCleanupAction,\n                Mode == IterationMode.Workload\n                ? unrollFactor == 1 ? parameters.WorkloadActionNoUnroll : parameters.WorkloadActionUnroll\n                : unrollFactor == 1 ? parameters.OverheadActionNoUnroll : parameters.OverheadActionUnroll);\n    }\n\n    internal sealed class EngineActualStageAuto : EngineActualStage\n    {\n        private readonly double maxRelativeError;\n        private readonly TimeInterval? maxAbsoluteError;\n        private readonly OutlierMode outlierMode;\n        private readonly int minIterationCount;\n        private readonly int maxIterationCount;\n        private readonly List<Measurement> measurementsForStatistics;\n        private int iterationCounter = 0;\n\n        public EngineActualStageAuto(IterationMode iterationMode, long invokeCount, int unrollFactor, EngineParameters parameters) : base(iterationMode, invokeCount, unrollFactor, parameters)\n        {\n            maxRelativeError = parameters.TargetJob.ResolveValue(AccuracyMode.MaxRelativeErrorCharacteristic, parameters.Resolver);\n            maxAbsoluteError = parameters.TargetJob.ResolveValueAsNullable(AccuracyMode.MaxAbsoluteErrorCharacteristic);\n            outlierMode = parameters.TargetJob.ResolveValue(AccuracyMode.OutlierModeCharacteristic, parameters.Resolver);\n            minIterationCount = parameters.TargetJob.ResolveValue(RunMode.MinIterationCountCharacteristic, parameters.Resolver);\n            maxIterationCount = parameters.TargetJob.ResolveValue(RunMode.MaxIterationCountCharacteristic, parameters.Resolver);\n            measurementsForStatistics = GetMeasurementList();\n        }\n\n        internal override List<Measurement> GetMeasurementList() => new(maxIterationCount);\n\n        internal override bool GetShouldRunIteration(List<Measurement> measurements, out IterationData iterationData)\n        {\n            if (measurements.Count == 0)\n            {\n                iterationData = GetIterationData();\n                return true;\n            }\n\n            const double MaxOverheadRelativeError = 0.05;\n            bool isOverhead = Mode == IterationMode.Overhead;\n            double effectiveMaxRelativeError = isOverhead ? MaxOverheadRelativeError : maxRelativeError;\n            iterationCounter++;\n            var measurement = measurements[measurements.Count - 1];\n            measurementsForStatistics.Add(measurement);\n\n            var statistics = MeasurementsStatistics.Calculate(measurementsForStatistics, outlierMode);\n            double actualError = statistics.LegacyConfidenceInterval.Margin;\n\n            double maxError1 = effectiveMaxRelativeError * statistics.Mean;\n            double maxError2 = maxAbsoluteError?.Nanoseconds ?? double.MaxValue;\n            double maxError = Math.Min(maxError1, maxError2);\n\n            if (iterationCounter >= minIterationCount && actualError < maxError)\n            {\n                iterationData = default;\n                return false;\n            }\n\n            if (iterationCounter >= maxIterationCount || isOverhead && iterationCounter >= MaxOverheadIterationCount)\n            {\n                iterationData = default;\n                return false;\n            }\n\n            iterationData = GetIterationData();\n            return true;\n        }\n    }\n\n    internal sealed class EngineActualStageSpecific(int maxIterationCount, IterationMode iterationMode, long invokeCount, int unrollFactor, EngineParameters parameters)\n        : EngineActualStage(iterationMode, invokeCount, unrollFactor, parameters)\n    {\n        internal override List<Measurement> GetMeasurementList() => new(maxIterationCount);\n\n        internal override bool GetShouldRunIteration(List<Measurement> measurements, out IterationData iterationData)\n        {\n            if (iterationIndex < maxIterationCount)\n            {\n                iterationData = GetIterationData();\n                return true;\n            }\n\n            iterationData = default;\n            return false;\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Engines/EngineEventSource.cs",
    "content": "﻿using System;\nusing System.Diagnostics.Tracing;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Engines\n{\n    [EventSource(Name = EngineEventSource.SourceName)]\n    public class EngineEventSource : EventSource\n    {\n        public const string SourceName = \"BenchmarkDotNet.EngineEventSource\";\n\n        [PublicAPI] public const int BenchmarkStartEventId = 1;\n        [PublicAPI] public const int BenchmarkStopEventId = 2;\n        [PublicAPI] public const int OverheadJittingStartEventId = 3;\n        [PublicAPI] public const int OverheadJittingStopEventId = 4;\n        [PublicAPI] public const int WorkloadJittingStartEventId = 5;\n        [PublicAPI] public const int WorkloadJittingStopEventId = 6;\n        [PublicAPI] public const int WorkloadPilotStartEventId = 7;\n        [PublicAPI] public const int WorkloadPilotStopEventId = 8;\n        [PublicAPI] public const int OverheadWarmupStartEventId = 9;\n        [PublicAPI] public const int OverheadWarmupStopEventId = 10;\n        [PublicAPI] public const int OverheadActualStartEventId = 11;\n        [PublicAPI] public const int OverheadActualStopEventId = 12;\n        [PublicAPI] public const int WorkloadWarmupStartEventId = 13;\n        [PublicAPI] public const int WorkloadWarmupStopEventId = 14;\n        [PublicAPI] public const int WorkloadActualStartEventId = 15;\n        [PublicAPI] public const int WorkloadActualStopEventId = 16;\n\n        public class Tasks\n        {\n            [PublicAPI] public const EventTask Benchmark = (EventTask)1;\n            [PublicAPI] public const EventTask OverheadJitting = (EventTask)2;\n            [PublicAPI] public const EventTask WorkloadJitting = (EventTask)3;\n            [PublicAPI] public const EventTask WorkloadPilot = (EventTask)4;\n            [PublicAPI] public const EventTask OverheadWarmup = (EventTask)5;\n            [PublicAPI] public const EventTask OverheadActual = (EventTask)6;\n            [PublicAPI] public const EventTask WorkloadWarmup = (EventTask)7;\n            [PublicAPI] public const EventTask WorkloadActual = (EventTask)8;\n        }\n\n        internal static readonly EngineEventSource Log = new EngineEventSource();\n\n        private EngineEventSource() { }\n\n        [Event(BenchmarkStartEventId, Level = EventLevel.Informational, Task = Tasks.Benchmark, Opcode = EventOpcode.Start)]\n        internal void BenchmarkStart(string benchmarkName) => WriteEvent(BenchmarkStartEventId, benchmarkName);\n\n        [Event(BenchmarkStopEventId, Level = EventLevel.Informational, Task = Tasks.Benchmark, Opcode = EventOpcode.Stop)]\n        internal void BenchmarkStop(string benchmarkName) => WriteEvent(BenchmarkStopEventId, benchmarkName);\n\n        [Event(OverheadJittingStartEventId, Level = EventLevel.Informational, Task = Tasks.OverheadJitting, Opcode = EventOpcode.Start)]\n        internal void OverheadJittingStart(long totalOperations) => WriteEvent(OverheadJittingStartEventId, totalOperations);\n\n        [Event(OverheadJittingStopEventId, Level = EventLevel.Informational, Task = Tasks.OverheadJitting, Opcode = EventOpcode.Stop)]\n        internal void OverheadJittingStop(long totalOperations) => WriteEvent(OverheadJittingStopEventId, totalOperations);\n\n        [Event(WorkloadJittingStartEventId, Level = EventLevel.Informational, Task = Tasks.WorkloadJitting, Opcode = EventOpcode.Start)]\n        internal void WorkloadJittingStart(long totalOperations) => WriteEvent(WorkloadJittingStartEventId, totalOperations);\n\n        [Event(WorkloadJittingStopEventId, Level = EventLevel.Informational, Task = Tasks.WorkloadJitting, Opcode = EventOpcode.Stop)]\n        internal void WorkloadJittingStop(long totalOperations) => WriteEvent(WorkloadJittingStopEventId, totalOperations);\n\n        [Event(WorkloadPilotStartEventId, Level = EventLevel.Informational, Task = Tasks.WorkloadPilot, Opcode = EventOpcode.Start)]\n        internal void WorkloadPilotStart(long totalOperations) => WriteEvent(WorkloadPilotStartEventId, totalOperations);\n\n        [Event(WorkloadPilotStopEventId, Level = EventLevel.Informational, Task = Tasks.WorkloadPilot, Opcode = EventOpcode.Stop)]\n        internal void WorkloadPilotStop(long totalOperations) => WriteEvent(WorkloadPilotStopEventId, totalOperations);\n\n        [Event(OverheadWarmupStartEventId, Level = EventLevel.Informational, Task = Tasks.OverheadWarmup, Opcode = EventOpcode.Start)]\n        internal void OverheadWarmupStart(long totalOperations) => WriteEvent(OverheadWarmupStartEventId, totalOperations);\n\n        [Event(OverheadWarmupStopEventId, Level = EventLevel.Informational, Task = Tasks.OverheadWarmup, Opcode = EventOpcode.Stop)]\n        internal void OverheadWarmupStop(long totalOperations) => WriteEvent(OverheadWarmupStopEventId, totalOperations);\n\n        [Event(OverheadActualStartEventId, Level = EventLevel.Informational, Task = Tasks.OverheadActual, Opcode = EventOpcode.Start)]\n        internal void OverheadActualStart(long totalOperations) => WriteEvent(OverheadActualStartEventId, totalOperations);\n\n        [Event(OverheadActualStopEventId, Level = EventLevel.Informational, Task = Tasks.OverheadActual, Opcode = EventOpcode.Stop)]\n        internal void OverheadActualStop(long totalOperations) => WriteEvent(OverheadActualStopEventId, totalOperations);\n\n        [Event(WorkloadWarmupStartEventId, Level = EventLevel.Informational, Task = Tasks.WorkloadWarmup, Opcode = EventOpcode.Start)]\n        internal void WorkloadWarmupStart(long totalOperations) => WriteEvent(WorkloadWarmupStartEventId, totalOperations);\n\n        [Event(WorkloadWarmupStopEventId, Level = EventLevel.Informational, Task = Tasks.WorkloadWarmup, Opcode = EventOpcode.Stop)]\n        internal void WorkloadWarmupStop(long totalOperations) => WriteEvent(WorkloadWarmupStopEventId, totalOperations);\n\n        [Event(WorkloadActualStartEventId, Level = EventLevel.Informational, Task = Tasks.WorkloadActual, Opcode = EventOpcode.Start)]\n        internal void WorkloadActualStart(long totalOperations) => WriteEvent(WorkloadActualStartEventId, totalOperations);\n\n        [Event(WorkloadActualStopEventId, Level = EventLevel.Informational, Task = Tasks.WorkloadActual, Opcode = EventOpcode.Stop)]\n        internal void WorkloadActualStop(long totalOperations) => WriteEvent(WorkloadActualStopEventId, totalOperations);\n\n        [NonEvent]\n        internal void IterationStart(IterationMode mode, IterationStage stage, long totalOperations)\n        {\n            switch (stage)\n            {\n                case IterationStage.Jitting when mode == IterationMode.Overhead:\n                    OverheadJittingStart(totalOperations);\n                    break;\n                case IterationStage.Jitting when mode == IterationMode.Workload:\n                    WorkloadJittingStart(totalOperations);\n                    break;\n                case IterationStage.Pilot when mode == IterationMode.Workload:\n                    WorkloadPilotStart(totalOperations);\n                    break;\n                case IterationStage.Warmup when mode == IterationMode.Overhead:\n                    OverheadWarmupStart(totalOperations);\n                    break;\n                case IterationStage.Warmup when mode == IterationMode.Workload:\n                    WorkloadWarmupStart(totalOperations);\n                    break;\n                case IterationStage.Actual when mode == IterationMode.Overhead:\n                    OverheadActualStart(totalOperations);\n                    break;\n                case IterationStage.Actual when mode == IterationMode.Workload:\n                    WorkloadActualStart(totalOperations);\n                    break;\n                default:\n                    throw new ArgumentOutOfRangeException(nameof(stage), stage, null);\n            }\n        }\n\n        [NonEvent]\n        internal void IterationStop(IterationMode mode, IterationStage stage, long totalOperations)\n        {\n            switch (stage)\n            {\n                case IterationStage.Jitting when mode == IterationMode.Overhead:\n                    OverheadJittingStop(totalOperations);\n                    break;\n                case IterationStage.Jitting when mode == IterationMode.Workload:\n                    WorkloadJittingStop(totalOperations);\n                    break;\n                case IterationStage.Pilot when mode == IterationMode.Workload:\n                    WorkloadPilotStop(totalOperations);\n                    break;\n                case IterationStage.Warmup when mode == IterationMode.Overhead:\n                    OverheadWarmupStop(totalOperations);\n                    break;\n                case IterationStage.Warmup when mode == IterationMode.Workload:\n                    WorkloadWarmupStop(totalOperations);\n                    break;\n                case IterationStage.Actual when mode == IterationMode.Overhead:\n                    OverheadActualStop(totalOperations);\n                    break;\n                case IterationStage.Actual when mode == IterationMode.Workload:\n                    WorkloadActualStop(totalOperations);\n                    break;\n                default:\n                    throw new ArgumentOutOfRangeException(nameof(stage), stage, null);\n            }\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Engines/EngineFactory.cs",
    "content": "namespace BenchmarkDotNet.Engines;\n\npublic class EngineFactory : IEngineFactory\n{\n    public IEngine Create(EngineParameters engineParameters)\n        => new Engine(engineParameters);\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Engines/EngineJitStage.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Portability;\nusing BenchmarkDotNet.Reports;\nusing Perfolizer.Horology;\n\nnamespace BenchmarkDotNet.Engines;\n\ninternal abstract class EngineJitStage(EngineParameters parameters) : EngineStage(IterationStage.Jitting, IterationMode.Workload, parameters)\n{\n}\n\n// We do our best to encourage the jit to fully promote methods to tier1, but tiered jit relies on heuristics,\n// and we purposefully don't spend too much time in this stage, so we can't guarantee it.\n// This should succeed for 99%+ of microbenchmarks. For any sufficiently short benchmarks where this fails,\n// the following stages (Pilot and Warmup) will likely take it the rest of the way. Long-running benchmarks may never fully reach tier1.\ninternal sealed class EngineFirstJitStage : EngineJitStage\n{\n    // It is not worth spending a long time in jit stage for macro-benchmarks.\n    private static readonly TimeInterval MaxTieringTime = TimeInterval.FromSeconds(10);\n\n    // Jit call counting delay is only for when the app starts up. We don't need to wait for every benchmark if multiple benchmarks are ran in-process.\n    private static TimeSpan s_tieredDelay = JitInfo.TieredDelay;\n\n    internal bool didStopEarly = false;\n    internal Measurement lastMeasurement;\n\n    private readonly IEnumerator<IterationData> enumerator;\n    private readonly bool evaluateOverhead;\n\n    internal EngineFirstJitStage(bool evaluateOverhead, EngineParameters parameters) : base(parameters)\n    {\n        enumerator = EnumerateIterations();\n        this.evaluateOverhead = evaluateOverhead;\n    }\n\n    internal override List<Measurement> GetMeasurementList() => new(GetMaxMeasurementCount());\n\n    private int GetMaxMeasurementCount()\n    {\n        int count = JitInfo.IsTiered\n            ? JitInfo.MaxTierPromotions * JitInfo.TieredCallCountThreshold + 2\n            : 1;\n        if (evaluateOverhead)\n        {\n            count *= 2;\n        }\n        return count;\n    }\n\n    internal override bool GetShouldRunIteration(List<Measurement> measurements, out IterationData iterationData)\n    {\n        if (measurements.Count > 0)\n        {\n            var measurement = measurements[measurements.Count - 1];\n            if (measurement.IterationMode == IterationMode.Workload)\n            {\n                lastMeasurement = measurement;\n            }\n        }\n        if (enumerator.MoveNext())\n        {\n            iterationData = enumerator.Current;\n            return true;\n        }\n        enumerator.Dispose();\n        iterationData = default;\n        return false;\n    }\n\n    private IEnumerator<IterationData> EnumerateIterations()\n    {\n        ++iterationIndex;\n        if (evaluateOverhead)\n        {\n            yield return GetOverheadIterationData(1);\n        }\n        yield return GetWorkloadIterationData(1);\n\n        // If the jit is not tiered, we're done.\n        if (!JitInfo.IsTiered)\n        {\n            yield break;\n        }\n\n        // Wait enough time for jit call counting to begin.\n        Engine.SleepIfPositive(s_tieredDelay);\n        // Don't make the next jit stage wait if it's ran in the same process.\n        s_tieredDelay = TimeSpan.Zero;\n\n        // Attempt to promote methods to tier1, but don't spend too much time in jit stage.\n        StartedClock startedClock = parameters.TargetJob.ResolveValue(InfrastructureMode.ClockCharacteristic, parameters.Resolver)!.Start();\n\n        int remainingTiers = JitInfo.MaxTierPromotions;\n        int lastInvokeCount = 1;\n        while (remainingTiers > 0)\n        {\n            --remainingTiers;\n            int remainingCalls = JitInfo.TieredCallCountThreshold;\n            while (remainingCalls > 0)\n            {\n                // If we can run one batch of calls within the time limit (based on the last measurement), do that instead of multiple single-invocation iterations.\n                var remainingTimeLimit = MaxTieringTime.ToNanoseconds() - startedClock.GetElapsed().GetNanoseconds();\n                var lastMeasurementSingleInvocationTime = lastMeasurement.Nanoseconds / lastInvokeCount;\n                int allowedCallsWithinTimeLimit = (int) Math.Floor(remainingTimeLimit / lastMeasurementSingleInvocationTime);\n                int invokeCount = allowedCallsWithinTimeLimit > 0\n                    ? Math.Min(remainingCalls, allowedCallsWithinTimeLimit)\n                    : 1;\n                lastInvokeCount = invokeCount;\n\n                remainingCalls -= invokeCount;\n                ++iterationIndex;\n                if (evaluateOverhead)\n                {\n                    yield return GetOverheadIterationData(invokeCount);\n                }\n                yield return GetWorkloadIterationData(invokeCount);\n\n                if ((remainingTiers + remainingCalls) > 0\n                    && startedClock.GetElapsed().GetTimeValue() >= MaxTieringTime)\n                {\n                    didStopEarly = true;\n                    yield break;\n                }\n            }\n\n            Engine.SleepIfPositive(JitInfo.BackgroundCompilationDelay);\n        }\n\n        // Empirical evidence shows that the first call after the method is tiered up may take longer,\n        // so we run an extra iteration to ensure the next stage gets a stable measurement.\n        ++iterationIndex;\n        if (evaluateOverhead)\n        {\n            yield return GetOverheadIterationData(1);\n        }\n        yield return GetWorkloadIterationData(1);\n    }\n\n    private IterationData GetOverheadIterationData(long invokeCount)\n        => new(IterationMode.Overhead, IterationStage.Jitting, iterationIndex, invokeCount, 1, () => { }, () => { }, parameters.OverheadActionNoUnroll);\n\n    private IterationData GetWorkloadIterationData(long invokeCount)\n        => new(IterationMode.Workload, IterationStage.Jitting, iterationIndex, invokeCount, 1, parameters.IterationSetupAction, parameters.IterationCleanupAction, parameters.WorkloadActionNoUnroll);\n}\n\ninternal sealed class EngineSecondJitStage : EngineJitStage\n{\n    private readonly int unrollFactor;\n    private readonly bool evaluateOverhead;\n\n    public EngineSecondJitStage(int unrollFactor, bool evaluateOverhead, EngineParameters parameters) : base(parameters)\n    {\n        this.unrollFactor = unrollFactor;\n        this.evaluateOverhead = evaluateOverhead;\n        iterationIndex = evaluateOverhead ? 0 : 2;\n    }\n\n    internal override List<Measurement> GetMeasurementList() => new(evaluateOverhead ? 2 : 1);\n\n    // The benchmark method has already been jitted via *NoUnroll, we only need to jit the *Unroll methods here, which aren't tiered.\n    internal override bool GetShouldRunIteration(List<Measurement> measurements, out IterationData iterationData)\n    {\n        iterationData = ++iterationIndex switch\n        {\n            1 => new(IterationMode.Overhead, IterationStage.Jitting, 1, unrollFactor, unrollFactor, () => { }, () => { }, parameters.OverheadActionUnroll),\n            // IterationSetup/Cleanup are only used for *NoUnroll benchmarks\n            2 => new(IterationMode.Workload, IterationStage.Jitting, 1, unrollFactor, unrollFactor, () => { }, () => { }, parameters.WorkloadActionUnroll),\n            _ => default\n        };\n        return iterationIndex <= 2;\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Engines/EngineParameters.cs",
    "content": "using System;\nusing BenchmarkDotNet.Characteristics;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Running;\n\nnamespace BenchmarkDotNet.Engines\n{\n    public class EngineParameters\n    {\n        public static readonly IResolver DefaultResolver = new CompositeResolver(BenchmarkRunnerClean.DefaultResolver, EngineResolver.Instance);\n\n        public IResolver Resolver { get; set; } = DefaultResolver;\n        public required IHost Host { get; set; }\n        public required Action<long> WorkloadActionNoUnroll { get; set; }\n        public required Action<long> WorkloadActionUnroll { get; set; }\n        public required Action<long> OverheadActionNoUnroll { get; set; }\n        public required Action<long> OverheadActionUnroll { get; set; }\n        public Job TargetJob { get; set; } = Job.Default;\n        public long OperationsPerInvoke { get; set; } = 1;\n        public required Action GlobalSetupAction { get; set; }\n        public required Action GlobalCleanupAction { get; set; }\n        public required Action IterationSetupAction { get; set; }\n        public required Action IterationCleanupAction { get; set; }\n        public bool RunExtraIteration { get; set; }\n        public required string BenchmarkName { get;  set; }\n        public required Diagnosers.CompositeInProcessDiagnoserHandler InProcessDiagnoserHandler { get; set; }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Engines/EnginePilotStage.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Reports;\nusing Perfolizer.Horology;\n\nnamespace BenchmarkDotNet.Engines\n{\n    // TODO: use clockResolution\n    internal abstract class EnginePilotStage(long invokeCount, int unrollFactor, int minInvokeCount, EngineParameters parameters) : EngineStage(IterationStage.Pilot, IterationMode.Workload, parameters)\n    {\n        internal const long MaxInvokeCount = (long.MaxValue / 2 + 1) / 2;\n\n        internal long invokeCount = invokeCount;\n        internal int unrollFactor = unrollFactor;\n        internal int minInvokeCount = minInvokeCount;\n\n        internal override List<Measurement> GetMeasurementList() => [];\n\n        internal static EnginePilotStage GetStage(long invokeCount, int unrollFactor, int minInvokeCount, EngineParameters parameters)\n            // Here we want to guess \"perfect\" amount of invocation\n            => parameters.TargetJob.HasValue(RunMode.IterationTimeCharacteristic)\n                ? new EnginePilotStageSpecific(invokeCount, unrollFactor, minInvokeCount, parameters)\n                : new EnginePilotStageAuto(invokeCount, unrollFactor, minInvokeCount, parameters);\n\n        protected long Autocorrect(long count) => (count + unrollFactor - 1) / unrollFactor * unrollFactor;\n\n        protected IterationData GetIterationData()\n            => new(Mode, Stage, ++iterationIndex, invokeCount, unrollFactor, parameters.IterationSetupAction, parameters.IterationCleanupAction,\n                unrollFactor == 1 ? parameters.WorkloadActionNoUnroll : parameters.WorkloadActionUnroll);\n    }\n\n    internal sealed class EnginePilotStageInitial(long invokeCount, int unrollFactor, int minInvokeCount, EngineParameters parameters) : EnginePilotStage(invokeCount, unrollFactor, minInvokeCount, parameters)\n    {\n        internal bool evaluateOverhead = true;\n        internal bool needsFurtherPilot = true;\n\n        internal override List<Measurement> GetMeasurementList() => [];\n\n        internal override bool GetShouldRunIteration(List<Measurement> measurements, out IterationData iterationData)\n        {\n            if (measurements.Count == 0)\n            {\n                iterationData = new(Mode, Stage, ++iterationIndex, 1, 1, parameters.IterationSetupAction, parameters.IterationCleanupAction, parameters.WorkloadActionNoUnroll);\n                return true;\n            }\n\n            CorrectValues(measurements[measurements.Count - 1]);\n            iterationData = default;\n            return false;\n        }\n\n        internal void CorrectValues(Measurement measurement)\n        {\n            var iterationTime = parameters.TargetJob.ResolveValue(RunMode.IterationTimeCharacteristic, parameters.Resolver);\n            var singleInvokeNanoseconds = measurement.Nanoseconds * parameters.OperationsPerInvoke / measurement.Operations;\n            double timesPerIteration = iterationTime.Nanoseconds / singleInvokeNanoseconds; // how many times can we run given benchmark per iteration\n            // Executing once takes longer than iteration time -> long running benchmark,\n            // or executing twice would put us well past the iteration time.\n            if (timesPerIteration < 1.5)\n            {\n                invokeCount = 1;\n                unrollFactor = 1;\n                // It's very time consuming, overhead is too small compared to total time.\n                evaluateOverhead = false;\n                needsFurtherPilot = false;\n                return;\n            }\n\n            int roundedUpTimesPerIteration = (int) Math.Ceiling(timesPerIteration);\n            // If we run it unrollFactor times per iteration, it's going to take longer than IterationTime.\n            if (roundedUpTimesPerIteration < unrollFactor)\n            {\n                unrollFactor = 1;\n                // The minimum is 2 (not the default 4 which can be too much and not 1 which we already know is not enough).\n                minInvokeCount = 2;\n                // It's very time consuming, overhead is too small compared to total time.\n                evaluateOverhead = false;\n            }\n        }\n    }\n\n    internal sealed class EnginePilotStageAuto(long invokeCount, int unrollFactor, int minInvokeCount, EngineParameters parameters) : EnginePilotStage(invokeCount, unrollFactor, minInvokeCount, parameters)\n    {\n        private readonly TimeInterval minIterationTime = parameters.TargetJob.ResolveValue(AccuracyMode.MinIterationTimeCharacteristic, parameters.Resolver);\n        private readonly double maxRelativeError = parameters.TargetJob.ResolveValue(AccuracyMode.MaxRelativeErrorCharacteristic, parameters.Resolver);\n        private readonly TimeInterval? maxAbsoluteError = parameters.TargetJob.ResolveValueAsNullable(AccuracyMode.MaxAbsoluteErrorCharacteristic);\n        private readonly double resolution = parameters.TargetJob.ResolveValue(InfrastructureMode.ClockCharacteristic, parameters.Resolver)!.GetResolution().Nanoseconds;\n\n        internal override bool GetShouldRunIteration(List<Measurement> measurements, out IterationData iterationData)\n        {\n            if (measurements.Count == 0)\n            {\n                invokeCount = Autocorrect(minInvokeCount);\n                iterationData = GetIterationData();\n                return true;\n            }\n\n            var measurement = measurements[measurements.Count - 1];\n            double iterationTime = measurement.Nanoseconds;\n            double operationError = 2.0 * resolution / invokeCount; // An operation error which has arisen due to the Chronometer precision\n\n            // Max acceptable operation error\n            double operationMaxError1 = iterationTime / invokeCount * maxRelativeError;\n            double operationMaxError2 = maxAbsoluteError?.Nanoseconds ?? double.MaxValue;\n            double operationMaxError = Math.Min(operationMaxError1, operationMaxError2);\n\n            bool isFinished = operationError < operationMaxError && iterationTime >= minIterationTime.Nanoseconds;\n            if (isFinished || invokeCount >= MaxInvokeCount)\n            {\n                iterationData = default;\n                return false;\n            }\n\n            if (unrollFactor == 1 && invokeCount < EnvironmentResolver.DefaultUnrollFactorForThroughput)\n            {\n                ++invokeCount;\n            }\n            else\n            {\n                invokeCount *= 2;\n            }\n\n                iterationData = GetIterationData();\n            return true;\n        }\n    }\n\n    internal sealed class EnginePilotStageSpecific(long invokeCount, int unrollFactor, int minInvokeCount, EngineParameters parameters) : EnginePilotStage(invokeCount, unrollFactor, minInvokeCount, parameters)\n    {\n        private readonly double targetIterationTime = parameters.TargetJob.ResolveValue(RunMode.IterationTimeCharacteristic, parameters.Resolver).ToNanoseconds();\n\n        private int _downCount = 0; // Amount of iterations where newInvokeCount < invokeCount\n\n        internal override bool GetShouldRunIteration(List<Measurement> measurements, out IterationData iterationData)\n        {\n            if (measurements.Count == 0)\n            {\n                invokeCount = Autocorrect(minInvokeCount);\n                iterationData = GetIterationData();\n                return true;\n            }\n\n            var measurement = measurements[measurements.Count - 1];\n            double actualIterationTime = measurement.Nanoseconds;\n            long newInvokeCount = Autocorrect(Math.Max(minInvokeCount, (long) Math.Round(invokeCount * targetIterationTime / actualIterationTime)));\n\n            if (newInvokeCount < invokeCount)\n            {\n                _downCount++;\n            }\n\n            long diff = newInvokeCount - invokeCount;\n            if (_downCount >= 3\n                || (diff != long.MinValue && Math.Abs(diff) <= 1))\n            {\n                iterationData = default;\n                return false;\n            }\n\n            invokeCount = newInvokeCount;\n            iterationData = GetIterationData();\n            return true;\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Engines/EngineResolver.cs",
    "content": "﻿using System;\nusing BenchmarkDotNet.Characteristics;\nusing BenchmarkDotNet.Jobs;\nusing Perfolizer.Horology;\nusing Perfolizer.Mathematics.OutlierDetection;\n\nnamespace BenchmarkDotNet.Engines\n{\n    public class EngineResolver : Resolver\n    {\n        internal const int DefaultMinWorkloadIterationCount = 15;\n        internal const int DefaultMaxWorkloadIterationCount = 100;\n        internal const int DefaultIterationTime = 500;\n\n        internal const int ForceAutoWarmup = -1;\n        internal const int DefaultMinWarmupIterationCount = 6;\n        internal const int DefaultMaxWarmupIterationCount = 50;\n\n        public static readonly IResolver Instance = new EngineResolver();\n\n        private EngineResolver()\n        {\n            Register(RunMode.RunStrategyCharacteristic, () => RunStrategy.Throughput);\n            Register(RunMode.IterationTimeCharacteristic, () => TimeInterval.Millisecond * DefaultIterationTime);\n\n            Register(RunMode.MinIterationCountCharacteristic, () => DefaultMinWorkloadIterationCount);\n            Register(RunMode.MaxIterationCountCharacteristic, () => DefaultMaxWorkloadIterationCount);\n\n            Register(RunMode.MinWarmupIterationCountCharacteristic, () => DefaultMinWarmupIterationCount);\n            Register(RunMode.MaxWarmupIterationCountCharacteristic, () => DefaultMaxWarmupIterationCount);\n\n            Register(AccuracyMode.MaxRelativeErrorCharacteristic, () => 0.02);\n            Register(AccuracyMode.MinIterationTimeCharacteristic, () => TimeInterval.Millisecond * 500);\n            Register(AccuracyMode.MinInvokeCountCharacteristic, () => 4);\n            Register(AccuracyMode.EvaluateOverheadCharacteristic, () => false);\n            Register(RunMode.MemoryRandomizationCharacteristic, () => false);\n            Register(AccuracyMode.OutlierModeCharacteristic, job =>\n            {\n                // if Memory Randomization was enabled and the benchmark is truly multimodal\n                // removing outliers could remove some values that are not actually outliers\n                // see https://github.com/dotnet/BenchmarkDotNet/pull/1587#issue-516837573 for example\n                if (job.ResolveValue(RunMode.MemoryRandomizationCharacteristic, this))\n                    return OutlierMode.DontRemove;\n\n                var strategy = job.ResolveValue(RunMode.RunStrategyCharacteristic, this);\n                switch (strategy)\n                {\n                    case RunStrategy.Throughput:\n                        return OutlierMode.RemoveUpper;\n                    case RunStrategy.ColdStart:\n                    case RunStrategy.Monitoring:\n                        return OutlierMode.DontRemove;\n                    default:\n                        throw new NotSupportedException($\"Unknown runStrategy: {strategy}\");\n                }\n            });\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Engines/EngineStage.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Runtime.CompilerServices;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Portability;\nusing BenchmarkDotNet.Reports;\n\nnamespace BenchmarkDotNet.Engines\n{\n    internal abstract class EngineStage(IterationStage stage, IterationMode mode, EngineParameters parameters)\n    {\n        internal readonly IterationStage Stage = stage;\n        internal readonly IterationMode Mode = mode;\n        protected readonly EngineParameters parameters = parameters;\n        protected int iterationIndex;\n\n        internal abstract List<Measurement> GetMeasurementList();\n        internal abstract bool GetShouldRunIteration(List<Measurement> measurements, out IterationData iterationData);\n\n        [MethodImpl(MethodImplOptions.NoInlining)]\n        internal static IEnumerable<EngineStage> EnumerateStages(EngineParameters parameters)\n        {\n            var strategy = parameters.TargetJob.ResolveValue(RunMode.RunStrategyCharacteristic, parameters.Resolver);\n            var invokeCount = parameters.TargetJob.ResolveValue(RunMode.InvocationCountCharacteristic, parameters.Resolver, 1);\n            var unrollFactor = parameters.TargetJob.ResolveValue(RunMode.UnrollFactorCharacteristic, parameters.Resolver);\n\n            if (strategy != RunStrategy.ColdStart)\n            {\n                if (strategy != RunStrategy.Monitoring)\n                {\n                    // If InvocationCount is specified, pilot stage should be skipped\n                    bool skipPilotStage = parameters.TargetJob.HasValue(RunMode.InvocationCountCharacteristic);\n                    bool evaluateOverhead = parameters.TargetJob.ResolveValue(AccuracyMode.EvaluateOverheadCharacteristic, parameters.Resolver);\n                    int minInvokeCount = parameters.TargetJob.ResolveValue(AccuracyMode.MinInvokeCountCharacteristic, parameters.Resolver);\n\n                    // AOT technically doesn't have a JIT, but we run jit stage regardless because of static constructors. #2004\n                    var jitStage = new EngineFirstJitStage(evaluateOverhead, parameters);\n                    yield return jitStage;\n\n                    bool hasUnrollFactor = parameters.TargetJob.HasValue(RunMode.UnrollFactorCharacteristic);\n                    if (!hasUnrollFactor && !skipPilotStage)\n                    {\n                        // Initial pilot stage adjusts unrollFactor from a single invocation.\n                        var pilotStage = new EnginePilotStageInitial(invokeCount, unrollFactor, minInvokeCount, parameters);\n                        // If the jit invocation was too time consuming, just correct the values without running another invocation.\n                        if (jitStage.didStopEarly)\n                        {\n                            pilotStage.CorrectValues(jitStage.lastMeasurement);\n                        }\n                        else\n                        {\n                            yield return pilotStage;\n                        }\n\n                        invokeCount = pilotStage.invokeCount;\n                        unrollFactor = pilotStage.unrollFactor;\n                        minInvokeCount = pilotStage.minInvokeCount;\n                        evaluateOverhead &= pilotStage.evaluateOverhead;\n                        skipPilotStage = !pilotStage.needsFurtherPilot;\n                    }\n\n                    // The first jit stage only jitted *NoUnroll methods, now we need to jit *Unroll methods if they're going to be used.\n                    // TODO: This stage can be removed after we refactor the engine/codegen to pass the clock into the delegates.\n                    if (!RuntimeInformation.IsAot && unrollFactor != 1)\n                    {\n                        yield return new EngineSecondJitStage(unrollFactor, evaluateOverhead, parameters);\n                    }\n\n                    if (!skipPilotStage)\n                    {\n                        var pilotStage = EnginePilotStage.GetStage(invokeCount, unrollFactor, minInvokeCount, parameters);\n                        yield return pilotStage;\n\n                        invokeCount = pilotStage.invokeCount;\n                    }\n\n                    if (evaluateOverhead)\n                    {\n                        yield return EngineWarmupStage.GetOverhead(invokeCount, unrollFactor, parameters);\n                        yield return EngineActualStage.GetOverhead(invokeCount, unrollFactor, parameters);\n                    }\n                }\n\n                yield return EngineWarmupStage.GetWorkload(strategy, invokeCount, unrollFactor, parameters);\n\n                // TODO: restart pilot/warmup stages if some heuristic determines it's necessary (#2787, #1210).\n            }\n\n            yield return EngineActualStage.GetWorkload(strategy, invokeCount, unrollFactor, parameters);\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Engines/EngineWarmupStage.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Reports;\n\nnamespace BenchmarkDotNet.Engines\n{\n    internal abstract class EngineWarmupStage(IterationMode iterationMode, long invokeCount, int unrollFactor, EngineParameters parameters) : EngineStage(IterationStage.Warmup, iterationMode, parameters)\n    {\n        private const int MinOverheadIterationCount = 4;\n        internal const int MaxOverheadIterationCount = 10;\n\n        internal static EngineWarmupStage GetOverhead(long invokeCount, int unrollFactor, EngineParameters parameters)\n            => new EngineWarmupStageAuto(IterationMode.Overhead, MinOverheadIterationCount, MaxOverheadIterationCount, invokeCount, unrollFactor, parameters);\n\n        internal static EngineWarmupStage GetWorkload(RunStrategy runStrategy, long invokeCount, int unrollFactor, EngineParameters parameters)\n        {\n            var job = parameters.TargetJob;\n            var count = job.ResolveValueAsNullable(RunMode.WarmupCountCharacteristic);\n            if (count.HasValue && count.Value != EngineResolver.ForceAutoWarmup || runStrategy == RunStrategy.Monitoring)\n            {\n                return new EngineWarmupStageSpecific(count ?? 0, IterationMode.Workload, invokeCount, unrollFactor, parameters);\n            }\n\n            int minIterationCount = job.ResolveValue(RunMode.MinWarmupIterationCountCharacteristic, parameters.Resolver);\n            int maxIterationCount = job.ResolveValue(RunMode.MaxWarmupIterationCountCharacteristic, parameters.Resolver);\n            return new EngineWarmupStageAuto(IterationMode.Workload, minIterationCount, maxIterationCount, invokeCount, unrollFactor, parameters);\n        }\n\n        protected IterationData GetIterationData()\n            => new(Mode, Stage, ++iterationIndex, invokeCount, unrollFactor, parameters.IterationSetupAction, parameters.IterationCleanupAction,\n                Mode == IterationMode.Workload\n                ? unrollFactor == 1 ? parameters.WorkloadActionNoUnroll : parameters.WorkloadActionUnroll\n                : unrollFactor == 1 ? parameters.OverheadActionNoUnroll: parameters.OverheadActionUnroll);\n    }\n\n    internal sealed class EngineWarmupStageAuto(IterationMode iterationMode, int minIterationCount, int maxIterationCount, long invokeCount, int unrollFactor, EngineParameters parameters)\n        : EngineWarmupStage(iterationMode, invokeCount, unrollFactor, parameters)\n    {\n        private const int MinFluctuationCount = 4;\n\n        private readonly int minIterationCount = minIterationCount;\n        private readonly int maxIterationCount = maxIterationCount;\n\n        internal override List<Measurement> GetMeasurementList() => new(maxIterationCount);\n\n        internal override bool GetShouldRunIteration(List<Measurement> measurements, out IterationData iterationData)\n        {\n            int n = measurements.Count;\n\n            if (n >= maxIterationCount)\n            {\n                iterationData = default;\n                return false;\n            }\n            if (n < minIterationCount)\n            {\n                iterationData = GetIterationData();\n                return true;\n            }\n\n            int direction = -1; // The default \"pre-state\" is \"decrease mode\"\n            int fluctuationCount = 0;\n            for (int i = 1; i < n; i++)\n            {\n                int nextDirection = Math.Sign(measurements[i].Nanoseconds - measurements[i - 1].Nanoseconds);\n                if (nextDirection != direction || nextDirection == 0)\n                {\n                    direction = nextDirection;\n                    fluctuationCount++;\n                }\n            }\n\n            iterationData = GetIterationData();\n            return fluctuationCount < MinFluctuationCount;\n        }\n    }\n\n    internal sealed class EngineWarmupStageSpecific(int maxIterationCount, IterationMode iterationMode, long invokeCount, int unrollFactor, EngineParameters parameters)\n        : EngineWarmupStage(iterationMode, invokeCount, unrollFactor, parameters)\n    {\n        internal override List<Measurement> GetMeasurementList() => new(maxIterationCount);\n\n        internal override bool GetShouldRunIteration(List<Measurement> measurements, out IterationData iterationData)\n        {\n            if (iterationIndex < maxIterationCount)\n            {\n                iterationData = GetIterationData();\n                return true;\n            }\n\n            iterationData = default;\n            return false;\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Engines/GcStats.cs",
    "content": "﻿using System;\nusing System.Reflection;\nusing System.Runtime.CompilerServices;\nusing BenchmarkDotNet.Columns;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Portability;\nusing BenchmarkDotNet.Running;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Engines\n{\n    public struct GcStats : IEquatable<GcStats>\n    {\n        internal const string ResultsLinePrefix = \"// GC: \";\n\n        public static readonly long AllocationQuantum = CalculateAllocationQuantumSize();\n\n        public static readonly GcStats Empty = default;\n\n        private GcStats(int gen0Collections, int gen1Collections, int gen2Collections, long? allocatedBytes, long totalOperations)\n        {\n            Gen0Collections = gen0Collections;\n            Gen1Collections = gen1Collections;\n            Gen2Collections = gen2Collections;\n            AllocatedBytes = allocatedBytes;\n            TotalOperations = totalOperations;\n        }\n\n        // did not use array here just to avoid heap allocation\n        public int Gen0Collections { get; }\n        public int Gen1Collections { get; }\n        public int Gen2Collections { get; }\n\n        /// <summary>\n        /// Total per all runs\n        /// </summary>\n        private long? AllocatedBytes { get; }\n\n        public long TotalOperations { get; }\n\n        public long? GetBytesAllocatedPerOperation(BenchmarkCase benchmarkCase)\n        {\n            bool excludeAllocationQuantumSideEffects = benchmarkCase.GetRuntime().RuntimeMoniker <= RuntimeMoniker.NetCoreApp20; // the issue got fixed for .NET Core 2.0+ https://github.com/dotnet/coreclr/issues/10207\n\n            long? allocatedBytes = GetTotalAllocatedBytes(excludeAllocationQuantumSideEffects);\n            return allocatedBytes == null ? null\n                : allocatedBytes == 0 ? 0\n                : (long) Math.Round( // let's round it to reduce the side effects of Allocation quantum\n                    (double) allocatedBytes.Value / TotalOperations,\n                    MidpointRounding.ToEven);\n        }\n\n        public static GcStats operator +(GcStats left, GcStats right)\n        {\n            return new GcStats(\n                left.Gen0Collections + right.Gen0Collections,\n                left.Gen1Collections + right.Gen1Collections,\n                left.Gen2Collections + right.Gen2Collections,\n                left.AllocatedBytes + right.AllocatedBytes,\n                left.TotalOperations + right.TotalOperations);\n        }\n\n        public static GcStats operator -(GcStats left, GcStats right)\n        {\n            return new GcStats(\n                Math.Max(0, left.Gen0Collections - right.Gen0Collections),\n                Math.Max(0, left.Gen1Collections - right.Gen1Collections),\n                Math.Max(0, left.Gen2Collections - right.Gen2Collections),\n                ClampToPositive(left.AllocatedBytes - right.AllocatedBytes),\n                Math.Max(0, left.TotalOperations - right.TotalOperations));\n        }\n\n        private static long? ClampToPositive(long? num)\n        {\n            return num.HasValue ? Math.Max(0, num.Value) : null;\n        }\n\n        public GcStats WithTotalOperations(long totalOperationsCount)\n            => this + new GcStats(0, 0, 0, 0, totalOperationsCount);\n\n        public int GetCollectionsCount(int generation)\n        {\n            switch (generation) {\n                case 0:\n                    return Gen0Collections;\n                case 1:\n                    return Gen1Collections;\n                default:\n                    return Gen2Collections;\n            }\n        }\n\n        /// <summary>\n        /// returns total allocated bytes (not per operation)\n        /// </summary>\n        /// <param name=\"excludeAllocationQuantumSideEffects\">Allocation quantum can affecting some of our nano-benchmarks in non-deterministic way.\n        /// when this parameter is set to true and the number of all allocated bytes is less or equal AQ, we ignore AQ and put 0 to the results</param>\n        /// <returns></returns>\n        public long? GetTotalAllocatedBytes(bool excludeAllocationQuantumSideEffects)\n        {\n            if (AllocatedBytes == null)\n                return null;\n\n            if (!excludeAllocationQuantumSideEffects)\n                return AllocatedBytes;\n\n            return AllocatedBytes <= AllocationQuantum ? 0L : AllocatedBytes;\n        }\n\n        // Skip tier0 jit to make sure we don't get any unexpected allocations in this method.\n        [MethodImpl(CodeGenHelper.AggressiveOptimizationOption)]\n        public static GcStats ReadInitial()\n        {\n            long? allocatedBytes = GetAllocatedBytes();\n\n            return new GcStats(\n                GC.CollectionCount(0),\n                GC.CollectionCount(1),\n                GC.CollectionCount(2),\n                allocatedBytes,\n                0);\n        }\n\n        // Skip tier0 jit to make sure we don't get any unexpected allocations in this method.\n        [MethodImpl(CodeGenHelper.AggressiveOptimizationOption)]\n        public static GcStats ReadFinal()\n        {\n            return new GcStats(\n                GC.CollectionCount(0),\n                GC.CollectionCount(1),\n                GC.CollectionCount(2),\n                GetAllocatedBytes(),\n                0);\n        }\n\n        [PublicAPI]\n        public static GcStats FromForced(int forcedFullGarbageCollections)\n            => new GcStats(forcedFullGarbageCollections, forcedFullGarbageCollections, forcedFullGarbageCollections, 0, 0);\n\n        // Skip tier0 jit to make sure we don't get any unexpected allocations in this method.\n        [MethodImpl(CodeGenHelper.AggressiveOptimizationOption)]\n        private static long? GetAllocatedBytes()\n        {\n            // Do NOT call GC.Collect() here, as it causes finalizers to run and possibly allocate. https://github.com/dotnet/runtime/issues/101536#issuecomment-2077533242\n            // Instead, we call it before we start the measurement in the Engine.\n#if NET6_0_OR_GREATER\n            return GC.GetTotalAllocatedBytes(precise: true);\n#else\n            if (GcHelpers.GetTotalAllocatedBytesDelegate != null) // it's .NET Core 3.0 with the new API available\n                return GcHelpers.GetTotalAllocatedBytesDelegate.Invoke(true); // true for the \"precise\" argument\n\n            if (GcHelpers.CanUseMonitoringTotalAllocatedMemorySize) // Monitoring is not available in Mono, see http://stackoverflow.com/questions/40234948/how-to-get-the-number-of-allocated-bytes-\n                return AppDomain.CurrentDomain.MonitoringTotalAllocatedMemorySize;\n\n            if (GcHelpers.GetAllocatedBytesForCurrentThreadDelegate != null)\n                return GcHelpers.GetAllocatedBytesForCurrentThreadDelegate.Invoke();\n\n            return null;\n#endif\n        }\n\n        public string ToOutputLine()\n            => $\"{ResultsLinePrefix} {Gen0Collections} {Gen1Collections} {Gen2Collections} {AllocatedBytes?.ToString() ?? MetricColumn.UnknownRepresentation} {TotalOperations}\";\n\n        public static GcStats Parse(string line)\n        {\n            if (!line.StartsWith(ResultsLinePrefix))\n                throw new NotSupportedException($\"Line must start with {ResultsLinePrefix}\");\n\n            var measurementSplit = line.Remove(0, ResultsLinePrefix.Length).Split([' '], StringSplitOptions.RemoveEmptyEntries);\n            if (!int.TryParse(measurementSplit[0], out int gen0)\n                || !int.TryParse(measurementSplit[1], out int gen1)\n                || !int.TryParse(measurementSplit[2], out int gen2)\n                || !TryParse(measurementSplit[3], out long? allocatedBytes)\n                || !long.TryParse(measurementSplit[4], out long totalOperationsCount))\n            {\n                throw new NotSupportedException(\"Invalid string\");\n            }\n\n            return new GcStats(gen0, gen1, gen2, allocatedBytes, totalOperationsCount);\n        }\n\n        private static bool TryParse(string s, out long? result)\n        {\n            if (s == MetricColumn.UnknownRepresentation)\n            {\n                result = null;\n                return true;\n            }\n            if (long.TryParse(s, out long r))\n            {\n                result = r;\n                return true;\n            }\n            result = null;\n            return false;\n        }\n\n        public override string ToString() => ToOutputLine();\n\n        /// <summary>\n        /// code copied from https://github.com/rsdn/CodeJam/blob/71a6542b6e5c52ea8dd92c601adad11e62796a98/PerfTests/src/%5BL4_Configuration%5D/Metrics/%5BMetricValuesProvider%5D/GcMetricValuesProvider.cs#L63-L89\n        /// </summary>\n        /// <returns></returns>\n        private static long CalculateAllocationQuantumSize()\n        {\n            long result;\n            int retry = 0;\n            do\n            {\n                if (++retry > 10)\n                {\n                    result = 8192; // 8kb https://github.com/dotnet/coreclr/blob/master/Documentation/botr/garbage-collection.md\n                    break;\n                }\n\n                Engine.ForceGcCollect();\n\n                result = GC.GetTotalMemory(false);\n                var tmp = new object();\n                result = GC.GetTotalMemory(false) - result;\n                GC.KeepAlive(tmp);\n            } while (result <= 0);\n\n            return result;\n        }\n\n        public bool Equals(GcStats other) => Gen0Collections == other.Gen0Collections && Gen1Collections == other.Gen1Collections && Gen2Collections == other.Gen2Collections && AllocatedBytes == other.AllocatedBytes && TotalOperations == other.TotalOperations;\n\n        public override bool Equals(object? obj) => obj is GcStats other && Equals(other);\n\n        public override int GetHashCode() => HashCode.Combine(Gen0Collections, Gen1Collections, Gen2Collections, AllocatedBytes, TotalOperations);\n\n#if !NET6_0_OR_GREATER\n        // Separate class to have the cctor run lazily, to avoid enabling monitoring before the benchmarks are ran.\n        private static class GcHelpers\n        {\n            // do not reorder these, CheckMonitoringTotalAllocatedMemorySize relies on GetTotalAllocatedBytesDelegate being initialized first\n            public static readonly Func<bool, long>? GetTotalAllocatedBytesDelegate = CreateGetTotalAllocatedBytesDelegate();\n            public static readonly Func<long>? GetAllocatedBytesForCurrentThreadDelegate = CreateGetAllocatedBytesForCurrentThreadDelegate();\n            public static readonly bool CanUseMonitoringTotalAllocatedMemorySize = CheckMonitoringTotalAllocatedMemorySize();\n\n            private static Func<bool, long>? CreateGetTotalAllocatedBytesDelegate()\n            {\n                try\n                {\n                    // this method is not a part of .NET Standard so we need to use reflection\n                    var method = typeof(GC).GetTypeInfo().GetMethod(\"GetTotalAllocatedBytes\", BindingFlags.Public | BindingFlags.Static);\n\n                    if (method == null)\n                        return null;\n\n                    // we create delegate to avoid boxing, IMPORTANT!\n                    var del = (Func<bool, long>)method.CreateDelegate(typeof(Func<bool, long>));\n\n                    // verify the api works\n                    return del.Invoke(true) >= 0 ? del : null;\n                }\n                catch\n                {\n                    return null;\n                }\n            }\n\n            private static Func<long>? CreateGetAllocatedBytesForCurrentThreadDelegate()\n            {\n                try\n                {\n                    // this method is not a part of .NET Standard so we need to use reflection\n                    var method = typeof(GC).GetTypeInfo().GetMethod(\"GetAllocatedBytesForCurrentThread\", BindingFlags.Public | BindingFlags.Static);\n\n                    if (method == null)\n                        return null;\n\n                    // we create delegate to avoid boxing, IMPORTANT!\n                    var del = (Func<long>)method.CreateDelegate(typeof(Func<long>));\n\n                    // verify the api works\n                    return del.Invoke() >= 0 ? del : null;\n                }\n                catch\n                {\n                    return null;\n                }\n            }\n\n            private static bool CheckMonitoringTotalAllocatedMemorySize()\n            {\n                try\n                {\n                    // we potentially don't want to enable monitoring if we don't need it\n                    if (GetTotalAllocatedBytesDelegate != null)\n                        return false;\n\n                    // check if monitoring is enabled\n                    if (!AppDomain.MonitoringIsEnabled)\n                        AppDomain.MonitoringIsEnabled = true;\n\n                    // verify the api works\n                    return AppDomain.MonitoringIsEnabled && AppDomain.CurrentDomain.MonitoringTotalAllocatedMemorySize >= 0;\n                }\n                catch\n                {\n                    return false;\n                }\n            }\n        }\n#endif\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Engines/HostExtensions.cs",
    "content": "﻿using JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Engines\n{\n    public static class HostExtensions\n    {\n        [StringFormatMethod(\"messageFormat\")]\n        public static void WriteLine(this IHost host, string messageFormat, params object[] args)\n            => host.WriteLine(string.Format(messageFormat, args));\n\n        public static void BeforeAnythingElse(this IHost host) => host.SendSignal(HostSignal.BeforeAnythingElse);\n\n        public static void BeforeMainRun(this IHost host) => host.SendSignal(HostSignal.BeforeActualRun);\n\n        public static void AfterMainRun(this IHost host) => host.SendSignal(HostSignal.AfterActualRun);\n\n        public static void AfterAll(this IHost host) => host.SendSignal(HostSignal.AfterAll);\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Engines/HostSignal.cs",
    "content": "﻿namespace BenchmarkDotNet.Engines\n{\n    public enum HostSignal\n    {\n        /// <summary>\n        /// before we start the benchmarking process\n        /// </summary>\n        BeforeProcessStart,\n\n        /// <summary>\n        /// right after we start the benchmarking process\n        /// </summary>\n        AfterProcessStart,\n\n        /// <summary>\n        /// before jitting, warmup\n        /// </summary>\n        BeforeAnythingElse,\n\n        /// <summary>\n        /// after globalSetup, warmup and pilot but before the main run\n        /// </summary>\n        BeforeActualRun,\n\n        /// <summary>\n        /// after main run, but before global Cleanup\n        /// </summary>\n        AfterActualRun,\n\n        /// <summary>\n        /// after actual run, after extra IterationSetup, before extra iteration\n        /// </summary>\n        BeforeExtraIteration,\n\n        /// <summary>\n        /// after extra iteration, before extra IterationCleanup\n        /// </summary>\n        AfterExtraIteration,\n\n        /// <summary>\n        /// after all (the last thing the benchmarking engine does is to fire this signal)\n        /// </summary>\n        AfterAll,\n\n        /// <summary>\n        /// used to run some code independent to the benchmarked process\n        /// </summary>\n        SeparateLogic,\n\n        /// <summary>\n        /// after the benchmarking process exits\n        /// </summary>\n        AfterProcessExit\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Engines/IEngine.cs",
    "content": "﻿namespace BenchmarkDotNet.Engines;\n\npublic interface IEngine\n{\n    RunResults Run();\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Engines/IEngineFactory.cs",
    "content": "namespace BenchmarkDotNet.Engines\n{\n    public interface IEngineFactory\n    {\n        IEngine Create(EngineParameters engineParameters);\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Engines/IHost.cs",
    "content": "﻿using System;\nusing System.Diagnostics.CodeAnalysis;\n\nnamespace BenchmarkDotNet.Engines\n{\n    [SuppressMessage(\"ReSharper\", \"UnusedMember.Global\")]\n    public interface IHost : IDisposable\n    {\n        void Write(string message);\n        void WriteLine();\n        void WriteLine(string message);\n\n        void SendSignal(HostSignal hostSignal);\n        void SendError(string message);\n\n        void ReportResults(RunResults runResults);\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Engines/IterationData.cs",
    "content": "﻿using System;\n\nnamespace BenchmarkDotNet.Engines\n{\n    internal readonly struct IterationData(IterationMode iterationMode, IterationStage iterationStage, int index, long invokeCount, int unrollFactor,\n        Action setupAction, Action cleanupAction, Action<long> workloadAction)\n    {\n        public readonly IterationMode mode = iterationMode;\n        public readonly IterationStage stage = iterationStage;\n        public readonly int index = index;\n        public readonly long invokeCount = invokeCount;\n        public readonly int unrollFactor = unrollFactor;\n        public readonly Action setupAction = setupAction;\n        public readonly Action cleanupAction = cleanupAction;\n        public readonly Action<long> workloadAction = workloadAction;\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Engines/IterationMode.cs",
    "content": "﻿namespace BenchmarkDotNet.Engines\n{\n    public enum IterationMode\n    {\n        Overhead,\n\n        Workload,\n\n        Unknown\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Engines/IterationStage.cs",
    "content": "﻿namespace BenchmarkDotNet.Engines\n{\n    public enum IterationStage\n    {\n        Unknown,\n\n        Jitting,\n\n        /// <summary>\n        /// <seealso href=\"https://en.wikipedia.org/wiki/Pilot_experiment\"/>\n        /// </summary>\n        Pilot,\n\n        Warmup,\n\n        Actual,\n\n        Result,\n\n        Extra,\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Engines/NoAcknowledgementConsoleHost.cs",
    "content": "﻿using System;\nusing System.IO;\nusing System.Runtime.CompilerServices;\nusing BenchmarkDotNet.Portability;\nusing BenchmarkDotNet.Validators;\n\nnamespace BenchmarkDotNet.Engines\n{\n    // this class is used only when somebody manually launches benchmarking .exe without providing anonymous pipes file descriptors\n    public sealed class NoAcknowledgementConsoleHost : IHost\n    {\n        private readonly TextWriter outWriter;\n\n        public NoAcknowledgementConsoleHost() => outWriter = Console.Out;\n\n        public void Write(string message) => outWriter.Write(message);\n\n        public void WriteLine() => outWriter.WriteLine();\n\n        [MethodImpl(CodeGenHelper.AggressiveOptimizationOption)]\n        public void WriteLine(string message) => outWriter.WriteLine(message);\n\n        [MethodImpl(CodeGenHelper.AggressiveOptimizationOption)]\n        public void SendSignal(HostSignal hostSignal) => WriteLine(Engine.Signals.ToMessage(hostSignal));\n\n        public void SendError(string message) => outWriter.WriteLine($\"{ValidationErrorReporter.ConsoleErrorPrefix} {message}\");\n\n        public void ReportResults(RunResults runResults) => runResults.Print(outWriter);\n\n        public void Dispose()\n        {\n            // do nothing on purpose - there is no point in closing STD OUT\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Engines/RunResults.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Mathematics;\nusing BenchmarkDotNet.Reports;\nusing JetBrains.Annotations;\nusing Perfolizer.Mathematics.OutlierDetection;\n\nnamespace BenchmarkDotNet.Engines\n{\n    public readonly struct RunResults(IReadOnlyList<Measurement> engineMeasurements, OutlierMode outlierMode, GcStats gcStats)\n    {\n        private readonly OutlierMode outlierMode = outlierMode;\n\n        [PublicAPI]\n        public IReadOnlyList<Measurement>? EngineMeasurements { get; } = engineMeasurements;\n\n        [PublicAPI]\n        public IReadOnlyList<Measurement>? Overhead\n            => EngineMeasurements\n                ?.Where(m => m.Is(IterationMode.Overhead, IterationStage.Actual))\n                .ToArray();\n\n        [PublicAPI]\n        public IReadOnlyList<Measurement>? Workload\n            => EngineMeasurements\n                ?.Where(m => m.Is(IterationMode.Workload, IterationStage.Actual))\n                .ToArray();\n\n        public GcStats GCStats { get; } = gcStats;\n\n        public IEnumerable<Measurement> GetWorkloadResultMeasurements()\n        {\n            var overheadActualMeasurements = Overhead ?? [];\n            var workloadActualMeasurements = Workload ?? [];\n            if (workloadActualMeasurements.IsEmpty())\n                yield break;\n\n            double overhead = overheadActualMeasurements.IsEmpty() ? 0.0 : new Statistics(overheadActualMeasurements.Select(m => m.Nanoseconds)).Median;\n            var mainStats = new Statistics(workloadActualMeasurements.Select(m => m.Nanoseconds));\n            int resultIndex = 0;\n            foreach (var measurement in workloadActualMeasurements)\n            {\n                if (mainStats.IsActualOutlier(measurement.Nanoseconds, outlierMode))\n                    continue;\n                double value = Math.Max(0, measurement.Nanoseconds - overhead);\n                if (IsSuspiciouslySmall(value))\n                    value = 0;\n\n                yield return new Measurement(\n                    measurement.LaunchIndex,\n                    IterationMode.Workload,\n                    IterationStage.Result,\n                    ++resultIndex,\n                    measurement.Operations,\n                    value);\n            }\n        }\n\n        public IEnumerable<Measurement> GetAllMeasurements()\n        {\n            foreach (var measurement in EngineMeasurements ?? [])\n                yield return measurement;\n            foreach (var measurement in GetWorkloadResultMeasurements())\n                yield return measurement;\n        }\n\n        public void Print(TextWriter outWriter)\n        {\n            foreach (var measurement in GetWorkloadResultMeasurements())\n                outWriter.WriteLine(measurement.ToString());\n\n            if (!GCStats.Equals(GcStats.Empty))\n                outWriter.WriteLine(GCStats.ToOutputLine());\n\n            outWriter.WriteLine();\n        }\n\n        // TODO: improve\n        // If we get value < 0.1ns, it's probably a random noise, the actual value is 0.0ns.\n        private static bool IsSuspiciouslySmall(double value) => value < 0.1;\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Engines/RunStrategy.cs",
    "content": "﻿namespace BenchmarkDotNet.Engines\n{\n    public enum RunStrategy\n    {\n        /// <summary>\n        /// Throughput mode.\n        /// Perfect for microbenchmarking.\n        /// </summary>\n        Throughput,\n\n        /// <summary>\n        /// A mode without overhead evaluating and warmup, with single invocation.\n        /// Perfect for startup time evaluation.\n        /// </summary>\n        ColdStart,\n\n        /// <summary>\n        /// A mode without overhead evaluating, with several target iterations.\n        /// Perfect for macrobenchmarks without a steady state with high variance.\n        /// </summary>\n        Monitoring\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Environments/BenchmarkEnvironmentInfo.cs",
    "content": "using System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Runtime;\nusing BenchmarkDotNet.Detectors.Cpu;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Portability;\nusing BenchmarkDotNet.Properties;\nusing BenchmarkDotNet.Validators;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Environments\n{\n    public class BenchmarkEnvironmentInfo\n    {\n        internal const string RuntimeInfoPrefix = \"Runtime=\";\n        internal const string GcInfoPrefix = \"GC=\";\n        internal const string HardwareIntrinsicsPrefix = \"HardwareIntrinsics=\";\n\n        [PublicAPI] public string Architecture { get; protected set; }\n        [PublicAPI] public string Configuration { get; protected set; }\n        [PublicAPI] public string RuntimeVersion { get; protected set; }\n        [PublicAPI] public bool HasAttachedDebugger { get; protected set; }\n        [PublicAPI] public bool HasRyuJit { get; protected set; }\n        [PublicAPI] public string JitInfo { get; protected set; }\n        [PublicAPI] public string HardwareIntrinsicsShort { get; protected set; }\n        [PublicAPI] public bool IsServerGC { get; protected set; }\n        [PublicAPI] public bool IsConcurrentGC { get; protected set; }\n        [PublicAPI] public long GCAllocationQuantum { get; protected set; }\n        [PublicAPI] public bool InDocker { get; protected set; }\n\n        protected BenchmarkEnvironmentInfo()\n        {\n            Architecture = RuntimeInformation.GetArchitecture();\n            RuntimeVersion = RuntimeInformation.GetRuntimeVersion();\n            Configuration = RuntimeInformation.GetConfiguration();\n            HasRyuJit = Portability.JitInfo.IsRyuJit;\n            JitInfo = Portability.JitInfo.GetInfo();\n            HardwareIntrinsicsShort = HardwareIntrinsics.GetShortInfo();\n            IsServerGC = GCSettings.IsServerGC;\n            IsConcurrentGC = GCSettings.LatencyMode != GCLatencyMode.Batch;\n            HasAttachedDebugger = Debugger.IsAttached;\n            GCAllocationQuantum = GcStats.AllocationQuantum;\n            InDocker = RuntimeInformation.IsRunningInContainer;\n        }\n\n        public static BenchmarkEnvironmentInfo GetCurrent() => new BenchmarkEnvironmentInfo();\n\n        // ReSharper disable once UnusedMemberInSuper.Global\n        public virtual IEnumerable<string> ToFormattedString()\n        {\n            yield return \"Benchmark Process Environment Information:\";\n            yield return $\"{BenchmarkDotNetInfo.Instance.BrandTitle}\";\n            yield return $\"{RuntimeInfoPrefix}{GetRuntimeInfo()}\";\n            yield return $\"{GcInfoPrefix}{GetGcConcurrentFlag()} {GetGcServerFlag()}\";\n            yield return $\"{HardwareIntrinsicsPrefix}{HardwareIntrinsics.GetFullInfo(RuntimeInformation.GetCurrentPlatform())} {HardwareIntrinsics.GetVectorSize()}\";\n        }\n\n        [PublicAPI] protected string GetConfigurationFlag() => Configuration == RuntimeInformation.Unknown || Configuration == RuntimeInformation.ReleaseConfigurationName\n            ? \"\"\n            : Configuration;\n\n        [PublicAPI] protected string GetDebuggerFlag() => HasAttachedDebugger ? \"[AttachedDebugger]\" : \"\";\n        [PublicAPI] protected string GetGcServerFlag() => IsServerGC ? \"Server\" : \"Workstation\";\n        [PublicAPI] protected string GetGcConcurrentFlag() => IsConcurrentGC ? \"Concurrent\" : \"Non-concurrent\";\n\n        internal string GetRuntimeInfo()\n        {\n            string jitInfo = string.Join(\" \", new[] { JitInfo, HardwareIntrinsicsShort, GetConfigurationFlag(), GetDebuggerFlag() }.Where(title => title != \"\"));\n            return $\"{RuntimeVersion}, {Architecture} {jitInfo}\";\n        }\n\n        public static IEnumerable<ValidationError> Validate(Job job)\n        {\n            if (job.Environment.Jit == Jit.RyuJit && !Portability.JitInfo.IsRyuJit)\n                yield return new ValidationError(true, \"RyuJIT is requested but it is not available in current environment\");\n            var currentRuntime = RuntimeInformation.GetCurrentRuntime();\n            if (job.Environment.Jit == Jit.LegacyJit && !(currentRuntime is ClrRuntime))\n                yield return new ValidationError(true, $\"LegacyJIT is requested but it is not available for {currentRuntime}\");\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Environments/EnvironmentResolver.cs",
    "content": "﻿using System;\nusing BenchmarkDotNet.Characteristics;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Portability;\nusing BenchmarkDotNet.Running;\n\nnamespace BenchmarkDotNet.Environments\n{\n    public class EnvironmentResolver : Resolver\n    {\n        public const int DefaultUnrollFactorForThroughput = 16;\n\n        public static readonly IResolver Instance = new CompositeResolver(new EnvironmentResolver(), GcResolver.Instance);\n\n        private EnvironmentResolver()\n        {\n            Register(EnvironmentMode.PlatformCharacteristic, RuntimeInformation.GetCurrentPlatform);\n            Register(EnvironmentMode.RuntimeCharacteristic, RuntimeInformation.GetCurrentRuntime);\n            Register(EnvironmentMode.JitCharacteristic, JitInfo.GetCurrentJit);\n            Register(EnvironmentMode.AffinityCharacteristic, RuntimeInformation.GetCurrentAffinity);\n            Register(EnvironmentMode.EnvironmentVariablesCharacteristic, Array.Empty<EnvironmentVariable>);\n            Register(EnvironmentMode.PowerPlanModeCharacteristic, () => PowerManagementApplier.Map(PowerPlan.HighPerformance));\n\n            // TODO: find a better place\n            Register(AccuracyMode.AnalyzeLaunchVarianceCharacteristic, () => false);\n            Register(RunMode.UnrollFactorCharacteristic, job =>\n            {\n                // TODO: move it to another place and use the main resolver\n                var strategy = job.ResolveValue(RunMode.RunStrategyCharacteristic, RunStrategy.Throughput);\n                switch (strategy)\n                {\n                    case RunStrategy.Throughput:\n                        return DefaultUnrollFactorForThroughput;\n                    case RunStrategy.ColdStart:\n                    case RunStrategy.Monitoring:\n                        return 1;\n                    default:\n                        throw new NotSupportedException($\"Unknown runStrategy: {strategy}\");\n                }\n            });\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Environments/GcResolver.cs",
    "content": "﻿using BenchmarkDotNet.Characteristics;\nusing BenchmarkDotNet.Jobs;\n\nnamespace BenchmarkDotNet.Environments\n{\n    public class GcResolver : Resolver\n    {\n        public static readonly IResolver Instance = new GcResolver();\n\n        private GcResolver()\n        {\n            Register(GcMode.ServerCharacteristic, () => HostEnvironmentInfo.GetCurrent().IsServerGC);\n            Register(GcMode.ConcurrentCharacteristic, () => HostEnvironmentInfo.GetCurrent().IsConcurrentGC);\n            Register(GcMode.CpuGroupsCharacteristic, () => false);\n            Register(GcMode.ForceCharacteristic, () => true);\n            Register(GcMode.AllowVeryLargeObjectsCharacteristic, () => false);\n            Register(GcMode.RetainVmCharacteristic, () => false); // Maoni0: \"The default is false\" https://github.com/dotnet/docs/issues/878#issuecomment-248986456\n            Register(GcMode.NoAffinitizeCharacteristic, () => false); // Maoni0: https://github.com/dotnet/coreclr/pull/6104/commits/d088712003e8d483872754d6b3c72aa2d4443a93\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Environments/HostEnvironmentInfo.cs",
    "content": "﻿using BenchmarkDotNet.Detectors;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Helpers;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Models;\nusing BenchmarkDotNet.Portability;\nusing BenchmarkDotNet.Properties;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Toolchains.DotNetCli;\nusing JetBrains.Annotations;\nusing Perfolizer.Helpers;\nusing Perfolizer.Horology;\nusing Perfolizer.Metrology;\nusing Perfolizer.Models;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\n\nnamespace BenchmarkDotNet.Environments\n{\n    // this class is used by our auto-generated benchmark program,\n    // keep it in mind if you want to do some renaming\n    // you can find the source code at Templates\\BenchmarkProgram.txt\n    public class HostEnvironmentInfo : BenchmarkEnvironmentInfo\n    {\n        public const string BenchmarkDotNetCaption = \"BenchmarkDotNet\";\n\n        // TODO: API to GlobalSetup the logger.\n        /// <summary>\n        /// Logger to use when there's no config available.\n        /// </summary>\n        public static ILogger FallbackLogger => ConsoleLogger.Default;\n\n        private static HostEnvironmentInfo? current;\n\n        public string BenchmarkDotNetVersion { get; protected set; }\n\n        /// <summary>\n        /// is expensive to call (1s)\n        /// </summary>\n        public Lazy<CpuInfo> Cpu { get; protected set; }\n\n        public Lazy<OsInfo> Os { get; protected set; }\n\n        /// <summary>\n        /// .NET Core SDK version\n        /// <remarks>It's expensive to call (creates new process by calling `dotnet --version`)</remarks>\n        /// </summary>\n        public Lazy<string> DotNetSdkVersion { get; protected set; }\n\n        /// <summary>\n        /// checks if Mono is installed\n        /// <remarks>It's expensive to call (creates new process by calling `mono --version`)</remarks>\n        /// </summary>\n        public Lazy<bool> IsMonoInstalled { get; }\n\n        /// <summary>\n        /// The frequency of the timer as the number of ticks per second.\n        /// </summary>\n        [PublicAPI] public Frequency ChronometerFrequency { get; protected set; }\n\n        [PublicAPI] public TimeInterval ChronometerResolution => ChronometerFrequency.ToResolution();\n\n        public HardwareTimerKind HardwareTimerKind { get; protected set; }\n\n        public Lazy<ICollection<Antivirus>> AntivirusProducts { get; }\n\n        // TODO: Join with OsInfo\n        public Lazy<VirtualMachineHypervisor?> VirtualMachineHypervisor { get; protected set; }\n\n        public Lazy<PhysicalMemoryInfo?> PhysicalMemory { get; protected set; }\n\n        protected HostEnvironmentInfo()\n        {\n            BenchmarkDotNetVersion = BenchmarkDotNetInfo.Instance.BrandVersion;\n            ChronometerFrequency = Chronometer.Frequency;\n            HardwareTimerKind = Chronometer.HardwareTimerKind;\n            DotNetSdkVersion = new Lazy<string>(DotNetCliCommandExecutor.GetDotNetSdkVersion);\n            IsMonoInstalled = new Lazy<bool>(() => ProcessHelper.TestCommandExists(\"mono\"));\n            AntivirusProducts = new Lazy<ICollection<Antivirus>>(RuntimeInformation.GetAntivirusProducts);\n            VirtualMachineHypervisor = new Lazy<VirtualMachineHypervisor?>(RuntimeInformation.GetVirtualMachineHypervisor);\n            Os = new Lazy<OsInfo>(OsDetector.GetOs);\n            Cpu = new Lazy<CpuInfo>(() => CpuDetector.CrossPlatform.Detect() ?? CpuInfo.Unknown);\n            PhysicalMemory = new Lazy<PhysicalMemoryInfo?>(SystemMemory.GetPhysicalMemory);\n        }\n\n        public new static HostEnvironmentInfo GetCurrent() => current ??= new HostEnvironmentInfo();\n\n        public override IEnumerable<string> ToFormattedString()\n        {\n            string? vmName = VirtualMachineHypervisor.Value?.Name;\n\n            if (vmName.IsNotBlank())\n                yield return $\"{BenchmarkDotNetCaption} v{BenchmarkDotNetVersion}, {Os.Value.ToBrandString()} ({vmName})\";\n            else if (RuntimeInformation.IsRunningInContainer)\n                yield return $\"{BenchmarkDotNetCaption} v{BenchmarkDotNetVersion}, {Os.Value.ToBrandString()} (container)\";\n            else\n                yield return $\"{BenchmarkDotNetCaption} v{BenchmarkDotNetVersion}, {Os.Value.ToBrandString()}\";\n\n            yield return Cpu.Value.ToFullBrandName();\n\n            if (HardwareTimerKind != HardwareTimerKind.Unknown)\n            {\n                string frequency = PerfolizerMeasurementFormatter.Instance.Format(\n                    ChronometerFrequency.ToMeasurement(FrequencyUnit.Hz),\n                    unitPresentation: UnitHelper.DefaultPresentation);\n                string resolution = PerfolizerMeasurementFormatter.Instance.Format(\n                    ChronometerResolution.ToMeasurement(),\n                    format: \"0.000\",\n                    unitPresentation: UnitHelper.DefaultPresentation);\n                string timer = HardwareTimerKind.ToString().ToUpper();\n                yield return $\"Frequency: {frequency}, Resolution: {resolution}, Timer: {timer}\";\n            }\n\n            if (PhysicalMemory.Value != null)\n                yield return $\"Memory: {PhysicalMemory.Value.ToFormattedString()}\";\n\n            if (RuntimeInformation.IsNetCore && IsDotNetCliInstalled())\n            {\n                // this wonderful version number contains words like \"preview\" and ... 5 segments, so it can not be parsed by Version.Parse. Example: \"5.0.100-preview.8.20362.3\"\n                if (int.TryParse(new string(DotNetSdkVersion.Value.TrimStart().TakeWhile(char.IsDigit).ToArray()), out int major) && major >= 5)\n                    yield return $\".NET SDK {DotNetSdkVersion.Value}\";\n                else\n                    yield return $\".NET Core SDK {DotNetSdkVersion.Value}\";\n            }\n        }\n\n        [PublicAPI]\n        public bool IsDotNetCliInstalled() => DotNetSdkVersion.Value.IsNotBlank();\n\n        /// <summary>\n        /// Return string representation of CPU and environment configuration including BenchmarkDotNet, OS and .NET version\n        /// </summary>\n        [PublicAPI]\n        public static string GetInformation()\n        {\n            var hostEnvironmentInfo = GetCurrent();\n            var sb = new StringBuilder();\n            foreach (string infoLine in hostEnvironmentInfo.ToFormattedString())\n            {\n                sb.AppendLine(infoLine);\n            }\n\n            sb.AppendLine(Summary.BuildAllRuntimes(hostEnvironmentInfo, Array.Empty<BenchmarkReport>()));\n            return sb.ToString();\n        }\n\n        internal BdnHostInfo ToPerfonar() => new()\n        {\n            Cpu = Cpu.Value,\n            Os = Os.Value,\n            RuntimeVersion = RuntimeVersion,\n            HasAttachedDebugger = HasAttachedDebugger,\n            HasRyuJit = HasRyuJit,\n            Configuration = Configuration,\n            DotNetSdkVersion = DotNetSdkVersion.Value,\n            ChronometerFrequency = ChronometerFrequency.Hertz,\n            HardwareTimerKind = HardwareTimerKind.ToString()\n        };\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Environments/InfrastructureResolver.cs",
    "content": "﻿using System;\nusing BenchmarkDotNet.Characteristics;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Jobs;\nusing Perfolizer.Horology;\n\nnamespace BenchmarkDotNet.Environments\n{\n    public class InfrastructureResolver : Resolver\n    {\n        public static readonly IResolver Instance = new InfrastructureResolver();\n\n        private InfrastructureResolver()\n        {\n            Register(InfrastructureMode.ClockCharacteristic, () => Chronometer.BestClock);\n            Register(InfrastructureMode.EngineFactoryCharacteristic, () => new EngineFactory());\n            Register(InfrastructureMode.BuildConfigurationCharacteristic, () => InfrastructureMode.ReleaseConfigurationName);\n\n            Register(InfrastructureMode.ArgumentsCharacteristic, Array.Empty<Argument>);\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Environments/Jit.cs",
    "content": "﻿namespace BenchmarkDotNet.Environments\n{\n    public enum Jit\n    {\n        /// <summary>\n        /// Default\n        /// <remarks>By default</remarks>\n        /// </summary>\n        Default,\n\n        /// <summary>\n        /// LegacyJIT\n        /// <remarks>Supported only for Full Framework</remarks>\n        /// </summary>\n        LegacyJit,\n\n        /// <summary>\n        /// RyuJIT\n        /// <remarks>Full Framework or CoreCLR</remarks>\n        /// </summary>\n        RyuJit,\n\n        /// <summary>\n        /// LLVM\n        /// <remarks>Supported only for Mono</remarks>\n        /// </summary>\n        Llvm\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Environments/PhysicalMemoryInfo.cs",
    "content": "﻿using System;\nusing System.Diagnostics;\nusing System.IO;\nusing System.Runtime.InteropServices;\nusing System.Text.RegularExpressions;\n\nnamespace BenchmarkDotNet.Environments\n{\n    public class PhysicalMemoryInfo\n    {\n        public long TotalPhysicalBytes { get; }\n        public long? AvailablePhysicalBytes { get; }\n\n        public PhysicalMemoryInfo(long totalPhysicalBytes, long? availablePhysicalBytes = null)\n        {\n            TotalPhysicalBytes = totalPhysicalBytes;\n            AvailablePhysicalBytes = availablePhysicalBytes;\n        }\n\n        public string ToFormattedString()\n        {\n            double totalGb = TotalPhysicalBytes / (1024.0 * 1024.0 * 1024.0);\n\n            if (AvailablePhysicalBytes.HasValue)\n            {\n                double availableGb = AvailablePhysicalBytes.Value / (1024.0 * 1024.0 * 1024.0);\n                return $\"{Math.Round(totalGb, 2)} GB Total, {Math.Round(availableGb, 2)} GB Available\";\n            }\n\n            return $\"{Math.Round(totalGb, 2)} GB\";\n        }\n    }\n\n    public static class SystemMemory\n    {\n        public static PhysicalMemoryInfo? GetPhysicalMemory()\n        {\n            try\n            {\n                if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))\n                    return GetWindowsMemory();\n\n                if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))\n                    return GetLinuxMemory();\n\n                if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))\n                    return GetMacMemory();\n            }\n            catch (Exception)\n            {\n                // Ignore errors\n            }\n\n            return null;\n        }\n\n        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]\n        private class MEMORYSTATUSEX\n        {\n            public uint dwLength;\n            public uint dwMemoryLoad;\n            public ulong ullTotalPhys;\n            public ulong ullAvailPhys;\n            public ulong ullTotalPageFile;\n            public ulong ullAvailPageFile;\n            public ulong ullTotalVirtual;\n            public ulong ullAvailVirtual;\n            public ulong ullAvailExtendedVirtual;\n\n            public MEMORYSTATUSEX()\n            {\n                dwLength = (uint)Marshal.SizeOf(typeof(MEMORYSTATUSEX));\n            }\n        }\n\n        [DllImport(\"kernel32.dll\", CharSet = CharSet.Auto, SetLastError = true)]\n        [return: MarshalAs(UnmanagedType.Bool)]\n        private static extern bool GlobalMemoryStatusEx([In, Out] MEMORYSTATUSEX lpBuffer);\n\n        private static PhysicalMemoryInfo? GetWindowsMemory()\n        {\n            var memStatus = new MEMORYSTATUSEX();\n            if (GlobalMemoryStatusEx(memStatus))\n            {\n                return new PhysicalMemoryInfo((long)memStatus.ullTotalPhys, (long)memStatus.ullAvailPhys);\n            }\n            return null;\n        }\n\n        private static PhysicalMemoryInfo? GetLinuxMemory()\n        {\n            const string path = \"/proc/meminfo\";\n            if (File.Exists(path))\n            {\n                long total = 0;\n                long? available = null;\n\n                foreach (var line in File.ReadAllLines(path))\n                {\n                    if (line.StartsWith(\"MemTotal:\"))\n                    {\n                        var match = Regex.Match(line, @\"\\d+\");\n                        if (match.Success && long.TryParse(match.Value, out long kb))\n                            total = kb * 1024;\n                    }\n                    else if (line.StartsWith(\"MemAvailable:\") || line.StartsWith(\"MemFree:\"))\n                    {\n                        var match = Regex.Match(line, @\"\\d+\");\n                        if (match.Success && long.TryParse(match.Value, out long kb) && available == null)\n                            available = kb * 1024;\n                    }\n                }\n\n                if (total > 0)\n                    return new PhysicalMemoryInfo(total, available);\n            }\n            return null;\n        }\n\n        private static PhysicalMemoryInfo? GetMacMemory()\n        {\n            long total = 0;\n            long? available = null;\n\n            // 1. Get Total Memory\n            var sysctlInfo = new ProcessStartInfo(\"sysctl\", \"-n hw.memsize\")\n            {\n                RedirectStandardOutput = true,\n                UseShellExecute = false,\n                CreateNoWindow = true\n            };\n\n            using (var process = Process.Start(sysctlInfo))\n            {\n                if (process != null)\n                {\n                    string output = process.StandardOutput.ReadToEnd();\n                    process.WaitForExit();\n                    long.TryParse(output.Trim(), out total);\n                }\n            }\n\n            if (total == 0) return null;\n\n            // 2. Get Free Memory using vm_stat\n            var vmStatInfo = new ProcessStartInfo(\"vm_stat\")\n            {\n                RedirectStandardOutput = true,\n                UseShellExecute = false,\n                CreateNoWindow = true\n            };\n\n            using (var process = Process.Start(vmStatInfo))\n            {\n                if (process != null)\n                {\n                    string output = process.StandardOutput.ReadToEnd();\n                    process.WaitForExit();\n\n                    long pageSize = 4096;\n                    var pageSizeMatch = Regex.Match(output, @\"page size of (\\d+) bytes\");\n                    if (pageSizeMatch.Success && long.TryParse(pageSizeMatch.Groups[1].Value, out long parsedPageSize))\n                    {\n                        pageSize = parsedPageSize;\n                    }\n\n                    var match = Regex.Match(output, @\"Pages free:\\s+(\\d+)\");\n                    if (match.Success && long.TryParse(match.Groups[1].Value, out long pagesFree))\n                    {\n                        available = pagesFree * pageSize;\n                    }\n                }\n            }\n\n            return new PhysicalMemoryInfo(total, available);\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Environments/Platform.cs",
    "content": "﻿namespace BenchmarkDotNet.Environments\n{\n    public enum Platform\n    {\n        /// <summary>\n        /// AnyCPU\n        /// </summary>\n        AnyCpu,\n\n        /// <summary>\n        /// x86\n        /// </summary>\n        X86,\n\n        /// <summary>\n        /// x64\n        /// </summary>\n        X64,\n\n        /// <summary>\n        /// ARM\n        /// </summary>\n        Arm,\n\n        /// <summary>\n        /// ARM64\n        /// </summary>\n        Arm64,\n\n        /// <summary>\n        /// Wasm\n        /// </summary>\n        Wasm,\n\n        /// <summary>\n        /// S390x\n        /// </summary>\n        S390x,\n\n        /// <summary>\n        /// LOONGARCH64\n        /// </summary>\n        LoongArch64,\n\n        /// <summary>\n        /// A 32-bit ARMv6 processor architecture.\n        /// </summary>\n        Armv6,\n\n        /// <summary>\n        /// A PowerPC 64-bit (little-endian) processor architecture.\n        /// </summary>\n        Ppc64le,\n\n        /// <summary>\n        /// A RiscV 64-bit processor architecture.\n        /// </summary>\n        RiscV64,\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Environments/PowerPlan.cs",
    "content": "﻿namespace BenchmarkDotNet.Environments\n{\n    public enum PowerPlan\n    {\n        HighPerformance,\n        UserPowerPlan,\n        PowerSaver,\n        Balanced,\n        UltimatePerformance\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Environments/Runtimes/ClrRuntime.cs",
    "content": "﻿using System;\nusing System.Reflection;\nusing BenchmarkDotNet.Detectors;\nusing BenchmarkDotNet.Helpers;\nusing BenchmarkDotNet.Jobs;\n\nnamespace BenchmarkDotNet.Environments\n{\n    public class ClrRuntime : Runtime, IEquatable<ClrRuntime>\n    {\n        public static readonly ClrRuntime Net461 = new ClrRuntime(RuntimeMoniker.Net461, \"net461\", \".NET Framework 4.6.1\");\n        public static readonly ClrRuntime Net462 = new ClrRuntime(RuntimeMoniker.Net462, \"net462\", \".NET Framework 4.6.2\");\n        public static readonly ClrRuntime Net47 = new ClrRuntime(RuntimeMoniker.Net47, \"net47\", \".NET Framework 4.7\");\n        public static readonly ClrRuntime Net471 = new ClrRuntime(RuntimeMoniker.Net471, \"net471\", \".NET Framework 4.7.1\");\n        public static readonly ClrRuntime Net472 = new ClrRuntime(RuntimeMoniker.Net472, \"net472\", \".NET Framework 4.7.2\");\n        public static readonly ClrRuntime Net48 = new ClrRuntime(RuntimeMoniker.Net48, \"net48\", \".NET Framework 4.8\");\n        public static readonly ClrRuntime Net481 = new ClrRuntime(RuntimeMoniker.Net481, \"net481\", \".NET Framework 4.8.1\");\n\n        public string Version { get; }\n\n        private ClrRuntime(RuntimeMoniker runtimeMoniker, string msBuildMoniker, string displayName, string version = \"\")\n            : base(runtimeMoniker, msBuildMoniker, displayName)\n        {\n            Version = version;\n        }\n\n        /// <param name=\"version\">YOU PROBABLY DON'T NEED IT, but if you are a .NET Runtime developer..\n        /// please set it to particular .NET Runtime version if you want to benchmark it.\n        /// BenchmarkDotNet in going to pass `COMPLUS_Version` env var to the process for you.\n        /// </param>\n        public static ClrRuntime CreateForLocalFullNetFrameworkBuild(string version)\n        {\n            if (string.IsNullOrEmpty(version)) throw new ArgumentNullException(nameof(version));\n\n            var current = GetCurrentVersion();\n\n            return new ClrRuntime(current.RuntimeMoniker, current.MsBuildMoniker, version, version);\n        }\n\n        public override bool Equals(object? obj) => obj is ClrRuntime other && Equals(other);\n\n        public bool Equals(ClrRuntime? other) => other != null && base.Equals(other) && Version == other.Version;\n\n        public override int GetHashCode() => HashCode.Combine(base.GetHashCode(), Version);\n\n        internal static ClrRuntime GetCurrentVersion()\n        {\n            if (!OsDetector.IsWindows())\n            {\n                throw new PlatformNotSupportedException(\".NET Framework supports Windows OS only.\");\n            }\n\n            string version = FrameworkVersionHelper.GetLatestNetDeveloperPackVersion()\n                ?? FrameworkVersionHelper.GetFrameworkReleaseVersion(); // .NET Developer Pack is not installed\n            return GetRuntimeFromVersion(version);\n        }\n\n        internal static ClrRuntime GetTargetOrCurrentVersion(Assembly? assembly)\n        {\n            if (!OsDetector.IsWindows())\n            {\n                throw new PlatformNotSupportedException(\".NET Framework supports Windows OS only.\");\n            }\n\n            // Try to determine the Framework version that the assembly was compiled for.\n            string? version = FrameworkVersionHelper.GetTargetFrameworkVersion(assembly);\n            return version != null\n                ? GetRuntimeFromVersion(version)\n                // Fallback to the current running Framework version.\n                : GetCurrentVersion();\n        }\n\n        private static ClrRuntime GetRuntimeFromVersion(string version)\n            => version switch\n            {\n                \"4.6.1\" => Net461,\n                \"4.6.2\" => Net462,\n                \"4.7\" => Net47,\n                \"4.7.1\" => Net471,\n                \"4.7.2\" => Net472,\n                \"4.8\" => Net48,\n                \"4.8.1\" => Net481,\n                // unlikely to happen but theoretically possible\n                _ => new ClrRuntime(RuntimeMoniker.NotRecognized, $\"net{version.Replace(\".\", null)}\", $\".NET Framework {version}\"),\n            };\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Environments/Runtimes/CoreRuntime.cs",
    "content": "﻿using System;\nusing System.Diagnostics;\nusing System.Diagnostics.CodeAnalysis;\nusing System.IO;\nusing System.Linq;\nusing System.Reflection;\nusing System.Runtime.Versioning;\nusing BenchmarkDotNet.Helpers;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Portability;\n\nnamespace BenchmarkDotNet.Environments\n{\n    public class CoreRuntime : Runtime\n    {\n        public static readonly CoreRuntime Core20 = new(RuntimeMoniker.NetCoreApp20, \"netcoreapp2.0\", \".NET Core 2.0\");\n        public static readonly CoreRuntime Core21 = new(RuntimeMoniker.NetCoreApp21, \"netcoreapp2.1\", \".NET Core 2.1\");\n        public static readonly CoreRuntime Core22 = new(RuntimeMoniker.NetCoreApp22, \"netcoreapp2.2\", \".NET Core 2.2\");\n        public static readonly CoreRuntime Core30 = new(RuntimeMoniker.NetCoreApp30, \"netcoreapp3.0\", \".NET Core 3.0\");\n        public static readonly CoreRuntime Core31 = new(RuntimeMoniker.NetCoreApp31, \"netcoreapp3.1\", \".NET Core 3.1\");\n        public static readonly CoreRuntime Core50 = new(RuntimeMoniker.Net50, \"net5.0\", \".NET 5.0\");\n        public static readonly CoreRuntime Core60 = new(RuntimeMoniker.Net60, \"net6.0\", \".NET 6.0\");\n        public static readonly CoreRuntime Core70 = new(RuntimeMoniker.Net70, \"net7.0\", \".NET 7.0\");\n        public static readonly CoreRuntime Core80 = new(RuntimeMoniker.Net80, \"net8.0\", \".NET 8.0\");\n        public static readonly CoreRuntime Core90 = new(RuntimeMoniker.Net90, \"net9.0\", \".NET 9.0\");\n        public static readonly CoreRuntime Core10_0 = new(RuntimeMoniker.Net10_0, \"net10.0\", \".NET 10.0\");\n        public static readonly CoreRuntime Core11_0 = new(RuntimeMoniker.Net11_0, \"net11.0\", \".NET 11.0\");\n\n        public static CoreRuntime Latest => Core11_0; // when dotnet/runtime branches for 12.0, this will need to get updated\n\n        private CoreRuntime(RuntimeMoniker runtimeMoniker, string msBuildMoniker, string displayName)\n            : base(runtimeMoniker, msBuildMoniker, displayName)\n        {\n        }\n\n        public bool IsPlatformSpecific => MsBuildMoniker.IndexOf('-') > 0;\n\n        /// <summary>\n        /// use this method if you want to target .NET version not supported by current version of BenchmarkDotNet. Example: .NET 10\n        /// </summary>\n        /// <param name=\"msBuildMoniker\">msbuild moniker, example: net10.0</param>\n        /// <param name=\"displayName\">display name used by BDN to print the results</param>\n        /// <returns>new runtime information</returns>\n        public static CoreRuntime CreateForNewVersion(string msBuildMoniker, string displayName)\n        {\n            if (string.IsNullOrEmpty(msBuildMoniker)) throw new ArgumentNullException(nameof(msBuildMoniker));\n            if (string.IsNullOrEmpty(displayName)) throw new ArgumentNullException(nameof(displayName));\n\n            return new CoreRuntime(RuntimeMoniker.NotRecognized, msBuildMoniker, displayName);\n        }\n\n        internal static CoreRuntime GetTargetOrCurrentVersion(Assembly? assembly)\n            // Try to determine the version that the assembly was compiled for.\n            => FrameworkVersionHelper.GetTargetCoreVersion(assembly) is { } version\n                ? FromVersion(version, assembly)\n                // Fallback to the current running version.\n                : GetCurrentVersion();\n\n        internal static CoreRuntime GetCurrentVersion()\n        {\n            if (!RuntimeInformation.IsNetCore)\n            {\n                throw new NotSupportedException(\"It's impossible to reliably detect the version of .NET Core if the process is not a .NET Core process!\");\n            }\n\n            if (!TryGetVersion(out var version))\n            {\n                throw new NotSupportedException(\"Unable to recognize .NET Core version, please report a bug at https://github.com/dotnet/BenchmarkDotNet\");\n            }\n\n            return FromVersion(version, null);\n        }\n\n        internal static CoreRuntime FromVersion(Version version, Assembly? assembly = null) => version switch\n        {\n            { Major: 2, Minor: 0 } => Core20,\n            { Major: 2, Minor: 1 } => Core21,\n            { Major: 2, Minor: 2 } => Core22,\n            { Major: 3, Minor: 0 } => Core30,\n            { Major: 3, Minor: 1 } => Core31,\n            { Major: 5 } => GetPlatformSpecific(Core50, assembly),\n            { Major: 6 } => GetPlatformSpecific(Core60, assembly),\n            { Major: 7 } => GetPlatformSpecific(Core70, assembly),\n            { Major: 8 } => GetPlatformSpecific(Core80, assembly),\n            { Major: 9 } => GetPlatformSpecific(Core90, assembly),\n            { Major: 10 } => GetPlatformSpecific(Core10_0, assembly),\n            { Major: 11 } => GetPlatformSpecific(Core11_0, assembly),\n            _ => CreateForNewVersion($\"net{version.Major}.{version.Minor}\", $\".NET {version.Major}.{version.Minor}\"),\n        };\n\n        internal static bool TryGetVersion([NotNullWhen(true)] out Version? version)\n        {\n            // we can't just use System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription\n            // because it can be null and it reports versions like 4.6.* for .NET Core 2.*\n\n            // for .NET 5+ we can use Environment.Version\n            if (Environment.Version.Major >= 5)\n            {\n                version = Environment.Version;\n                return true;\n            }\n\n            string runtimeDirectory = System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory();\n            if (TryGetVersionFromRuntimeDirectory(runtimeDirectory, out version))\n            {\n                return true;\n            }\n\n            string coreclrLocation = typeof(object).Assembly.Location;\n            // Single-file publish has empty assembly location.\n            if (coreclrLocation.IsNotBlank())\n            {\n                var systemPrivateCoreLib = FileVersionInfo.GetVersionInfo(coreclrLocation);\n                var productVersion = systemPrivateCoreLib?.ProductVersion ?? \"\";\n                var productName = systemPrivateCoreLib?.ProductName ?? \"\";\n\n                // systemPrivateCoreLib.Product*Part properties return 0 so we have to implement some ugly parsing...\n                if (TryGetVersionFromProductInfo(productVersion, productName, out version))\n                {\n                    return true;\n                }\n            }\n            else\n            {\n                // .Net Core 3.X supports single-file publish, .Net Core 2.X does not.\n                // .Net Core 3.X fixed the version in FrameworkDescription, so we don't need to handle the case of 4.6.x in this branch.\n                var frameworkDescriptionVersion = GetParsableVersionPart(GetVersionFromFrameworkDescription());\n                if (Version.TryParse(frameworkDescriptionVersion, out version))\n                {\n                    return true;\n                }\n            }\n\n            // it's OK to use this method only after checking the previous ones\n            // because we might have a benchmark app build for .NET Core X but executed using CoreRun Y\n            // example: -f netcoreapp3.1 --corerun $omittedForBrevity\\Microsoft.NETCore.App\\6.0.0\\CoreRun.exe - built as 3.1, run as 6.0 (#1576)\n            string frameworkName = Assembly.GetEntryAssembly()?.GetCustomAttribute<TargetFrameworkAttribute>()?.FrameworkName ?? \"\";\n            if (TryGetVersionFromFrameworkName(frameworkName, out version))\n            {\n                return true;\n            }\n\n            if (RuntimeInformation.IsRunningInContainer)\n            {\n                return Version.TryParse(Environment.GetEnvironmentVariable(\"DOTNET_VERSION\"), out version)\n                    || Version.TryParse(Environment.GetEnvironmentVariable(\"ASPNETCORE_VERSION\"), out version);\n            }\n\n            version = null;\n            return false;\n        }\n\n        internal static string GetVersionFromFrameworkDescription()\n        {\n            // .NET 10.0.0-preview.5.25277.114 -> 10.0.0-preview.5.25277.114\n            // .NET Core 3.1.32 -> 3.1.32\n            string frameworkDescription = System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription;\n            return new string(frameworkDescription.SkipWhile(c => !char.IsDigit(c)).ToArray());\n        }\n\n        // sample input:\n        // for dotnet run: C:\\Program Files\\dotnet\\shared\\Microsoft.NETCore.App\\2.1.12\\\n        // for dotnet publish: C:\\Users\\adsitnik\\source\\repos\\ConsoleApp25\\ConsoleApp25\\bin\\Release\\netcoreapp2.0\\win-x64\\publish\\\n        internal static bool TryGetVersionFromRuntimeDirectory(string runtimeDirectory, [NotNullWhen(true)] out Version? version)\n        {\n            if (runtimeDirectory.IsNotBlank() && Version.TryParse(GetParsableVersionPart(new DirectoryInfo(runtimeDirectory).Name), out version))\n            {\n                return true;\n            }\n\n            version = null;\n            return false;\n        }\n\n        // sample input:\n        // 2.0: 4.6.26614.01 @BuiltBy: dlab14-DDVSOWINAGE018 @Commit: a536e7eec55c538c94639cefe295aa672996bf9b, Microsoft .NET Framework\n        // 2.1: 4.6.27817.01 @BuiltBy: dlab14-DDVSOWINAGE101 @Branch: release/2.1 @SrcCode: https://github.com/dotnet/coreclr/tree/6f78fbb3f964b4f407a2efb713a186384a167e5c, Microsoft .NET Framework\n        // 2.2: 4.6.27817.03 @BuiltBy: dlab14-DDVSOWINAGE101 @Branch: release/2.2 @SrcCode: https://github.com/dotnet/coreclr/tree/ce1d090d33b400a25620c0145046471495067cc7, Microsoft .NET Framework\n        // 3.0: 3.0.0-preview8.19379.2+ac25be694a5385a6a1496db40de932df0689b742, Microsoft .NET Core\n        // 5.0: 5.0.0-alpha1.19413.7+0ecefa44c9d66adb8a997d5778dc6c246ad393a7, Microsoft .NET Core\n        internal static bool TryGetVersionFromProductInfo(string productVersion, string productName, [NotNullWhen(true)] out Version? version)\n        {\n            if (productVersion.IsNotBlank() && productName.IsNotBlank())\n            {\n                if (productName.IndexOf(\".NET Core\", StringComparison.OrdinalIgnoreCase) >= 0)\n                {\n                    string parsableVersion = GetParsableVersionPart(productVersion);\n                    if (Version.TryParse(productVersion, out version) || Version.TryParse(parsableVersion, out version))\n                    {\n                        return true;\n                    }\n                }\n\n                // yes, .NET Core 2.X has a product name == .NET Framework...\n                if (productName.IndexOf(\".NET Framework\", StringComparison.OrdinalIgnoreCase) >= 0)\n                {\n                    const string releaseVersionPrefix = \"release/\";\n                    int releaseVersionIndex = productVersion.IndexOf(releaseVersionPrefix, StringComparison.Ordinal);\n                    if (releaseVersionIndex > 0)\n                    {\n                        string releaseVersion = GetParsableVersionPart(productVersion.Substring(releaseVersionIndex + releaseVersionPrefix.Length));\n\n                        return Version.TryParse(releaseVersion, out version);\n                    }\n                }\n            }\n\n            version = null;\n            return false;\n        }\n\n        // sample input:\n        // .NETCoreApp,Version=v2.0\n        // .NETCoreApp,Version=v2.1\n        internal static bool TryGetVersionFromFrameworkName(string frameworkName, [NotNullWhen(true)] out Version? version)\n        {\n            const string versionPrefix = \".NETCoreApp,Version=v\";\n            if (frameworkName.IsNotBlank() && frameworkName.StartsWith(versionPrefix))\n            {\n                string frameworkVersion = GetParsableVersionPart(frameworkName.Substring(versionPrefix.Length));\n\n                return Version.TryParse(frameworkVersion, out version);\n            }\n\n            version = null;\n            return false;\n        }\n\n        // Version.TryParse does not handle thing like 3.0.0-WORD\n        internal static string GetParsableVersionPart(string fullVersionName) => new string(fullVersionName.TakeWhile(c => char.IsDigit(c) || c == '.').ToArray());\n\n        private static CoreRuntime GetPlatformSpecific(CoreRuntime fallback, Assembly? assembly)\n            => TryGetTargetPlatform(assembly ?? Assembly.GetEntryAssembly(), out var platform)\n                ? new CoreRuntime(fallback.RuntimeMoniker, $\"{fallback.MsBuildMoniker}-{platform}\", fallback.Name)\n                : fallback;\n\n        private static bool TryGetTargetPlatform(Assembly? assembly, [NotNullWhen(true)] out string? platform)\n        {\n            platform = null;\n\n            if (assembly is null)\n                return false;\n\n            // TargetPlatformAttribute is not part of .NET Standard 2.0 so as usual we have to use some reflection hacks.\n            var targetPlatformAttributeType = typeof(object).Assembly.GetType(\"System.Runtime.Versioning.TargetPlatformAttribute\", throwOnError: false);\n            if (targetPlatformAttributeType is null) // an old preview version of .NET 5\n                return false;\n\n            var attributeInstance = assembly.GetCustomAttribute(targetPlatformAttributeType);\n            if (attributeInstance is null)\n                return false;\n\n            var platformNameProperty = targetPlatformAttributeType.GetProperty(\"PlatformName\");\n            if (platformNameProperty is null)\n                return false;\n\n            platform = platformNameProperty.GetValue(attributeInstance) as string;\n            return platform.IsNotBlank();\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Environments/Runtimes/CustomRuntime.cs",
    "content": "using BenchmarkDotNet.Jobs;\n\nnamespace BenchmarkDotNet.Environments\n{\n    public abstract class CustomRuntime : Runtime\n    {\n        protected CustomRuntime(RuntimeMoniker runtimeMoniker, string msBuildMoniker, string displayName)\n            : base(runtimeMoniker, msBuildMoniker, displayName)\n        {\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Environments/Runtimes/MonoAotLLVMRuntime.cs",
    "content": "﻿using BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Toolchains.MonoAotLLVM;\nusing System;\nusing System.ComponentModel;\nusing System.IO;\n\nnamespace BenchmarkDotNet.Environments\n{\n    public class MonoAotLLVMRuntime : Runtime, IEquatable<MonoAotLLVMRuntime>\n    {\n        [EditorBrowsable(EditorBrowsableState.Never)]\n        internal static readonly MonoAotLLVMRuntime Default = new MonoAotLLVMRuntime();\n\n        public FileInfo AOTCompilerPath { get; }\n        public MonoAotCompilerMode AOTCompilerMode { get; }\n\n        public override bool IsAOT => true;\n\n        /// <summary>\n        /// creates new instance of MonoAotLLVMRuntime\n        /// </summary>\n        public MonoAotLLVMRuntime(FileInfo? aotCompilerPath, MonoAotCompilerMode aotCompilerMode, string msBuildMoniker = \"net6.0\", string displayName = \"MonoAOTLLVM\", RuntimeMoniker moniker = RuntimeMoniker.MonoAOTLLVM) : base(moniker, msBuildMoniker, displayName)\n        {\n            ArgumentNullException.ThrowIfNull(aotCompilerPath);\n\n            if (aotCompilerPath.IsNotNullButDoesNotExist())\n                throw new FileNotFoundException($\"Provided {nameof(aotCompilerPath)} file: \\\"{aotCompilerPath.FullName}\\\" doest NOT exist\");\n\n            AOTCompilerPath = aotCompilerPath;\n            AOTCompilerMode = aotCompilerMode;\n        }\n\n        // this ctor exists only for the purpose of having .Default property that returns something consumable by RuntimeInformation.GetCurrentRuntime()\n        private MonoAotLLVMRuntime(string msBuildMoniker = \"net6.0\", string displayName = \"MonoAOTLLVM\") : base(RuntimeMoniker.MonoAOTLLVM, msBuildMoniker, displayName)\n        {\n            AOTCompilerPath = new FileInfo(\"fake\");\n        }\n\n        public override bool Equals(object? obj)\n            => obj is MonoAotLLVMRuntime other && Equals(other);\n\n        public bool Equals(MonoAotLLVMRuntime? other)\n            => other != null && base.Equals(other) && other.AOTCompilerPath == AOTCompilerPath;\n\n        public override int GetHashCode()\n            => HashCode.Combine(base.GetHashCode(), AOTCompilerPath);\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Environments/Runtimes/MonoRuntime.cs",
    "content": "﻿using System;\nusing BenchmarkDotNet.Jobs;\n\nnamespace BenchmarkDotNet.Environments\n{\n    public class MonoRuntime : Runtime, IEquatable<MonoRuntime>\n    {\n        public static readonly MonoRuntime Default = new(\"Mono\");\n        public static readonly MonoRuntime Mono60 = new(\"Mono with .NET 6.0\", RuntimeMoniker.Mono60, \"net6.0\", isDotNetBuiltIn: true);\n        public static readonly MonoRuntime Mono70 = new(\"Mono with .NET 7.0\", RuntimeMoniker.Mono70, \"net7.0\", isDotNetBuiltIn: true);\n        public static readonly MonoRuntime Mono80 = new(\"Mono with .NET 8.0\", RuntimeMoniker.Mono80, \"net8.0\", isDotNetBuiltIn: true);\n\n        public string CustomPath { get; } = \"\";\n\n        public string AotArgs { get; } = \"\";\n\n        public override bool IsAOT => !string.IsNullOrEmpty(AotArgs);\n\n        public string MonoBclPath { get; } = \"\";\n\n        internal bool IsDotNetBuiltIn { get; }\n\n        private MonoRuntime(string name) : base(RuntimeMoniker.Mono, \"mono\", name) { }\n\n        private MonoRuntime(string name, RuntimeMoniker runtimeMoniker, string msBuildMoniker, bool isDotNetBuiltIn) : base(runtimeMoniker, msBuildMoniker, name)\n        {\n            IsDotNetBuiltIn = isDotNetBuiltIn;\n        }\n\n        public MonoRuntime(string name, string customPath) : this(name) => CustomPath = customPath;\n\n        public MonoRuntime(string name, string customPath, string aotArgs, string monoBclPath) : this(name)\n        {\n            CustomPath = customPath;\n            AotArgs = aotArgs;\n            MonoBclPath = monoBclPath;\n        }\n\n        public override bool Equals(object? obj)\n            => obj is MonoRuntime runtime && Equals(runtime);\n\n        public bool Equals(MonoRuntime? other)\n        {\n            if (other is null)\n                return false;\n            if (ReferenceEquals(this, other))\n                return true;\n\n            return base.Equals(other)\n                && Name == other.Name\n                && CustomPath == other.CustomPath\n                && AotArgs == other.AotArgs\n                && MonoBclPath == other.MonoBclPath;\n        }\n\n        public override int GetHashCode()\n            => HashCode.Combine(base.GetHashCode(), Name, CustomPath, AotArgs, MonoBclPath);\n\n        internal static Runtime GetCurrentVersion()\n        {\n            Version version = Environment.Version;\n            return version.Major switch\n            {\n                6 => Mono60,\n                7 => Mono70,\n                8 => Mono80,\n                _ => new MonoRuntime($\"Mono with .NET {version.Major}.{version.Minor}\", RuntimeMoniker.NotRecognized, $\"net{version.Major}.{version.Minor}\", isDotNetBuiltIn: true)\n            };\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Environments/Runtimes/NativeAotRuntime.cs",
    "content": "﻿using BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Portability;\nusing System;\n\nnamespace BenchmarkDotNet.Environments\n{\n    public class NativeAotRuntime : Runtime\n    {\n        /// <summary>\n        /// NativeAOT compiled as net6.0\n        /// </summary>\n        public static readonly NativeAotRuntime Net60 = new NativeAotRuntime(RuntimeMoniker.NativeAot60, \"net6.0\", \"NativeAOT 6.0\");\n        /// <summary>\n        /// NativeAOT compiled as net7.0\n        /// </summary>\n        public static readonly NativeAotRuntime Net70 = new NativeAotRuntime(RuntimeMoniker.NativeAot70, \"net7.0\", \"NativeAOT 7.0\");\n        /// <summary>\n        /// NativeAOT compiled as net8.0\n        /// </summary>\n        public static readonly NativeAotRuntime Net80 = new NativeAotRuntime(RuntimeMoniker.NativeAot80, \"net8.0\", \"NativeAOT 8.0\");\n        /// <summary>\n        /// NativeAOT compiled as net9.0\n        /// </summary>\n        public static readonly NativeAotRuntime Net90 = new NativeAotRuntime(RuntimeMoniker.NativeAot90, \"net9.0\", \"NativeAOT 9.0\");\n        /// <summary>\n        /// NativeAOT compiled as net10.0\n        /// </summary>\n        public static readonly NativeAotRuntime Net10_0 = new NativeAotRuntime(RuntimeMoniker.NativeAot10_0, \"net10.0\", \"NativeAOT 10.0\");\n        /// <summary>\n        /// NativeAOT compiled as net11.0\n        /// </summary>\n        public static readonly NativeAotRuntime Net11_0 = new NativeAotRuntime(RuntimeMoniker.NativeAot11_0, \"net11.0\", \"NativeAOT 11.0\");\n\n        public override bool IsAOT => true;\n\n        private NativeAotRuntime(RuntimeMoniker runtimeMoniker, string msBuildMoniker, string displayName)\n            : base(runtimeMoniker, msBuildMoniker, displayName)\n        {\n        }\n\n        public static NativeAotRuntime GetCurrentVersion()\n        {\n            if (!RuntimeInformation.IsNetCore && !RuntimeInformation.IsNativeAOT)\n            {\n                throw new NotSupportedException(\"It's impossible to reliably detect the version of NativeAOT if the process is not a .NET or NativeAOT process!\");\n            }\n\n            if (!CoreRuntime.TryGetVersion(out var version))\n            {\n                throw new NotSupportedException(\"Failed to recognize NativeAOT version\");\n            }\n\n            switch (version)\n            {\n                case Version v when v.Major == 6 && v.Minor == 0: return Net60;\n                case Version v when v.Major == 7 && v.Minor == 0: return Net70;\n                case Version v when v.Major == 8 && v.Minor == 0: return Net80;\n                case Version v when v.Major == 9 && v.Minor == 0: return Net90;\n                case Version v when v.Major == 10 && v.Minor == 0: return Net10_0;\n                case Version v when v.Major == 11 && v.Minor == 0: return Net11_0;\n                default:\n                    return new NativeAotRuntime(RuntimeMoniker.NotRecognized, $\"net{version.Major}.{version.Minor}\", $\"NativeAOT {version.Major}.{version.Minor}\");\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Environments/Runtimes/R2RRuntime.cs",
    "content": "﻿using BenchmarkDotNet.Jobs;\nusing System;\nusing System.Collections.Generic;\nusing System.Text;\n\nnamespace BenchmarkDotNet.Environments\n{\n    public class R2RRuntime : Runtime\n    {\n        public static readonly R2RRuntime Net80 = new R2RRuntime(RuntimeMoniker.R2R80, \"net8.0\", \"R2R 8.0\");\n        public static readonly R2RRuntime Net90 = new R2RRuntime(RuntimeMoniker.R2R90, \"net9.0\", \"R2R 9.0\");\n        public static readonly R2RRuntime Net10_0 = new R2RRuntime(RuntimeMoniker.R2R10_0, \"net10.0\", \"R2R 10.0\");\n        public static readonly R2RRuntime Net11_0 = new R2RRuntime(RuntimeMoniker.R2R11_0, \"net11.0\", \"R2R 11.0\");\n\n        private R2RRuntime(RuntimeMoniker runtimeMoniker, string msBuildMoniker, string displayName)\n            : base(runtimeMoniker, msBuildMoniker, displayName)\n        {\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Environments/Runtimes/Runtime.cs",
    "content": "﻿using System;\nusing BenchmarkDotNet.Jobs;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Environments\n{\n    public abstract class Runtime : IEquatable<Runtime>\n    {\n        /// <summary>\n        /// Display name\n        /// </summary>\n        [PublicAPI]\n        public string Name { get; }\n\n        /// <summary>\n        /// Target Framework Moniker\n        /// </summary>\n        public RuntimeMoniker RuntimeMoniker { get; }\n\n        /// <summary>\n        /// MsBuild Target Framework Moniker, example: net462, net8.0\n        /// </summary>\n        public string MsBuildMoniker { get; }\n\n        public virtual bool IsAOT => false;\n\n        protected Runtime(RuntimeMoniker runtimeMoniker, string msBuildMoniker, string displayName)\n        {\n            if (string.IsNullOrEmpty(displayName)) throw new ArgumentNullException(nameof(displayName));\n            if (string.IsNullOrEmpty(msBuildMoniker)) throw new ArgumentNullException(nameof(msBuildMoniker));\n\n            RuntimeMoniker = runtimeMoniker;\n            MsBuildMoniker = msBuildMoniker;\n            Name = displayName;\n        }\n\n        public override string ToString() => Name;\n\n        public bool Equals(Runtime? other)\n            => other != null && other.Name == Name && other.MsBuildMoniker == MsBuildMoniker && other.RuntimeMoniker == RuntimeMoniker;\n\n        public override bool Equals(object? obj) => obj is Runtime other && Equals(other);\n\n        public override int GetHashCode() => HashCode.Combine(Name, MsBuildMoniker, RuntimeMoniker);\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Environments/Runtimes/WasmRuntime.cs",
    "content": "﻿using System;\nusing System.ComponentModel;\nusing System.IO;\nusing BenchmarkDotNet.Helpers;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Portability;\nusing BenchmarkDotNet.Toolchains;\n\nnamespace BenchmarkDotNet.Environments\n{\n    public class WasmRuntime : Runtime, IEquatable<WasmRuntime>\n    {\n        public delegate string ArgumentFormatter(WasmRuntime runtime, ArtifactsPaths artifactsPaths, string args);\n\n        [EditorBrowsable(EditorBrowsableState.Never)]\n        internal static readonly WasmRuntime Default = new WasmRuntime();\n\n        public string JavaScriptEngine { get; }\n\n        public string JavaScriptEngineArguments { get; }\n\n        public ArgumentFormatter JavaScriptEngineArgumentFormatter { get; }\n\n        public override bool IsAOT { get; }\n\n        /// <summary>\n        /// Specifies the runtime flavor used for WASM benchmarks. <see cref=\"Environments.RuntimeFlavor.Mono\"/> (default) resolves the\n        /// Mono runtime pack (Microsoft.NETCore.App.Runtime.Mono.browser-wasm); <see cref=\"Environments.RuntimeFlavor.CoreCLR\"/> resolves\n        /// the CoreCLR runtime pack (Microsoft.NETCore.App.Runtime.browser-wasm).\n        /// </summary>\n        public RuntimeFlavor RuntimeFlavor { get; }\n\n        /// <summary>\n        /// Maximum time in minutes to wait for a single benchmark process to finish before force killing it. Default is 10 minutes.\n        /// </summary>\n        public int ProcessTimeoutMinutes { get; }\n\n        public FileInfo? MainJsTemplate { get; set; }\n\n        /// <summary>\n        /// creates new instance of WasmRuntime\n        /// </summary>\n        /// <param name=\"msBuildMoniker\">moniker</param>\n        /// <param name=\"moniker\">Runtime moniker</param>\n        /// <param name=\"displayName\">display name</param>\n        /// <param name=\"aot\">Specifies whether AOT or Interpreter project should be generated.</param>\n        /// <param name=\"javaScriptEngine\">Full path to a java script engine used to run the benchmarks.</param>\n        /// <param name=\"javaScriptEngineArguments\">Arguments for the javascript engine.</param>\n        /// <param name=\"runtimeFlavor\">Runtime flavor to use: Mono (default) or CoreCLR.</param>\n        /// <param name=\"processTimeoutMinutes\">Maximum time in minutes to wait for a single benchmark process to finish. Default is 10.</param>\n        /// <param name=\"mainJsTemplate\">Optional custom template for the generated main.mjs file. If not provided, a default template will be used.</param>\n        /// <param name=\"javaScriptEngineArgumentFormatter\">Allows to format or customize the arguments passed to the javascript engine.</param>\n        public WasmRuntime(\n            string msBuildMoniker,\n            RuntimeMoniker moniker,\n            string displayName,\n            bool aot,\n            string javaScriptEngine,\n            string? javaScriptEngineArguments = \"\",\n            RuntimeFlavor runtimeFlavor = RuntimeFlavor.Mono,\n            int processTimeoutMinutes = 10,\n            FileInfo? mainJsTemplate = null,\n            ArgumentFormatter? javaScriptEngineArgumentFormatter = null) : base(moniker, msBuildMoniker, displayName)\n        {\n            // Resolve path for windows because we can't use ProcessStartInfo.UseShellExecute while redirecting std out in the executor.\n            if (!ProcessHelper.TryResolveExecutableInPath(javaScriptEngine, out javaScriptEngine!))\n                throw new FileNotFoundException($\"Provided {nameof(javaScriptEngine)} file: \\\"{javaScriptEngine}\\\" does NOT exist\");\n\n            JavaScriptEngine = javaScriptEngine;\n            JavaScriptEngineArguments = javaScriptEngineArguments ?? \"\";\n            JavaScriptEngineArgumentFormatter = javaScriptEngineArgumentFormatter ?? DefaultArgumentFormatter;\n            RuntimeFlavor = runtimeFlavor;\n            IsAOT = aot;\n            ProcessTimeoutMinutes = processTimeoutMinutes;\n            MainJsTemplate = mainJsTemplate;\n        }\n\n        private WasmRuntime() : base(RuntimeMoniker.WasmNet80, \"Wasm\", \"Wasm\")\n        {\n            IsAOT = RuntimeInformation.IsAot;\n            JavaScriptEngine = \"\";\n            JavaScriptEngineArguments = \"\";\n            ProcessTimeoutMinutes = 10;\n            JavaScriptEngineArgumentFormatter = DefaultArgumentFormatter;\n        }\n\n        public override bool Equals(object? obj)\n            => obj is WasmRuntime other && Equals(other);\n\n        public bool Equals(WasmRuntime? other)\n        {\n            return other != null\n                && base.Equals(other)\n                && other.JavaScriptEngine == JavaScriptEngine\n                && other.JavaScriptEngineArguments == JavaScriptEngineArguments\n                && other.JavaScriptEngineArgumentFormatter == JavaScriptEngineArgumentFormatter\n                && other.IsAOT == IsAOT\n                && other.ProcessTimeoutMinutes == ProcessTimeoutMinutes\n                && other.RuntimeFlavor == RuntimeFlavor;\n        }\n\n        public override int GetHashCode()\n            => HashCode.Combine(base.GetHashCode(), JavaScriptEngine, JavaScriptEngineArguments, JavaScriptEngineArgumentFormatter, IsAOT, RuntimeFlavor, ProcessTimeoutMinutes);\n\n        private static string DefaultArgumentFormatter(WasmRuntime runtime, ArtifactsPaths artifactsPaths, string args)\n        {\n            return Path.GetFileNameWithoutExtension(runtime.JavaScriptEngine).ToLower() switch\n            {\n                \"node\" or \"bun\" => $\"{runtime.JavaScriptEngineArguments} {artifactsPaths.ExecutablePath} -- --run {artifactsPaths.ProgramName}.dll {args}\",\n                _ => $\"{runtime.JavaScriptEngineArguments} --module {artifactsPaths.ExecutablePath} -- --run {artifactsPaths.ProgramName}.dll {args}\",\n            };\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/EventProcessors/CompositeEventProcessor.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Toolchains.Results;\nusing BenchmarkDotNet.Validators;\n\nnamespace BenchmarkDotNet.EventProcessors\n{\n    internal sealed class CompositeEventProcessor : EventProcessor\n    {\n        private readonly HashSet<EventProcessor> eventProcessors;\n\n        public CompositeEventProcessor(BenchmarkRunInfo[] benchmarkRunInfos)\n        {\n            var eventProcessors = new HashSet<EventProcessor>();\n\n            foreach (var info in benchmarkRunInfos)\n                eventProcessors.AddRange(info.Config.GetEventProcessors());\n\n            this.eventProcessors = eventProcessors;\n        }\n\n        public override void OnStartValidationStage()\n        {\n            foreach (var eventProcessor in eventProcessors)\n                eventProcessor.OnStartValidationStage();\n        }\n\n        public override void OnValidationError(ValidationError validationError)\n        {\n            foreach (var eventProcessor in eventProcessors)\n                eventProcessor.OnValidationError(validationError);\n        }\n\n        public override void OnEndValidationStage()\n        {\n            foreach (var eventProcessor in eventProcessors)\n                eventProcessor.OnEndValidationStage();\n        }\n\n        public override void OnStartBuildStage(IReadOnlyList<BuildPartition> partitions)\n        {\n            foreach (var eventProcessor in eventProcessors)\n                eventProcessor.OnStartBuildStage(partitions);\n        }\n\n        public override void OnBuildComplete(BuildPartition buildPartition, BuildResult buildResult)\n        {\n            foreach (var eventProcessor in eventProcessors)\n                eventProcessor.OnBuildComplete(buildPartition, buildResult);\n        }\n\n        public override void OnEndBuildStage()\n        {\n            foreach (var eventProcessor in eventProcessors)\n                eventProcessor.OnEndBuildStage();\n        }\n\n        public override void OnStartRunStage()\n        {\n            foreach (var eventProcessor in eventProcessors)\n                eventProcessor.OnStartRunStage();\n        }\n\n        public override void OnEndRunStage()\n        {\n            foreach (var eventProcessor in eventProcessors)\n                eventProcessor.OnEndRunStage();\n        }\n\n        public override void OnStartRunBenchmarksInType(Type type, IReadOnlyList<BenchmarkCase> benchmarks)\n        {\n            foreach (var eventProcessor in eventProcessors)\n                eventProcessor.OnStartRunBenchmarksInType(type, benchmarks);\n        }\n\n        public override void OnEndRunBenchmarksInType(Type type, Summary summary)\n        {\n            foreach (var eventProcessor in eventProcessors)\n                eventProcessor.OnEndRunBenchmarksInType(type, summary);\n        }\n\n        public override void OnEndRunBenchmark(BenchmarkCase benchmarkCase, BenchmarkReport report)\n        {\n            foreach (var eventProcessor in eventProcessors)\n                eventProcessor.OnEndRunBenchmark(benchmarkCase, report);\n        }\n\n        public override void OnStartRunBenchmark(BenchmarkCase benchmarkCase)\n        {\n            foreach (var eventProcessor in eventProcessors)\n                eventProcessor.OnStartRunBenchmark(benchmarkCase);\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/EventProcessors/EventProcessor.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Toolchains.Results;\nusing BenchmarkDotNet.Validators;\n\nnamespace BenchmarkDotNet.EventProcessors\n{\n    public abstract class EventProcessor\n    {\n        public virtual void OnStartValidationStage() { }\n        public virtual void OnValidationError(ValidationError validationError) { }\n        public virtual void OnEndValidationStage() { }\n        public virtual void OnStartBuildStage(IReadOnlyList<BuildPartition> partitions) { }\n        public virtual void OnBuildComplete(BuildPartition partition, BuildResult buildResult) { }\n        public virtual void OnEndBuildStage() { }\n        public virtual void OnStartRunStage() { }\n        public virtual void OnStartRunBenchmarksInType(Type type, IReadOnlyList<BenchmarkCase> benchmarks) { }\n        public virtual void OnEndRunBenchmarksInType(Type type, Summary summary) { }\n        public virtual void OnStartRunBenchmark(BenchmarkCase benchmarkCase) { }\n        public virtual void OnEndRunBenchmark(BenchmarkCase benchmarkCase, BenchmarkReport report) { }\n        public virtual void OnEndRunStage() { }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Exporters/AsciiDocExporter.cs",
    "content": "﻿using System.Linq;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Reports;\n\nnamespace BenchmarkDotNet.Exporters\n{\n    public class AsciiDocExporter : ExporterBase\n    {\n        protected override string FileExtension => \"asciidoc\";\n\n        public static readonly IExporter Default = new AsciiDocExporter();\n\n        private AsciiDocExporter()\n        {\n        }\n\n        public override void ExportToLog(Summary summary, ILogger logger)\n        {\n            logger.WriteLine(\"....\");\n            foreach (string infoLine in summary.HostEnvironmentInfo.ToFormattedString())\n            {\n                logger.WriteLineInfo(infoLine);\n            }\n            logger.WriteLineInfo(summary.AllRuntimes);\n            logger.WriteLine();\n\n            PrintTable(summary.Table, logger);\n\n            var benchmarksWithTroubles = summary.Reports\n                .Where(r => !r.GetResultRuns().Any())\n                .Select(r => r.BenchmarkCase)\n                .ToList();\n\n            if (benchmarksWithTroubles.Count > 0)\n            {\n                logger.WriteLine();\n                logger.WriteLine(\"[WARNING]\");\n                logger.WriteLineError(\".Benchmarks with issues\");\n                logger.WriteLine(\"====\");\n                foreach (var benchmarkWithTroubles in benchmarksWithTroubles)\n                    logger.WriteLineError(\"* \" + benchmarkWithTroubles.DisplayInfo);\n                logger.WriteLine(\"====\");\n            }\n        }\n\n        private static void PrintTable(SummaryTable table, ILogger logger)\n        {\n            if (table.FullContent.Length == 0)\n            {\n                logger.WriteLine(\"[WARNING]\");\n                logger.WriteLine(\"====\");\n                logger.WriteLineError(\"There are no benchmarks found \");\n                logger.WriteLine(\"====\");\n                logger.WriteLine();\n                return;\n            }\n\n            table.PrintCommonColumns(logger);\n            logger.WriteLine(\"....\");\n\n            logger.WriteLine(\"[options=\\\"header\\\"]\");\n            logger.WriteLine(\"|===\");\n            table.PrintLine(table.FullHeader, logger, \"|\", string.Empty);\n            foreach (var line in table.FullContent)\n                table.PrintLine(line, logger, \"|\", string.Empty);\n            logger.WriteLine(\"|===\");\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Exporters/BenchmarkReportExporter.cs",
    "content": "﻿using BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Reports;\n\nnamespace BenchmarkDotNet.Exporters\n{\n    public class BenchmarkReportExporter: ExporterBase\n    {\n        public static readonly IExporter Default = new BenchmarkReportExporter();\n\n        private BenchmarkReportExporter()\n        {\n        }\n\n        public override void ExportToLog(Summary summary, ILogger logger)\n        {\n            foreach (var report in summary.Reports)\n            {\n                logger.WriteLineInfo(report.BenchmarkCase.DisplayInfo);\n                logger.WriteLineStatistic($\"Runtime = {report.GetRuntimeInfo()}; GC = {report.GetGcInfo()}\");\n                var resultRuns = report.GetResultRuns();\n                if (resultRuns.IsEmpty())\n                    logger.WriteLineError(\"There are not any results runs\");\n                else\n                {\n                    var statistics = resultRuns.GetStatistics();\n                    var cultureInfo = summary.GetCultureInfo();\n                    var formatter = statistics.CreateNanosecondFormatter(cultureInfo);\n                    logger.WriteLineStatistic(statistics.ToString(cultureInfo, formatter, calcHistogram: true));\n                }\n                logger.WriteLine();\n            }\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Exporters/CompositeExporter.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Collections.Immutable;\nusing System.Linq;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Reports;\n\nnamespace BenchmarkDotNet.Exporters\n{\n    public class CompositeExporter : IExporter\n    {\n        private readonly ImmutableArray<IExporter> exporters;\n\n        public CompositeExporter(ImmutableArray<IExporter> exporters) => this.exporters = exporters;\n\n        public string Name => nameof(CompositeExporter);\n\n        public void ExportToLog(Summary summary, ILogger logger)\n        {\n            if (summary.GetColumns().IsNullOrEmpty())\n                logger.WriteLineHint(\"You haven't configured any columns, your results will be empty\");\n\n            foreach (var exporter in exporters)\n            {\n                try\n                {\n                    exporter.ExportToLog(summary, logger);\n                }\n                catch (Exception e)\n                {\n                    logger.WriteLineError(e.ToString());\n                }\n            }\n        }\n\n        public IEnumerable<string> ExportToFiles(Summary summary, ILogger consoleLogger)\n            => exporters.SelectMany(exporter =>\n            {\n                var files = new List<string>();\n                try\n                {\n                    files.AddRange(exporter.ExportToFiles(summary, consoleLogger));\n                }\n                catch (Exception e)\n                {\n                    consoleLogger.WriteLineError(e.ToString());\n                }\n                return files;\n            });\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Exporters/Csv/CsvExporter.cs",
    "content": "﻿using BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Reports;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Exporters.Csv\n{\n    public class CsvExporter : ExporterBase\n    {\n        private readonly CsvSeparator separator;\n        private readonly SummaryStyle? style;\n        protected override string FileExtension => \"csv\";\n\n        public static readonly IExporter Default = new CsvExporter(CsvSeparator.CurrentCulture);\n\n        [PublicAPI]\n        public CsvExporter(CsvSeparator separator, SummaryStyle? style = null)\n        {\n            this.separator = separator;\n            this.style = style;\n        }\n\n        public override void ExportToLog(Summary summary, ILogger logger)\n        {\n            string realSeparator = separator.ToRealSeparator();\n            var exportStyle = (style ?? summary.Style).WithZeroMetricValuesInContent();\n            foreach (var line in summary.GetTable(exportStyle).FullContentWithHeader)\n            {\n                for (int i = 0; i < line.Length;)\n                {\n                    logger.Write(CsvHelper.Escape(line[i], realSeparator));\n\n                    if (++i < line.Length)\n                    {\n                        logger.Write(realSeparator);\n                    }\n                }\n\n                logger.WriteLine();\n            }\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Exporters/Csv/CsvHelper.cs",
    "content": "﻿using System.Linq;\n\nnamespace BenchmarkDotNet.Exporters.Csv\n{\n    // TODO: Introduce a CsvWriter class (based on ILogger and CsvSeparator)\n    public static class CsvHelper\n    {\n        private const string Quote = \"\\\"\";\n        private const string TwoQuotes = \"\\\"\\\"\";\n        private static readonly char[] ForbiddenSymbols = ['\\n', '\\r', '\"', ','];\n\n        public static string Escape(string? value, string currentListSeparator)\n        {\n            if (value == null)\n                return string.Empty;\n            // RFC 4180:\n            // 2.6: Fields containing line breaks (CRLF), double quotes, and commas should be enclosed in double-quotes.\n            // 2.7: If double-quotes are used to enclose fields, then a double-quote appearing inside a field must be escaped by preceding it with another double quote.\n            if (ForbiddenSymbols.Any(value.Contains) || value.Contains(currentListSeparator))\n                return Quote + value.Replace(Quote, TwoQuotes) + Quote;\n            return value;\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Exporters/Csv/CsvMeasurementsExporter.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing BenchmarkDotNet.Characteristics;\nusing BenchmarkDotNet.Columns;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Reports;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Exporters.Csv\n{\n    public class CsvMeasurementsExporter : ExporterBase\n    {\n        public static readonly CsvMeasurementsExporter Default = new CsvMeasurementsExporter(CsvSeparator.CurrentCulture, SummaryStyle.Default);\n        [PublicAPI] public static CsvMeasurementsExporter WithStyle(SummaryStyle style) => new CsvMeasurementsExporter(CsvSeparator.CurrentCulture, style);\n\n        private static readonly CharacteristicPresenter Presenter = CharacteristicPresenter.SummaryPresenter;\n\n        private static readonly Lazy<MeasurementColumn[]> Columns = new Lazy<MeasurementColumn[]>(BuildColumns);\n\n        private readonly CsvSeparator separator;\n        public CsvMeasurementsExporter(CsvSeparator separator, SummaryStyle? style = null)\n        {\n            this.separator = separator;\n            Style = style ?? SummaryStyle.Default;\n        }\n\n        public string Separator => separator.ToRealSeparator();\n\n        protected override string FileExtension => \"csv\";\n\n        protected override string FileCaption => \"measurements\";\n\n        [PublicAPI] public SummaryStyle Style { get; }\n\n        [PublicAPI] public static Job[] GetJobs(Summary summary) => summary.BenchmarksCases.Select(b => b.Job).ToArray();\n\n        public override void ExportToLog(Summary summary, ILogger logger)\n        {\n            string realSeparator = Separator;\n            var columns = GetColumns(summary);\n            logger.WriteLine(string.Join(realSeparator, columns.Select(c => CsvHelper.Escape(c.Title, realSeparator))));\n\n            foreach (var report in summary.Reports)\n            {\n                foreach (var measurement in report.AllMeasurements)\n                {\n                    for (int i = 0; i < columns.Length; )\n                    {\n                        logger.Write(CsvHelper.Escape(columns[i].GetValue(summary, report, measurement), realSeparator));\n\n                        if (++i < columns.Length)\n                        {\n                            logger.Write(realSeparator);\n                        }\n                    }\n                    logger.WriteLine();\n                }\n            }\n        }\n\n        private static MeasurementColumn[] GetColumns(Summary summary)\n        {\n            if (!summary.BenchmarksCases.Any(benchmark => benchmark.Config.HasMemoryDiagnoser()))\n                return Columns.Value;\n\n            var columns = new List<MeasurementColumn>(Columns.Value)\n            {\n                new MeasurementColumn(\"Gen_0\", (_, report, __) => report.GcStats.Gen0Collections.ToString(summary.GetCultureInfo())),\n                new MeasurementColumn(\"Gen_1\", (_, report, __) => report.GcStats.Gen1Collections.ToString(summary.GetCultureInfo())),\n                new MeasurementColumn(\"Gen_2\", (_, report, __) => report.GcStats.Gen2Collections.ToString(summary.GetCultureInfo())),\n                new MeasurementColumn(\"Allocated_Bytes\", (_, report, __) => report.GcStats.GetBytesAllocatedPerOperation(report.BenchmarkCase)?.ToString(summary.GetCultureInfo()) ?? MetricColumn.UnknownRepresentation)\n            };\n\n            return columns.ToArray();\n        }\n\n        private static MeasurementColumn[] BuildColumns()\n        {\n            // Target\n            var columns = new List<MeasurementColumn>\n            {\n                new MeasurementColumn(\"Target\", (summary, report, m) => report.BenchmarkCase.Descriptor.Type.Name + \".\" + report.BenchmarkCase.Descriptor.WorkloadMethodDisplayInfo),\n                new MeasurementColumn(\"Target_Namespace\", (summary, report, m) => report.BenchmarkCase.Descriptor.Type.Namespace ?? \"\"),\n                new MeasurementColumn(\"Target_Type\", (summary, report, m) => report.BenchmarkCase.Descriptor.Type.Name),\n                new MeasurementColumn(\"Target_Method\", (summary, report, m) => report.BenchmarkCase.Descriptor.WorkloadMethodDisplayInfo)\n            };\n\n            // Job\n            foreach (var characteristic in CharacteristicHelper.GetAllPresentableCharacteristics(typeof(Job), true))\n                columns.Add(new MeasurementColumn(\"Job_\" + characteristic.Id, (summary, report, m) => Presenter.ToPresentation(report.BenchmarkCase.Job, characteristic)));\n            columns.Add(new MeasurementColumn(\"Job_Display\", (summary, report, m) => report.BenchmarkCase.Job.DisplayInfo));\n\n            // Params\n            columns.Add(new MeasurementColumn(\"Params\", (summary, report, m) => report.BenchmarkCase.Parameters.PrintInfo));\n\n            // Measurements\n            columns.Add(new MeasurementColumn(\"Measurement_LaunchIndex\", (summary, report, m) => m.LaunchIndex.ToString()));\n            columns.Add(new MeasurementColumn(\"Measurement_IterationMode\", (summary, report, m) => m.IterationMode.ToString()));\n            columns.Add(new MeasurementColumn(\"Measurement_IterationStage\", (summary, report, m) => m.IterationStage.ToString()));\n            columns.Add(new MeasurementColumn(\"Measurement_IterationIndex\", (summary, report, m) => m.IterationIndex.ToString()));\n            columns.Add(new MeasurementColumn(\"Measurement_Nanoseconds\", (summary, report, m) => m.Nanoseconds.ToString(\"0.##\", summary.GetCultureInfo())));\n            columns.Add(new MeasurementColumn(\"Measurement_Operations\", (summary, report, m) => m.Operations.ToString()));\n            columns.Add(new MeasurementColumn(\"Measurement_Value\", (summary, report, m) => (m.Nanoseconds / m.Operations).ToString(\"0.##\", summary.GetCultureInfo())));\n\n            return columns.ToArray();\n        }\n\n        private struct MeasurementColumn\n        {\n            public string Title { get; }\n            public Func<Summary, BenchmarkReport, Measurement, string> GetValue { get; }\n\n            public MeasurementColumn(string title, Func<Summary, BenchmarkReport, Measurement, string> getValue)\n            {\n                Title = title;\n                GetValue = getValue;\n            }\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Exporters/Csv/CsvSeparator.cs",
    "content": "﻿namespace BenchmarkDotNet.Exporters.Csv\n{\n    public enum CsvSeparator\n    {\n        /// <summary>\n        /// ',' will be used as the CSV separator.\n        /// </summary>\n        Comma,\n\n        /// <summary>\n        /// ';' will be used as the CSV separator.\n        /// </summary>\n        Semicolon,\n\n        /// <summary>\n        ///\n        /// </summary>\n        CurrentCulture\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Exporters/Csv/CsvSeparatorExtensions.cs",
    "content": "﻿using System;\nusing System.Globalization;\nusing BenchmarkDotNet.Extensions;\n\nnamespace BenchmarkDotNet.Exporters.Csv\n{\n    public static class CsvSeparatorExtensions\n    {\n        /// <summary>\n        /// Return a string which represent real CSV separator which can be used as plain text.\n        /// </summary>\n        public static string ToRealSeparator(this CsvSeparator separator)\n        {\n            switch (separator)\n            {\n                case CsvSeparator.Comma:\n                    return \",\";\n                case CsvSeparator.Semicolon:\n                    return \";\";\n                case CsvSeparator.CurrentCulture:\n                    return CultureInfo.CurrentCulture.GetActualListSeparator();\n                default:\n                    throw new ArgumentOutOfRangeException(nameof(separator));\n            }\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Exporters/DefaultExporters.cs",
    "content": "﻿using BenchmarkDotNet.Exporters.Csv;\nusing BenchmarkDotNet.Exporters.Json;\nusing BenchmarkDotNet.Exporters.OpenMetrics;\nusing BenchmarkDotNet.Exporters.Xml;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Exporters\n{\n    public static class DefaultExporters\n    {\n        [PublicAPI] public static readonly IExporter AsciiDoc = AsciiDocExporter.Default;\n        [PublicAPI] public static readonly IExporter Csv = CsvExporter.Default;\n        [PublicAPI] public static readonly IExporter CsvMeasurements = CsvMeasurementsExporter.Default;\n        [PublicAPI] public static readonly IExporter Html = HtmlExporter.Default;\n        [PublicAPI] public static readonly IExporter Markdown = MarkdownExporter.Default;\n        [PublicAPI] public static readonly IExporter OpenMetrics = OpenMetricsExporter.Default;\n        [PublicAPI] public static readonly IExporter Plain = PlainExporter.Default;\n        [PublicAPI] public static readonly IExporter RPlot = RPlotExporter.Default;\n\n        [PublicAPI] public static readonly IExporter Json = JsonExporter.Default;\n        [PublicAPI] public static readonly IExporter JsonBrief = JsonExporter.Brief;\n        [PublicAPI] public static readonly IExporter JsonBriefCompressed = JsonExporter.BriefCompressed;\n        [PublicAPI] public static readonly IExporter JsonFull = JsonExporter.Full;\n        [PublicAPI] public static readonly IExporter JsonFullCompressed = JsonExporter.FullCompressed;\n\n        [PublicAPI] public static readonly IExporter Xml = XmlExporter.Default;\n        [PublicAPI] public static readonly IExporter XmlBrief = XmlExporter.Brief;\n        [PublicAPI] public static readonly IExporter XmlBriefCompressed = XmlExporter.BriefCompressed;\n        [PublicAPI] public static readonly IExporter XmlFull = XmlExporter.Full;\n        [PublicAPI] public static readonly IExporter XmlFullCompressed = XmlExporter.FullCompressed;\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Exporters/ExporterBase.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing BenchmarkDotNet.Helpers;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Reports;\n\nnamespace BenchmarkDotNet.Exporters\n{\n    public abstract class ExporterBase : IExporter\n    {\n        public string Name => $\"{GetType().Name}{FileNameSuffix}\";\n\n        protected virtual string FileExtension => \"txt\";\n        protected virtual string FileNameSuffix => string.Empty;\n        protected virtual string FileCaption => \"report\";\n\n        public abstract void ExportToLog(Summary summary, ILogger logger);\n\n        public IEnumerable<string> ExportToFiles(Summary summary, ILogger consoleLogger)\n        {\n            string fileName = GetFileName(summary);\n            string filePath = GetArtifactFullName(summary);\n            if (File.Exists(filePath))\n            {\n                try\n                {\n                    File.Delete(filePath);\n                }\n                catch (IOException)\n                {\n                    string uniqueString = DateTime.Now.ToString(\"yyyyMMdd-HHmmss\");\n                    string alternativeFilePath = $\"{Path.Combine(summary.ResultsDirectoryPath, fileName)}-{FileCaption}{FileNameSuffix}-{uniqueString}.{FileExtension}\";\n                    consoleLogger.WriteLineError($\"Could not overwrite file {filePath}. Exporting to {alternativeFilePath}\");\n                    filePath = alternativeFilePath;\n                }\n            }\n\n            using (var stream = new StreamWriter(filePath, append: false))\n            {\n                using (var streamLogger = new StreamLogger(stream))\n                {\n                    ExportToLog(summary, streamLogger);\n                }\n            }\n\n            return [filePath];\n        }\n\n        public string GetArtifactFullName(Summary summary)\n        {\n            string fileName = GetFileName(summary);\n            return $\"{Path.Combine(summary.ResultsDirectoryPath, fileName)}-{FileCaption}{FileNameSuffix}.{FileExtension}\";\n        }\n\n        private static string GetFileName(Summary summary)\n        {\n            // we can't use simple name here, because user might be running benchmarks for a library,  which defines few types with the same name\n            // and reports the results per type, so every summary is going to contain just single benchmark\n            // and we can't tell here if there is a name conflict or not\n            var targets = summary.BenchmarksCases.Select(b => b.Descriptor.Type).Distinct().ToArray();\n\n            if (targets.Length == 1)\n                return FolderNameHelper.ToFolderName(targets.Single());\n\n            return summary.Title;\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Exporters/FullNameProvider.cs",
    "content": "﻿using System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Reflection;\nusing System.Text;\nusing BenchmarkDotNet.Code;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Parameters;\nusing BenchmarkDotNet.Running;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Exporters\n{\n    public static class FullNameProvider\n    {\n        private static readonly IReadOnlyDictionary<Type, string> Aliases = new Dictionary<Type, string>\n        {\n            { typeof(byte), \"byte\" },\n            { typeof(sbyte), \"sbyte\" },\n            { typeof(short), \"short\" },\n            { typeof(ushort), \"ushort\" },\n            { typeof(int), \"int\" },\n            { typeof(uint), \"uint\" },\n            { typeof(long), \"long\" },\n            { typeof(ulong), \"ulong\" },\n            { typeof(float), \"float\" },\n            { typeof(double), \"double\" },\n            { typeof(decimal), \"decimal\" },\n            { typeof(object), \"object\" },\n            { typeof(bool), \"bool\" },\n            { typeof(char), \"char\" },\n            { typeof(string), \"string\" },\n            { typeof(byte?), \"byte?\" },\n            { typeof(sbyte?), \"sbyte?\" },\n            { typeof(short?), \"short?\" },\n            { typeof(ushort?), \"ushort?\" },\n            { typeof(int?), \"int?\" },\n            { typeof(uint?), \"uint?\" },\n            { typeof(long?), \"long?\" },\n            { typeof(ulong?), \"ulong?\" },\n            { typeof(float?), \"float?\" },\n            { typeof(double?), \"double?\" },\n            { typeof(decimal?), \"decimal?\" },\n            { typeof(bool?), \"bool?\" },\n            { typeof(char?), \"char?\" }\n        };\n\n        [PublicAPI(\"used by the dotnet/performance repository\")]\n        public static string GetBenchmarkName(BenchmarkCase benchmarkCase)\n        {\n            var type = benchmarkCase.Descriptor.Type;\n\n            // we can't just use type.FullName because we need sth different for generics (it reports SimpleGeneric`1[[System.Int32, mscorlib, Version=4.0.0.0)\n            var name = new StringBuilder();\n\n            if (type.Namespace.IsNotBlank())\n                name.Append(type.Namespace).Append('.');\n\n            name.Append(GetNestedTypes(type));\n\n            name.Append(GetTypeName(type)).Append('.');\n\n            name.Append(GetMethodName(benchmarkCase));\n\n            return name.ToString();\n        }\n\n        private static string GetNestedTypes(Type type)\n        {\n            string nestedTypes = \"\";\n            Type child = type, parent = type.DeclaringType!;\n            while (child.IsNested && parent != null)\n            {\n                nestedTypes = parent.Name + \"+\" + nestedTypes;\n\n                child = parent;\n                parent = parent.DeclaringType!;\n            }\n\n            return nestedTypes;\n        }\n\n        internal static string GetTypeName(Type type)\n        {\n            if (!type.IsGenericType)\n                return type.Name;\n\n            string mainName = type.Name.Substring(0, type.Name.IndexOf('`'));\n            string args = string.Join(\", \", type.GetGenericArguments().Select(GetTypeName).ToArray());\n\n            return $\"{mainName}<{args}>\";\n        }\n\n        internal static string GetMethodName(BenchmarkCase benchmarkCase)\n        {\n            var name = new StringBuilder(benchmarkCase.Descriptor.WorkloadMethod.Name);\n\n            if (benchmarkCase.HasParameters)\n                name.Append(GetBenchmarkParameters(benchmarkCase.Descriptor.WorkloadMethod, benchmarkCase.Parameters));\n\n            return name.ToString();\n        }\n\n        private static string GetBenchmarkParameters(MethodInfo method, ParameterInstances benchmarkParameters)\n        {\n            var methodArguments = method.GetParameters();\n            var benchmarkParams = benchmarkParameters.Items.Where(parameter => !parameter.IsArgument).ToArray();\n            var parametersBuilder = new StringBuilder(methodArguments.Length * 20).Append('(');\n\n            for (int i = 0; i < methodArguments.Length; i++)\n            {\n                if (i > 0)\n                    parametersBuilder.Append(\", \");\n\n                parametersBuilder.Append(methodArguments[i].Name).Append(':').Append(' ');\n                parametersBuilder.Append(GetArgument(benchmarkParameters.GetArgument(methodArguments[i].Name!).Value, methodArguments[i].ParameterType));\n            }\n\n            for (int i = 0; i < benchmarkParams.Length; i++)\n            {\n                var parameter = benchmarkParams[i];\n\n                if (methodArguments.Length > 0 || i > 0)\n                    parametersBuilder.Append(\", \");\n\n                parametersBuilder.Append(parameter.Name).Append(':').Append(' ');\n                parametersBuilder.Append(GetArgument(parameter.Value, parameter.Definition.ParameterType));\n            }\n\n            return parametersBuilder.Append(')').ToString();\n        }\n\n        private static string GetArgument(object? argumentValue, Type? argumentType)\n        {\n            switch (argumentValue) {\n                case null:\n                    return \"null\";\n                case IParam iparam:\n                    return GetArgument(iparam.Value, argumentType);\n                case object[] array when array.Length == 1:\n                    return GetArgument(array[0], argumentType);\n                case string text:\n                    return text.EscapeSpecialCharacters(true);\n                case char character:\n                    return character.EscapeSpecialCharacter(true);\n                case DateTime time:\n                    return time.ToString(\"yyyy'-'MM'-'dd'T'HH':'mm':'ss.fffffffK\");\n                case Type type:\n                    return $\"typeof({GetTypeArgumentName(type)})\";\n            }\n\n            if (argumentType != null && argumentType.IsArray)\n                return GetArray((IEnumerable)argumentValue);\n\n            return argumentValue.ToString()!;\n        }\n\n        // it's not generic so I can't simply use .Skip and all other LINQ goodness\n        private static string GetArray(IEnumerable collection)\n        {\n            var buffer = new StringBuilder().Append('[');\n\n            int index = 0;\n            foreach (var item in collection)\n            {\n                if (index > 0)\n                    buffer.Append(\", \");\n\n                if (index > 4)\n                {\n                    buffer.Append(\"...\"); // [0, 1, 2, 3, 4, ...]\n                    break;\n                }\n\n                buffer.Append(GetArgument(item, item?.GetType()));\n\n                ++index;\n            }\n\n            buffer.Append(']');\n\n            return buffer.ToString();\n        }\n\n        private static string GetTypeArgumentName(Type type)\n        {\n            if (Aliases.TryGetValue(type, out var alias))\n                return alias;\n\n            if (type.IsNullable())\n                return $\"{GetTypeArgumentName(Nullable.GetUnderlyingType(type)!)}?\";\n\n            if (type.Namespace.IsNotBlank())\n                return $\"{type.Namespace}.{GetTypeName(type)}\";\n\n            return GetTypeName(type);\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Exporters/HtmlExporter.cs",
    "content": "﻿using BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Reports;\n\nnamespace BenchmarkDotNet.Exporters\n{\n    public class HtmlExporter : ExporterBase\n    {\n        private const string CssDefinition = @\"\n<style type=\"\"text/css\"\">\n\ttable { border-collapse: collapse; display: block; width: 100%; overflow: auto; }\n\ttd, th { padding: 6px 13px; border: 1px solid #ddd; text-align: right; }\n\ttr { background-color: #fff; border-top: 1px solid #ccc; }\n\ttr:nth-child(even) { background: #f8f8f8; }\n</style>\";\n\n        protected override string FileExtension => \"html\";\n\n        public static readonly IExporter Default = new HtmlExporter();\n\n        public override void ExportToLog(Summary summary, ILogger logger)\n        {\n            PrintAll(summary, new HtmlLoggerWrapper(logger));\n        }\n\n        private static void PrintAll(Summary summary, ILogger logger)\n        {\n            logger.WriteLine(\"<!DOCTYPE html>\");\n            logger.WriteLine(\"<html lang='en'>\");\n            logger.WriteLine(\"<head>\");\n            logger.WriteLine(\"<meta charset='utf-8' />\");\n            logger.WriteLine(\"<title>\" + summary.Title + \"</title>\");\n            logger.WriteLine(CssDefinition);\n            logger.WriteLine(\"</head>\");\n\n            logger.WriteLine(\"<body>\");\n            logger.Write(\"<pre><code>\");\n            logger.WriteLine();\n            foreach (string infoLine in summary.HostEnvironmentInfo.ToFormattedString())\n            {\n                logger.WriteLine(infoLine);\n            }\n            logger.WriteLine(summary.AllRuntimes);\n            logger.Write(\"</code></pre>\");\n            logger.WriteLine();\n\n            PrintTable(summary.Table, logger);\n\n            logger.WriteLine(\"</body>\");\n            logger.WriteLine(\"</html>\");\n        }\n\n        private static void PrintTable(SummaryTable table, ILogger logger)\n        {\n            if (table.FullContent.Length == 0)\n            {\n                logger.WriteLineError(\"<pre>There are no benchmarks found</pre>\");\n                return;\n            }\n\n            logger.Write(\"<pre><code>\");\n            table.PrintCommonColumns(logger);\n            logger.WriteLine(\"</code></pre>\");\n            logger.WriteLine();\n\n            logger.WriteLine(\"<table>\");\n\n            logger.Write(\"<thead>\");\n            logger.Write(\"<tr>\");\n            table.PrintLine(table.FullHeader, logger, \"<th>\", \"</th>\");\n            logger.WriteLine(\"</tr>\");\n            logger.Write(\"</thead>\");\n\n            logger.Write(\"<tbody>\");\n            foreach (var line in table.FullContent)\n            {\n                logger.Write(\"<tr>\");\n                PrintLine(table, line, logger, \"<td>\", \"</td>\");\n                logger.Write(\"</tr>\");\n            }\n            logger.Write(\"</tbody>\");\n\n            logger.WriteLine(\"</table>\");\n        }\n\n        private static void PrintLine(SummaryTable table, string[] line, ILogger logger, string leftDel, string rightDel)\n        {\n            for (int columnIndex = 0; columnIndex < table.ColumnCount; columnIndex++)\n            {\n                if (table.Columns[columnIndex].NeedToShow)\n                {\n                    logger.WriteStatistic(leftDel + line[columnIndex].HtmlEncode() + rightDel);\n                }\n            }\n\n            logger.WriteLine();\n        }\n\n        private class HtmlLoggerWrapper : ILogger\n        {\n            private readonly ILogger internalLogger;\n\n            public HtmlLoggerWrapper(ILogger logger) => internalLogger = logger;\n\n            public string Id => nameof(HtmlLoggerWrapper);\n            public int Priority => 0;\n\n            public void Write(LogKind logKind, string text) => internalLogger.Write(logKind, Escape(text));\n            public void WriteLine() => internalLogger.WriteLine();\n            public void WriteLine(LogKind logKind, string text) => internalLogger.WriteLine(logKind, Escape(text));\n            public void Flush() => internalLogger.Flush();\n\n            private static string Escape(string text)\n            {\n                return text.Replace(\"\\u03BC\", \"&mu;\");\n            }\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Exporters/IExporter.cs",
    "content": "﻿using System.Collections.Generic;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Reports;\n\nnamespace BenchmarkDotNet.Exporters\n{\n    public interface IExporter\n    {\n        string Name { get; }\n\n        void ExportToLog(Summary summary, ILogger logger);\n        IEnumerable<string> ExportToFiles(Summary summary, ILogger consoleLogger);\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Exporters/IExporterDependencies.cs",
    "content": "﻿using System.Collections.Generic;\n\nnamespace BenchmarkDotNet.Exporters\n{\n    /// <summary>\n    /// This is an internal interface, it allows Exporters to specify that\n    /// they depends on another Exporter (see RPlotExporter for example)\n    /// </summary>\n    internal interface IExporterDependencies\n    {\n        IEnumerable<IExporter> Dependencies { get; }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Exporters/InstructionPointerExporter.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Text;\nusing BenchmarkDotNet.Diagnosers;\nusing BenchmarkDotNet.Disassemblers;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Helpers;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Running;\n\nnamespace BenchmarkDotNet.Exporters\n{\n    internal class InstructionPointerExporter : IExporter\n    {\n        internal const string CssStyle = @\"\n<style type=\"\"text/css\"\">\n    pre { margin: 0px; }\n    table { border-collapse:collapse; }\n    td.perMethod { border-top: 1px black solid; }\n    tr.evenMap td { background-color: #F5F5F5; }  \n</style>\";\n\n        private readonly IHardwareCountersDiagnoser hardwareCountersDiagnoser;\n        private readonly DisassemblyDiagnoser disassemblyDiagnoser;\n\n        internal InstructionPointerExporter(IHardwareCountersDiagnoser hardwareCountersDiagnoser, DisassemblyDiagnoser disassemblyDiagnoser)\n        {\n            this.hardwareCountersDiagnoser = hardwareCountersDiagnoser;\n            this.disassemblyDiagnoser = disassemblyDiagnoser;\n        }\n\n        public string Name => nameof(InstructionPointerExporter);\n\n        public void ExportToLog(Summary summary, ILogger logger) { }\n\n        public IEnumerable<string> ExportToFiles(Summary summary, ILogger consoleLogger)\n        {\n            var hardwareCounters = hardwareCountersDiagnoser.Results;\n            var disassembly = disassemblyDiagnoser.Results;\n\n            foreach (var disassemblyResult in disassembly)\n            {\n                if (hardwareCounters.TryGetValue(disassemblyResult.Key, out var pmcStats))\n                    yield return Export(summary, disassemblyResult.Key, disassemblyResult.Value, pmcStats);\n            }\n        }\n\n        private string Export(Summary summary, BenchmarkCase benchmarkCase, DisassemblyResult disassemblyResult, PmcStats pmcStats)\n        {\n            string filePath = Path.Combine(summary.ResultsDirectoryPath,\n                                            $\"{FolderNameHelper.ToFolderName(benchmarkCase.Descriptor.Type)}.\" +\n                                            $\"{benchmarkCase.Descriptor.WorkloadMethod.Name}.\" +\n                                            $\"{GetShortRuntimeInfo(summary[benchmarkCase]!.GetRuntimeInfo()!)}.counters.html\");\n\n            filePath.DeleteFileIfExists();\n\n            var totals = SumHardwareCountersStatsOfBenchmarkedCode(disassemblyResult, pmcStats);\n            var perMethod = SumHardwareCountersPerMethod(disassemblyResult, pmcStats);\n\n            using (var stream = new StreamWriter(filePath, append: false))\n            {\n                using (var streamLogger = new StreamLogger(stream))\n                {\n                    Export(streamLogger, benchmarkCase, totals, perMethod, pmcStats.Counters.Keys.ToArray());\n                }\n            }\n\n            return filePath;\n        }\n\n        /// <summary>\n        /// there might be some hardware counter events not belonging to the benchmarked code (for example CLR or BenchmarkDotNet's Engine)\n        /// to calculate the % per IP we need to know the total per benchmark, not per process\n        /// </summary>\n        private static Dictionary<HardwareCounter, (ulong withoutNoise, ulong total)> SumHardwareCountersStatsOfBenchmarkedCode(\n            DisassemblyResult disassemblyResult, PmcStats pmcStats)\n        {\n            IEnumerable<ulong> Range(Asm asm)\n            {\n                // most probably asm.StartAddress would be enough, but I don't want to miss any edge case\n                for (ulong instructionPointer = asm.InstructionPointer; instructionPointer < asm.InstructionPointer + (ulong)asm.InstructionLength; instructionPointer++)\n                    yield return instructionPointer;\n            }\n\n            var instructionPointers = new HashSet<ulong>(\n                disassemblyResult\n                    .Methods\n                    .SelectMany(method => method.Maps)\n                    .SelectMany(map => map.SourceCodes)\n                    .OfType<Asm>()\n                    .SelectMany(Range)\n                    .Distinct());\n\n            return pmcStats.Counters.ToDictionary(data => data.Key, data =>\n            {\n                ulong withoutNoise = 0, total = 0;\n\n                foreach (var ipToCount in data.Value.PerInstructionPointer)\n                {\n                    total += ipToCount.Value;\n\n                    if (instructionPointers.Contains(ipToCount.Key))\n                        withoutNoise += ipToCount.Value;\n                }\n\n                return (withoutNoise, total);\n            });\n        }\n\n        private static IReadOnlyList<MethodWithCounters> SumHardwareCountersPerMethod(DisassemblyResult disassemblyResult, PmcStats pmcStats)\n        {\n            var model = new List<MethodWithCounters>(disassemblyResult.Methods.Length);\n\n            foreach (var method in disassemblyResult.Methods.Where(method => method.Problem.IsBlank()))\n            {\n                var groups = new List<List<CodeWithCounters>>();\n\n                foreach (var map in method.Maps)\n                {\n                    var codeWithCounters = new List<CodeWithCounters>(map.SourceCodes.Length);\n\n                    foreach (var instruction in map.SourceCodes)\n                    {\n                        var totalsPerCounter = pmcStats.Counters.Keys.ToDictionary(key => key, _ => default(ulong));\n\n                        if (instruction is Asm asm)\n                        {\n                            foreach (var hardwareCounter in pmcStats.Counters)\n                            {\n                                // most probably asm.StartAddress would be enough, but I don't want to miss any edge case\n                                for (ulong instructionPointer = asm.InstructionPointer; instructionPointer < asm.InstructionPointer + (ulong)asm.InstructionLength; instructionPointer++)\n                                    if (hardwareCounter.Value.PerInstructionPointer.TryGetValue(instructionPointer, out ulong value))\n                                        totalsPerCounter[hardwareCounter.Key] = totalsPerCounter[hardwareCounter.Key] + value;\n                            }\n                        }\n\n                        codeWithCounters.Add(new CodeWithCounters\n                        {\n                            Code = instruction,\n                            SumPerCounter = totalsPerCounter\n                        });\n                    }\n\n                    groups.Add(codeWithCounters);\n                }\n\n                model.Add(new MethodWithCounters\n                {\n                    Method = method,\n                    Instructions = groups,\n                    SumPerCounter = pmcStats.Counters.Keys.ToDictionary(\n                        hardwareCounter => hardwareCounter,\n                        hardwareCounter =>\n                        {\n                            ulong sum = 0;\n\n                            foreach (var group in groups)\n                                foreach (var codeWithCounter in group)\n                                    sum += codeWithCounter.SumPerCounter[hardwareCounter];\n\n                            return sum;\n                        }\n                    )\n                });\n            }\n\n            return model;\n        }\n\n        private void Export(ILogger logger, BenchmarkCase benchmarkCase, Dictionary<HardwareCounter, (ulong withoutNoise, ulong total)> totals, IReadOnlyList<MethodWithCounters> model, HardwareCounter[] hardwareCounters)\n        {\n            int columnsCount = hardwareCounters.Length + 1;\n\n            logger.WriteLine(\"<!DOCTYPE html><html lang='en'><head><meta charset='utf-8' />\");\n            logger.WriteLine($\"<title>Combined Output of DisassemblyDiagnoser and HardwareCounters {benchmarkCase.DisplayInfo}</title>\");\n            logger.WriteLine(CssStyle);\n            logger.WriteLine(\"</head>\");\n\n            logger.WriteLine(\"<body>\");\n\n            logger.WriteLine(\"<!-- Generated with BenchmarkDotNet \");\n            foreach (var total in totals)\n            {\n                // this stats are mostly for me, the maintainer, who wants to know if removing noise makes any sense\n                logger.WriteLine($\"For {total.Key} we have {total.Value.total} in total, {total.Value.withoutNoise} without noise\");\n            }\n            logger.WriteLine(\"-->\");\n\n            logger.WriteLine(\"<table><thead><tr>\");\n\n            foreach (var hardwareCounter in hardwareCounters)\n                logger.WriteLine($\"<th>{hardwareCounter.ToShortName()}</th>\");\n\n            logger.WriteLine(\"<th></th></tr></thead>\");\n\n            logger.WriteLine(\"<tbody>\");\n            var disassemblyResult = disassemblyDiagnoser.Results[benchmarkCase];\n            var config = disassemblyDiagnoser.Config;\n            var formatterWithSymbols = config.GetFormatterWithSymbolSolver(disassemblyResult.AddressToNameMapping);\n            foreach (var method in model.Where(data => data.HasCounters))\n            {\n                logger.WriteLine($\"<tr><th colspan=\\\"{columnsCount}\\\">{method.Method.Name}</th></tr>\");\n\n                bool evenMap = true;\n                foreach (var map in method.Instructions)\n                {\n                    foreach (var instruction in map)\n                    {\n                        logger.WriteLine($\"<tr class=\\\"{(evenMap ? \"evenMap\" : \"oddMap\")}\\\">\");\n\n                        foreach (var hardwareCounter in hardwareCounters)\n                        {\n                            ulong totalWithoutNoise = totals[hardwareCounter].withoutNoise;\n                            ulong forRange = instruction.SumPerCounter[hardwareCounter];\n\n                            logger.Write(forRange != 0\n                                ? $\"<td title=\\\"{forRange} of {totalWithoutNoise}\\\">{(double) forRange / totalWithoutNoise:P}</td>\"\n                                : \"<td>-</td>\");\n                        }\n\n                        if (instruction.Code is Sharp sharp && sharp.FilePath.IsNotBlank())\n                            logger.Write($\"<td title=\\\"{sharp.FilePath} line {sharp.LineNumber}\\\">\");\n                        else\n                            logger.Write(\"<td>\");\n\n                        string formatted = CodeFormatter.Format(instruction.Code, formatterWithSymbols, config.PrintInstructionAddresses, disassemblyResult.PointerSize, disassemblyResult.AddressToNameMapping);\n                        logger.WriteLine($\"<pre><code>{formatted}</pre></code></td></tr>\");\n                    }\n\n                    evenMap = !evenMap;\n                }\n\n                logger.WriteLine(\"<tr>\");\n                foreach (var hardwareCounter in hardwareCounters)\n                {\n                    ulong totalWithoutNoise = totals[hardwareCounter].withoutNoise;\n                    ulong forMethod = method.SumPerCounter[hardwareCounter];\n\n                    logger.Write(forMethod != 0\n                        ? $\"<td class=\\\"perMethod\\\" title=\\\"{forMethod} of {totalWithoutNoise}\\\">{(double) forMethod / totalWithoutNoise:P}</td>\"\n                        : \"<td  class=\\\"perMethod\\\">-</td>\");\n                }\n                logger.WriteLine(\"<td></td></tr>\");\n                logger.WriteLine($\"<tr><td colspan=\\\"{columnsCount}\\\"></td></tr>\");\n            }\n\n            if (model.Any(data => !data.HasCounters))\n            {\n                logger.WriteLine($\"<tr><td colspan=\\\"{columnsCount}\\\">Method(s) without any hardware counters:</td></tr>\");\n\n                foreach (var method in model.Where(data => !data.HasCounters))\n                    logger.WriteLine($\"<tr><td colspan=\\\"{columnsCount}\\\">{method.Method.Name}</td></tr>\");\n            }\n\n            logger.WriteLine(\"</tbody></table></body></html>\");\n        }\n\n        // fullInfo is sth like \".NET Core 2.1.21 (CoreCLR 4.6.29130.01, CoreFX 4.6.29130.02), X64 RyuJIT\"\n        private static string GetShortRuntimeInfo(string fullInfo)\n        {\n            var builder = new StringBuilder();\n\n            for (int i = 0; i < fullInfo.IndexOf('(') - 1; i++)\n            {\n                if (fullInfo[i] != ' ')\n                {\n                    builder.Append(fullInfo[i]);\n                }\n                else\n                {\n                    builder.Append('_');\n                }\n            }\n\n            for (int i = fullInfo.LastIndexOf(',') + 1; i < fullInfo.Length; i++)\n            {\n                if (fullInfo[i] != ' ')\n                {\n                    builder.Append(fullInfo[i]);\n                }\n                else\n                {\n                    builder.Append('_');\n                }\n            }\n\n            return builder.ToString();\n        }\n\n        private class CodeWithCounters\n        {\n            internal required SourceCode Code { get; set; }\n            internal required IReadOnlyDictionary<HardwareCounter, ulong> SumPerCounter { get; set; }\n        }\n\n        private class MethodWithCounters\n        {\n            internal required DisassembledMethod Method { get; set; }\n            internal required IReadOnlyList<IReadOnlyList<CodeWithCounters>> Instructions { get; set; }\n            internal required IReadOnlyDictionary<HardwareCounter, ulong> SumPerCounter { get; set; }\n\n            internal bool HasCounters => SumPerCounter.Values.Any(value => value != default);\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Exporters/Json/JsonExporter.cs",
    "content": "﻿namespace BenchmarkDotNet.Exporters.Json\n{\n    public class JsonExporter : JsonExporterBase\n    {\n        public static readonly IExporter Brief = new JsonExporter(\"-brief\", indentJson: true, excludeMeasurements: true);\n        public static readonly IExporter Full = new JsonExporter(\"-full\", indentJson: true, excludeMeasurements: false);\n        public static readonly IExporter BriefCompressed = new JsonExporter(\"-brief-compressed\", indentJson: false, excludeMeasurements: true);\n        public static readonly IExporter FullCompressed = new JsonExporter(\"-full-compressed\", indentJson: false, excludeMeasurements: false);\n\n        public static readonly IExporter Default = FullCompressed;\n\n        protected override string FileNameSuffix { get; } = string.Empty;\n\n        public JsonExporter(string fileNameSuffix = \"\", bool indentJson = false, bool excludeMeasurements = false) : base(indentJson, excludeMeasurements)\n        {\n            FileNameSuffix = fileNameSuffix;\n        }\n\n        public static IExporter Custom(string fileNameSuffix = \"\", bool indentJson = false, bool excludeMeasurements = false) =>\n            new JsonExporter(fileNameSuffix, indentJson, excludeMeasurements);\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Exporters/Json/JsonExporterBase.cs",
    "content": "﻿using BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Serialization;\nusing Perfolizer.Helpers;\nusing Perfolizer.Horology;\nusing System.Collections.Generic;\nusing System.Linq;\n\nnamespace BenchmarkDotNet.Exporters.Json\n{\n    public abstract class JsonExporterBase : ExporterBase\n    {\n        protected override string FileExtension => \"json\";\n\n        private bool IndentJson { get; }\n        private bool ExcludeMeasurements { get; }\n\n        protected JsonExporterBase(bool indentJson = false, bool excludeMeasurements = false)\n        {\n            IndentJson = indentJson;\n            ExcludeMeasurements = excludeMeasurements;\n        }\n\n        public override void ExportToLog(Summary summary, ILogger logger)\n        {\n            var dataToSerialize = GetDataToSerialize(summary);\n            var json = BdnSimpleJsonSerializer.Serialize(dataToSerialize, IndentJson);\n            logger.WriteLine(json);\n        }\n\n        protected virtual IReadOnlyDictionary<string, object> GetDataToSerialize(Summary summary)\n        {\n            // If we just ask SimpleJson to serialize the entire \"summary\" object it throws several errors.\n            // So we are more specific in what we serialize (plus some fields/properties aren't relevant)\n            return new Dictionary<string, object>\n            {\n                { \"Title\", summary.Title },\n                { \"HostEnvironmentInfo\", GetDataToSerialize(summary.HostEnvironmentInfo) },\n                { \"Benchmarks\", summary.Reports.Select(GetDataToSerialize) }\n            };\n        }\n\n        protected virtual IReadOnlyDictionary<string, object?> GetDataToSerialize(HostEnvironmentInfo environmentInfo)\n        {\n            // We construct HostEnvironmentInfo manually, so that we can have the HardwareTimerKind enum as text, rather than an integer\n            // SimpleJson serializer doesn't seem to have an enum String/Value option (to-be-fair, it is meant to be \"Simple\")\n            return new Dictionary<string, object?>\n            {\n                { nameof(HostEnvironmentInfo.BenchmarkDotNetCaption), HostEnvironmentInfo.BenchmarkDotNetCaption },\n                { nameof(environmentInfo.BenchmarkDotNetVersion), environmentInfo.BenchmarkDotNetVersion },\n                { \"OsVersion\", environmentInfo.Os.Value.ToBrandString() },\n                { \"ProcessorName\", environmentInfo.Cpu.Value.ToShortBrandName() },\n                { \"PhysicalProcessorCount\", environmentInfo.Cpu.Value?.PhysicalProcessorCount },\n                { \"PhysicalCoreCount\", environmentInfo.Cpu.Value?.PhysicalCoreCount },\n                { \"LogicalCoreCount\", environmentInfo.Cpu.Value?.LogicalCoreCount },\n                { nameof(environmentInfo.RuntimeVersion), environmentInfo.RuntimeVersion },\n                { nameof(environmentInfo.Architecture), environmentInfo.Architecture },\n                { nameof(environmentInfo.HasAttachedDebugger), environmentInfo.HasAttachedDebugger },\n                { nameof(environmentInfo.HasRyuJit), environmentInfo.HasRyuJit },\n                { nameof(environmentInfo.Configuration), environmentInfo.Configuration },\n                { \"DotNetCliVersion\", environmentInfo.DotNetSdkVersion.Value },\n                { nameof(environmentInfo.ChronometerFrequency), environmentInfo.ChronometerFrequency },\n                { nameof(HardwareTimerKind), environmentInfo.HardwareTimerKind.ToString() },\n            };\n        }\n\n        protected virtual IReadOnlyDictionary<string, object?> GetDataToSerialize(BenchmarkReport report)\n        {\n            var benchmark = new Dictionary<string, object?>\n            {\n                // We don't need Benchmark.ShortInfo, that info is available via Benchmark.Parameters below\n                { \"DisplayInfo\", report.BenchmarkCase.DisplayInfo },\n                { \"Namespace\", report.BenchmarkCase.Descriptor.Type.Namespace },\n                { \"Type\", FullNameProvider.GetTypeName(report.BenchmarkCase.Descriptor.Type) },\n                { \"Method\", report.BenchmarkCase.Descriptor.WorkloadMethod.Name },\n                { \"MethodTitle\", report.BenchmarkCase.Descriptor.WorkloadMethodDisplayInfo },\n                { \"Parameters\", report.BenchmarkCase.Parameters.PrintInfo },\n                {\n                    \"FullName\", FullNameProvider.GetBenchmarkName(report.BenchmarkCase)\n                }, // do NOT remove this property, it is used for xunit-performance migration\n                // Hardware Intrinsics can be disabled using env vars, that is why they might be different per benchmark and are not exported as part of HostEnvironmentInfo\n                { \"HardwareIntrinsics\", report.GetHardwareIntrinsicsInfo() ?? \"\" },\n                // { \"Properties\", r.Benchmark.Job.ToSet().ToDictionary(p => p.Name, p => p.Value) }, // TODO\n                { \"Statistics\", report.ResultStatistics }\n            };\n\n            // We show MemoryDiagnoser's results only if it is being used\n            if (report.BenchmarkCase.Config.HasMemoryDiagnoser())\n            {\n                benchmark.Add(\"Memory\", new\n                {\n                    report.GcStats.Gen0Collections,\n                    report.GcStats.Gen1Collections,\n                    report.GcStats.Gen2Collections,\n                    report.GcStats.TotalOperations,\n                    BytesAllocatedPerOperation = report.GcStats.GetBytesAllocatedPerOperation(report.BenchmarkCase)\n                });\n            }\n\n            if (ExcludeMeasurements == false)\n            {\n                // We construct Measurements manually, so that we can have the IterationMode enum as text, rather than an integer\n                benchmark.Add(\"Measurements\",\n                    report.AllMeasurements.Select(m => new\n                    {\n                        IterationMode = m.IterationMode.ToString(),\n                        IterationStage = m.IterationStage.ToString(),\n                        m.LaunchIndex,\n                        m.IterationIndex,\n                        m.Operations,\n                        m.Nanoseconds\n                    }));\n\n                if (report.Metrics.Any())\n                {\n                    benchmark.Add(\"Metrics\", report.Metrics.Values);\n                }\n            }\n\n            return benchmark;\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Exporters/MarkdownExporter.cs",
    "content": "﻿using System.Linq;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Reports;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Exporters\n{\n    public class MarkdownExporter : ExporterBase\n    {\n        public enum MarkdownHighlightStrategy\n        {\n            // Don't highlight\n            None,\n\n            // Bold highlighting\n            Bold,\n\n            // Mark end of the line with special symbol (for tests)\n            Marker\n        }\n\n        protected override string FileExtension => \"md\";\n        protected override string FileNameSuffix => $\"-{Dialect.ToLower()}\";\n\n        protected string Dialect { get; set; } = default!;\n\n        public static readonly IExporter Default = new MarkdownExporter\n        {\n            Dialect = nameof(Default),\n            StartOfGroupHighlightStrategy = MarkdownHighlightStrategy.Bold\n        };\n\n        public static readonly IExporter Console = new MarkdownExporter\n        {\n            Dialect = nameof(Console),\n            StartOfGroupHighlightStrategy = MarkdownHighlightStrategy.None,\n            ColumnsStartWithSeparator = true // we want to be able to copy-paste the console output to GH #1062\n        };\n\n        public static readonly IExporter StackOverflow = new MarkdownExporter\n        {\n            Dialect = nameof(StackOverflow),\n            Prefix = \"    \",\n            StartOfGroupHighlightStrategy = MarkdownHighlightStrategy.Bold\n        };\n\n        public static readonly IExporter GitHub = new MarkdownExporter\n        {\n            Dialect = nameof(GitHub),\n            UseCodeBlocks = true,\n            CodeBlockStart = \"```\",\n            StartOfGroupHighlightStrategy = MarkdownHighlightStrategy.Bold,\n            ColumnsStartWithSeparator = true,\n            EscapeHtml = true\n        };\n\n        public static readonly IExporter Atlassian = new MarkdownExporter\n        {\n            Dialect = nameof(Atlassian),\n            StartOfGroupHighlightStrategy = MarkdownHighlightStrategy.Bold,\n            TableHeaderSeparator = \" ||\",\n            UseHeaderSeparatingRow = false,\n            ColumnsStartWithSeparator = true,\n            UseCodeBlocks = true,\n            CodeBlockStart = \"{noformat}\",\n            CodeBlockEnd = \"{noformat}\",\n            BoldMarkupFormat = \"*{0}*\"\n        };\n\n        // Only for unit tests\n        internal static readonly IExporter Mock = new MarkdownExporter\n        {\n            Dialect = nameof(Mock),\n            StartOfGroupHighlightStrategy = MarkdownHighlightStrategy.Marker\n        };\n\n        [PublicAPI] protected string Prefix = string.Empty;\n        [PublicAPI] protected bool UseCodeBlocks;\n        [PublicAPI] protected string CodeBlockStart = \"```\";\n        [PublicAPI] protected string CodeBlockEnd = \"```\";\n        [PublicAPI] protected MarkdownHighlightStrategy StartOfGroupHighlightStrategy = MarkdownHighlightStrategy.None;\n        [PublicAPI] protected string TableHeaderSeparator = \" | \";\n        [PublicAPI] protected string TableColumnSeparator = \" | \";\n        [PublicAPI] protected bool UseHeaderSeparatingRow = true;\n        [PublicAPI] protected bool ColumnsStartWithSeparator;\n        [PublicAPI] protected string BoldMarkupFormat = \"**{0}**\";\n        [PublicAPI] protected bool EscapeHtml;\n\n        protected MarkdownExporter() { }\n\n        public override void ExportToLog(Summary summary, ILogger logger)\n        {\n            if (UseCodeBlocks)\n            {\n                logger.WriteLine(CodeBlockStart);\n            }\n\n            logger = GetRightLogger(logger);\n            logger.WriteLine();\n            foreach (string infoLine in summary.HostEnvironmentInfo.ToFormattedString())\n            {\n                logger.WriteLineInfo(infoLine);\n            }\n\n            logger.WriteLineInfo(summary.AllRuntimes);\n            logger.WriteLine();\n\n            PrintTable(summary.Table, logger);\n\n            // TODO: move this logic to an analyzer\n            var benchmarksWithTroubles = summary.Reports.Where(r => !r.GetResultRuns().Any()).Select(r => r.BenchmarkCase).ToList();\n            if (benchmarksWithTroubles.Count > 0)\n            {\n                logger.WriteLine();\n                logger.WriteLineError(\"Benchmarks with issues:\");\n                foreach (var benchmarkWithTroubles in benchmarksWithTroubles)\n                {\n                    logger.WriteLineError(\"  \" + benchmarkWithTroubles.DisplayInfo);\n                }\n            }\n        }\n\n        private ILogger GetRightLogger(ILogger logger)\n        {\n            if (string.IsNullOrEmpty(Prefix)) // most common scenario!! we don't need expensive LoggerWithPrefix\n            {\n                return logger;\n            }\n\n            return new LoggerWithPrefix(logger, Prefix);\n        }\n\n        private void PrintTable(SummaryTable table, ILogger logger)\n        {\n            if (table.FullContent.Length == 0)\n            {\n                logger.WriteLineError(\"There are no benchmarks found \");\n                logger.WriteLine();\n                return;\n            }\n\n            table.PrintCommonColumns(logger);\n\n            if (table.Columns.All(c => !c.NeedToShow))\n            {\n                logger.WriteLine();\n                logger.WriteLine(\"There are no columns to show \");\n                return;\n            }\n\n            logger.WriteLine();\n\n            if (UseCodeBlocks)\n            {\n                logger.Write(CodeBlockEnd);\n                logger.WriteLine();\n            }\n\n            logger.WriteStatistic(ColumnsStartWithSeparator ? TableHeaderSeparator.TrimStart() : \" \");\n\n            table.PrintLine(table.FullHeader, logger, string.Empty, TableHeaderSeparator);\n            if (UseHeaderSeparatingRow)\n            {\n                logger.WriteStatistic(ColumnsStartWithSeparator ? TableHeaderSeparator.TrimStart().TrimEnd() + \"-\" : \"-\");\n\n                logger.WriteLineStatistic(string.Join(\"\",\n                    table.Columns.Where(c => c.NeedToShow).Select((column, index) =>\n                        new string('-', column.Width - 1) + GetHeaderSeparatorIndicator(column.OriginalColumn.IsNumeric) +\n                        GetHeaderSeparatorColumnDivider(index, table.Columns.Where(c => c.NeedToShow).Count()))));\n            }\n\n            int rowCounter = 0;\n            bool highlightRow = false;\n            var separatorLine = Enumerable.Range(0, table.ColumnCount).Select(_ => \"\").ToArray();\n            foreach (var line in table.FullContent)\n            {\n                if (rowCounter > 0 && table.FullContentStartOfLogicalGroup[rowCounter] && table.SeparateLogicalGroups)\n                {\n                    // Print logical separator\n                    logger.WriteStatistic(ColumnsStartWithSeparator ? TableColumnSeparator.TrimStart() : \" \");\n\n                    table.PrintLine(separatorLine, logger, string.Empty, TableColumnSeparator, highlightRow, false, StartOfGroupHighlightStrategy,\n                        BoldMarkupFormat, false);\n                }\n\n                // Each time we hit the start of a new group, alternative the color (in the console) or display bold in Markdown\n                if (table.FullContentStartOfHighlightGroup[rowCounter])\n                {\n                    highlightRow = !highlightRow;\n                }\n\n\n                logger.WriteStatistic(ColumnsStartWithSeparator ? TableColumnSeparator.TrimStart() : \" \");\n\n                table.PrintLine(line, logger, string.Empty, TableColumnSeparator, highlightRow, table.FullContentStartOfHighlightGroup[rowCounter],\n                    StartOfGroupHighlightStrategy, BoldMarkupFormat, EscapeHtml);\n                rowCounter++;\n            }\n        }\n\n        private static string GetHeaderSeparatorIndicator(bool isNumeric)\n        {\n            return isNumeric ? \":\" : \" \";\n        }\n\n        private static string GetHeaderSeparatorColumnDivider(int columnIndex, int columnCount)\n        {\n            var isLastColumn = columnIndex != columnCount - 1;\n            return isLastColumn ? \"|-\" : \"|\";\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Exporters/OpenMetrics/OpenMetricsExporter.cs",
    "content": "using System.Collections.Generic;\nusing System.Collections.Immutable;\nusing System.Linq;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Parameters;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Running;\nusing System;\nusing System.Text;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Mathematics;\nusing System.Globalization;\n\nnamespace BenchmarkDotNet.Exporters.OpenMetrics;\n\npublic class OpenMetricsExporter : ExporterBase\n{\n    private const string MetricPrefix = \"benchmark_\";\n    protected override string FileExtension => \"metrics\";\n    protected override string FileCaption => \"openmetrics\";\n\n    public static readonly IExporter Default = new OpenMetricsExporter();\n\n    public override void ExportToLog(Summary summary, ILogger logger)\n    {\n        var metricsSet = new HashSet<OpenMetric>();\n\n        foreach (var report in summary.Reports)\n        {\n            var benchmark = report.BenchmarkCase;\n            var gcStats = report.GcStats;\n            var descriptor = benchmark.Descriptor;\n            var parameters = benchmark.Parameters;\n\n            var stats = report.ResultStatistics;\n            var metrics = report.Metrics;\n            if (stats == null)\n                continue;\n\n            AddCommonMetrics(metricsSet, descriptor, parameters, stats, gcStats);\n            AddAdditionalMetrics(metricsSet, metrics, descriptor, parameters);\n        }\n\n        WriteMetricsToLogger(logger, metricsSet);\n    }\n\n    private static void AddCommonMetrics(HashSet<OpenMetric> metricsSet, Descriptor descriptor, ParameterInstances parameters, Statistics stats, GcStats gcStats)\n    {\n        metricsSet.AddRange([\n            // Mean\n            OpenMetric.FromStatistics(\n                $\"{MetricPrefix}execution_time_nanoseconds\",\n                \"Mean execution time in nanoseconds.\",\n                \"gauge\",\n                \"nanoseconds\",\n                descriptor,\n                parameters,\n                stats.Mean),\n            // Error\n            OpenMetric.FromStatistics(\n                $\"{MetricPrefix}error_nanoseconds\",\n                \"Standard error of the mean execution time in nanoseconds.\",\n                \"gauge\",\n                \"nanoseconds\",\n                descriptor,\n                parameters,\n                stats.StandardError),\n            // Standard Deviation\n            OpenMetric.FromStatistics(\n                $\"{MetricPrefix}stddev_nanoseconds\",\n                \"Standard deviation of execution time in nanoseconds.\",\n                \"gauge\",\n                \"nanoseconds\",\n                descriptor,\n                parameters,\n                stats.StandardDeviation),\n            // GC Stats Gen0 - these are counters, not gauges\n            OpenMetric.FromStatistics(\n                $\"{MetricPrefix}gc_gen0_collections_total\",\n                \"Total number of Gen 0 garbage collections during the benchmark execution.\",\n                \"counter\",\n                \"\",\n                descriptor,\n                parameters,\n                gcStats.Gen0Collections),\n            // GC Stats Gen1\n            OpenMetric.FromStatistics(\n                $\"{MetricPrefix}gc_gen1_collections_total\",\n                \"Total number of Gen 1 garbage collections during the benchmark execution.\",\n                \"counter\",\n                \"\",\n                descriptor,\n                parameters,\n                gcStats.Gen1Collections),\n            // GC Stats Gen2\n            OpenMetric.FromStatistics(\n                $\"{MetricPrefix}gc_gen2_collections_total\",\n                \"Total number of Gen 2 garbage collections during the benchmark execution.\",\n                \"counter\",\n                \"\",\n                descriptor,\n                parameters,\n                gcStats.Gen2Collections),\n            // Total GC Operations\n            OpenMetric.FromStatistics(\n                $\"{MetricPrefix}gc_total_operations_total\",\n                \"Total number of garbage collection operations during the benchmark execution.\",\n                \"counter\",\n                \"\",\n                descriptor,\n                parameters,\n                gcStats.TotalOperations),\n            // P90 - in nanoseconds\n            OpenMetric.FromStatistics(\n                $\"{MetricPrefix}p90_nanoseconds\",\n                \"90th percentile execution time in nanoseconds.\",\n                \"gauge\",\n                \"nanoseconds\",\n                descriptor,\n                parameters,\n                stats.Percentiles.P90),\n            // P95 - in nanoseconds\n            OpenMetric.FromStatistics(\n                $\"{MetricPrefix}p95_nanoseconds\",\n                \"95th percentile execution time in nanoseconds.\",\n                \"gauge\",\n                \"nanoseconds\",\n                descriptor,\n                parameters,\n                stats.Percentiles.P95)\n        ]);\n    }\n\n    private static void AddAdditionalMetrics(HashSet<OpenMetric> metricsSet, IReadOnlyDictionary<string, Metric> metrics, Descriptor descriptor, ParameterInstances parameters)\n    {\n        var reservedMetricNames = new HashSet<string>\n        {\n            $\"{MetricPrefix}execution_time_nanoseconds\",\n            $\"{MetricPrefix}error_nanoseconds\",\n            $\"{MetricPrefix}stddev_nanoseconds\",\n            $\"{MetricPrefix}gc_gen0_collections_total\",\n            $\"{MetricPrefix}gc_gen1_collections_total\",\n            $\"{MetricPrefix}gc_gen2_collections_total\",\n            $\"{MetricPrefix}gc_total_operations_total\",\n            $\"{MetricPrefix}p90_nanoseconds\",\n            $\"{MetricPrefix}p95_nanoseconds\"\n        };\n\n        foreach (var metric in metrics)\n        {\n            string metricName = SanitizeMetricName(metric.Key);\n            string fullMetricName = $\"{MetricPrefix}{metricName}\";\n\n            if (reservedMetricNames.Contains(fullMetricName))\n                continue;\n\n            metricsSet.Add(OpenMetric.FromMetric(\n                fullMetricName,\n                metric,\n                \"gauge\", // Assuming all additional metrics are of type \"gauge\"\n                descriptor,\n                parameters));\n        }\n    }\n\n    private static void WriteMetricsToLogger(ILogger logger, HashSet<OpenMetric> metricsSet)\n    {\n        var emittedHelpType = new HashSet<string>();\n\n        foreach (var metric in metricsSet.OrderBy(m => m.Name))\n        {\n            if (!emittedHelpType.Contains(metric.Name))\n            {\n                logger.WriteLine($\"# HELP {metric.Name} {metric.Help}\");\n                logger.WriteLine($\"# TYPE {metric.Name} {metric.Type}\");\n                if (metric.Unit.IsNotBlank())\n                {\n                    logger.WriteLine($\"# UNIT {metric.Name} {metric.Unit}\");\n                }\n                emittedHelpType.Add(metric.Name);\n            }\n\n            logger.WriteLine(metric.ToString());\n        }\n\n        logger.WriteLine(\"# EOF\");\n    }\n\n    private static string SanitizeMetricName(string name)\n    {\n        var builder = new StringBuilder();\n        bool lastWasUnderscore = false;\n\n        foreach (char c in name.ToLowerInvariant())\n        {\n            if (char.IsLetterOrDigit(c) || c == '_')\n            {\n                builder.Append(c);\n                lastWasUnderscore = false;\n            }\n            else if (!lastWasUnderscore)\n            {\n                builder.Append('_');\n                lastWasUnderscore = true;\n            }\n        }\n\n        string? result = builder.ToString().Trim('_'); // <-- Trim here\n\n        if (result.Length > 0 && char.IsDigit(result[0]))\n            result = \"_\" + result;\n\n        return result;\n    }\n\n    private class OpenMetric : IEquatable<OpenMetric>\n    {\n        internal string Name { get; }\n        internal string Help { get; }\n        internal string Type { get; }\n        internal string Unit { get; }\n        private readonly ImmutableSortedDictionary<string, string> labels;\n        private readonly double value;\n\n        private OpenMetric(string name, string help, string type, string unit, ImmutableSortedDictionary<string, string> labels, double value)\n        {\n            if (string.IsNullOrWhiteSpace(name)) throw new ArgumentException(\"Metric name cannot be null or empty.\");\n            if (string.IsNullOrWhiteSpace(type)) throw new ArgumentException(\"Metric type cannot be null or empty.\");\n\n            Name = name;\n            Help = help;\n            Type = type;\n            Unit = unit ?? \"\";\n            this.labels = labels ?? throw new ArgumentNullException(nameof(labels));\n            this.value = value;\n        }\n\n        public static OpenMetric FromStatistics(string name, string help, string type, string unit, Descriptor descriptor, ParameterInstances parameters, double value)\n        {\n            var labels = BuildLabelDict(descriptor, parameters);\n            return new OpenMetric(name, help, type, unit, labels, value);\n        }\n\n        public static OpenMetric FromMetric(string fullMetricName, KeyValuePair<string, Metric> metric, string type, Descriptor descriptor, ParameterInstances parameters)\n        {\n            string help = $\"Additional metric {metric.Key}\";\n            var labels = BuildLabelDict(descriptor, parameters);\n            return new OpenMetric(fullMetricName, help, type, \"\", labels, metric.Value.Value);\n        }\n\n        private static readonly Dictionary<string, string> NormalizedLabelKeyCache = [];\n        private static string NormalizeLabelKey(string key)\n        {\n            string normalized = new(key\n                .ToLowerInvariant()\n                .Select(c => char.IsLetterOrDigit(c) ? c : '_')\n                .ToArray());\n            return normalized;\n        }\n\n        private static ImmutableSortedDictionary<string, string> BuildLabelDict(Descriptor descriptor, ParameterInstances parameters)\n        {\n            var dict = new SortedDictionary<string, string>\n            {\n                [\"method\"] = descriptor.WorkloadMethod.Name,\n                [\"type\"] = descriptor.TypeInfo\n            };\n            foreach (var param in parameters.Items)\n            {\n                string key = NormalizeLabelKey(param.Name);\n                string value = EscapeLabelValue(param.Value?.ToString() ?? \"\");\n                dict[key] = value;\n            }\n            return dict.ToImmutableSortedDictionary();\n        }\n\n        private static string EscapeLabelValue(string value)\n        {\n            return value.Replace(\"\\\\\", @\"\\\\\")\n                        .Replace(\"\\\"\", \"\\\\\\\"\")\n                        .Replace(\"\\n\", \"\\\\n\")\n                        .Replace(\"\\r\", \"\\\\r\")\n                        .Replace(\"\\t\", \"\\\\t\");\n        }\n\n        public override bool Equals(object? obj) => Equals(obj as OpenMetric);\n\n        public bool Equals(OpenMetric? other)\n        {\n            if (other is null)\n                return false;\n\n            return Name == other.Name\n                && value.Equals(other.value)\n                && labels.Count == other.labels.Count\n                && labels.All(kv => other.labels.TryGetValue(kv.Key, out string? otherValue) && kv.Value == otherValue);\n        }\n\n        public override int GetHashCode()\n        {\n            var hash = new HashCode();\n            hash.Add(Name);\n            hash.Add(value);\n\n            foreach (var kv in labels)\n            {\n                hash.Add(kv.Key);\n                hash.Add(kv.Value);\n            }\n\n            return hash.ToHashCode();\n        }\n\n        public override string ToString()\n        {\n            string labelStr = labels.Count > 0\n                ? $\"{{{string.Join(\", \", labels.Select(kvp => $\"{kvp.Key}=\\\"{kvp.Value}\\\"\"))}}}\"\n                : string.Empty;\n            return $\"{Name}{labelStr} {value.ToString(CultureInfo.InvariantCulture)}\";\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Exporters/PerfonarJsonExporter.cs",
    "content": "using BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Reports;\nusing Perfolizer.Json;\n\nnamespace BenchmarkDotNet.Exporters;\n\n/// <summary>\n/// IMPORTANT: Not fully implemented yet\n/// </summary>\ninternal class PerfonarJsonExporter(LightJsonSettings? jsonSettings = null) : ExporterBase\n{\n    protected override string FileExtension => \"perfonar.json\";\n\n    public override void ExportToLog(Summary summary, ILogger logger)\n    {\n        logger.WriteLine(LightJsonSerializer.Serialize(summary.ToPerfonar(), jsonSettings));\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Exporters/PerfonarMdExporter.cs",
    "content": "using BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Reports;\n\nusing Perfolizer.Perfonar.Tables;\n\nnamespace BenchmarkDotNet.Exporters;\n\n/// <summary>\n/// IMPORTANT: Not fully implemented yet\n/// </summary>\ninternal class PerfonarMdExporter : ExporterBase\n{\n    protected override string FileExtension => \"perfonar.md\";\n\n    public override void ExportToLog(Summary summary, ILogger logger)\n    {\n        var table = new PerfonarTable(summary.ToPerfonar(), summary.GetDefaultTableConfig());\n        string markdown = table.ToMarkdown(new PerfonarTableStyle());\n        logger.WriteLine(markdown);\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Exporters/PlainExporter.cs",
    "content": "﻿using System.Linq;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Reports;\n\nnamespace BenchmarkDotNet.Exporters\n{\n    public class PlainExporter : ExporterBase\n    {\n        public static readonly IExporter Default = new PlainExporter();\n\n        private PlainExporter()\n        {\n        }\n\n        public override void ExportToLog(Summary summary, ILogger logger)\n        {\n            var cultureInfo = summary.GetCultureInfo();\n            foreach (var report in summary.Reports)\n            {\n                var measurements = report.AllMeasurements;\n                var modeStages = measurements.Select(it => (it.IterationMode, it.IterationStage)).Distinct();\n                logger.WriteLineHeader($\"*** {report.BenchmarkCase.DisplayInfo} ***\");\n                logger.WriteLineHeader(\"* Raw *\");\n                foreach (var measurement in measurements)\n                    logger.WriteLineResult(measurement.ToString());\n                foreach (var (mode, stage) in modeStages)\n                {\n                    logger.WriteLine();\n                    logger.WriteLineHeader($\"* Statistics for {mode}{stage}\");\n                    var statistics = measurements.Where(it => it.Is(mode, stage)).GetStatistics();\n                    var formatter = statistics.CreateNanosecondFormatter(cultureInfo);\n                    logger.WriteLineStatistic(statistics.ToString(cultureInfo, formatter, calcHistogram: true));\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Exporters/RPlotExporter.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.IO;\nusing BenchmarkDotNet.Detectors;\nusing BenchmarkDotNet.Exporters.Csv;\nusing BenchmarkDotNet.Helpers;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Portability;\nusing BenchmarkDotNet.Properties;\nusing BenchmarkDotNet.Reports;\n\nnamespace BenchmarkDotNet.Exporters\n{\n    public class RPlotExporter : IExporter, IExporterDependencies\n    {\n        public static readonly IExporter Default = new RPlotExporter();\n        public string Name => nameof(RPlotExporter);\n\n        private const string ImageExtension = \".png\";\n        private static readonly object BuildScriptLock = new object();\n\n        public IEnumerable<IExporter> Dependencies\n        {\n            // R Plots depends on having the full measurements available\n            get { yield return CsvMeasurementsExporter.Default; }\n        }\n\n        public IEnumerable<string> ExportToFiles(Summary summary, ILogger consoleLogger)\n        {\n            const string scriptFileName = \"BuildPlots.R\";\n            const string logFileName = \"BuildPlots.log\";\n            yield return Path.Combine(summary.ResultsDirectoryPath, scriptFileName);\n\n            string csvFullPath = Path.GetFullPath(CsvMeasurementsExporter.Default.GetArtifactFullName(summary));\n            string scriptFullPath = Path.GetFullPath(Path.Combine(summary.ResultsDirectoryPath, scriptFileName));\n            string logFullPath = Path.GetFullPath(Path.Combine(summary.ResultsDirectoryPath, logFileName));\n            \n            string script = ResourceHelper.\n                LoadTemplate(scriptFileName).\n                Replace(\"$BenchmarkDotNetVersion$\", BenchmarkDotNetInfo.Instance.BrandTitle).\n                Replace(\"$CsvSeparator$\", CsvMeasurementsExporter.Default.Separator);\n            lock (BuildScriptLock)\n                File.WriteAllText(scriptFullPath, script);\n\n            if (!TryFindRScript(consoleLogger, out var rscriptPath))\n            {\n                yield break;\n            }\n\n            var start = new ProcessStartInfo\n            {\n                UseShellExecute = false,\n                RedirectStandardOutput = true,\n                RedirectStandardError = true,\n                CreateNoWindow = true,\n                FileName = rscriptPath,\n                Arguments = $\"\\\"{scriptFullPath}\\\" \\\"{csvFullPath}\\\"\"\n            };\n            using (var process = new Process {StartInfo = start})\n            using (AsyncProcessOutputReader reader = new AsyncProcessOutputReader(process))\n            {\n                // When large R scripts are generated then ran, ReadToEnd()\n                // causes the stdout and stderr buffers to become full,\n                // which causes R to hang. To avoid this, use\n                // AsyncProcessOutputReader to cache the log contents\n                // then write to disk rather than Process.Standard*.ReadToEnd().\n                process.Start();\n                reader.BeginRead();\n                process.WaitForExit();\n                Debug.Assert(process.HasExited);\n                if (process.ExitCode != 0)\n                    throw new ApplicationException($\"Process {rscriptPath} has exited with code {process.ExitCode}\");\n\n                reader.StopRead();\n                File.WriteAllLines(logFullPath, reader.GetOutputLines());\n                File.AppendAllLines(logFullPath, reader.GetErrorLines());\n            }\n\n            yield return Path.Combine(summary.ResultsDirectoryPath, $\"*{ImageExtension}\");\n        }\n\n        public void ExportToLog(Summary summary, ILogger logger)\n        {\n            throw new NotSupportedException();\n        }\n\n        private static bool TryFindRScript(ILogger consoleLogger, out string? rscriptPath)\n        {\n            string rscriptExecutable = OsDetector.IsWindows() ? \"Rscript.exe\" : \"Rscript\";\n            rscriptPath = null;\n\n            string? rHome = Environment.GetEnvironmentVariable(\"R_HOME\");\n            if (rHome != null)\n            {\n                rscriptPath = Path.Combine(rHome, \"bin\", rscriptExecutable);\n                if (File.Exists(rscriptPath))\n                    return true;\n\n                consoleLogger.WriteLineError($\"{nameof(RPlotExporter)} requires R_HOME to point to the parent directory of the existing '{Path.DirectorySeparatorChar}bin{Path.DirectorySeparatorChar}{rscriptExecutable} (currently points to {rHome})\");\n                return false;\n            }\n\n            // No R_HOME, or R_HOME points to a wrong folder, try the path\n            rscriptPath = FindInPath(rscriptExecutable);\n            if (rscriptPath != null)\n                return true;\n\n            if (OsDetector.IsWindows())\n            {\n                string programFiles = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles);\n                string programFilesR = Path.Combine(programFiles, \"R\");\n                if (Directory.Exists(programFilesR))\n                {\n                    foreach (string rRootDirectory in Directory.EnumerateDirectories(programFilesR))\n                    {\n                        string rscriptPathCandidate = Path.Combine(rRootDirectory, \"bin\", rscriptExecutable);\n                        if (File.Exists(rscriptPathCandidate))\n                        {\n                            rscriptPath = rscriptPathCandidate;\n                            return true;\n                        }\n                    }\n                }\n            }\n\n            consoleLogger.WriteLineError($\"{nameof(RPlotExporter)} couldn't find {rscriptExecutable} in your PATH and no R_HOME environment variable is defined\");\n            return false;\n        }\n\n        private static string? FindInPath(string fileName)\n        {\n            string? path = Environment.GetEnvironmentVariable(\"PATH\");\n            if (path == null)\n                return null;\n\n            string[] dirs = path.Split(Path.PathSeparator);\n            foreach (string dir in dirs)\n            {\n                string trimmedDir = dir.Trim('\\'', '\"');\n                try\n                {\n                    string filePath = Path.Combine(trimmedDir, fileName);\n                    if (File.Exists(filePath))\n                        return filePath;\n                }\n                catch (Exception)\n                {\n                    // Never mind\n                }\n            }\n            return null;\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Exporters/Xml/IXmlSerializer.cs",
    "content": "﻿namespace BenchmarkDotNet.Exporters.Xml\n{\n    internal interface IXmlSerializer\n    {\n        void Serialize(IXmlWriter writer, object source);\n    }\n\n    internal interface IXmlWriter\n    {\n        void WriteStartDocument();\n        void WriteEndDocument();\n        void WriteStartElement(string localName);\n        void WriteEndElement();\n        void WriteElementString(string localName, string value);\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Exporters/Xml/SimpleXmlWriter.cs",
    "content": "﻿using System;\nusing System.IO;\nusing System.Xml;\n\nnamespace BenchmarkDotNet.Exporters.Xml\n{\n    internal class SimpleXmlWriter : IXmlWriter, IDisposable\n    {\n        private readonly XmlWriter writer;\n\n        public SimpleXmlWriter(TextWriter writer, bool indent)\n        {\n            this.writer = XmlWriter.Create(writer, new XmlWriterSettings { Indent = indent });\n        }\n\n        public void WriteElementString(string localName, string value)\n            => writer.WriteElementString(localName, value);\n\n        public void WriteEndDocument()\n            => writer.WriteEndDocument();\n\n        public void WriteEndElement()\n            => writer.WriteEndElement();\n\n        public void WriteStartDocument()\n            => writer.WriteStartDocument();\n\n        public void WriteStartElement(string localName)\n            => writer.WriteStartElement(localName);\n\n        public void Dispose() => writer.Dispose();\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Exporters/Xml/SummaryDto.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Linq;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Mathematics;\nusing BenchmarkDotNet.Reports;\nusing JetBrains.Annotations;\nusing Perfolizer.Helpers;\nusing Perfolizer.Horology;\n\n// ReSharper disable UnusedMember.Global\n\nnamespace BenchmarkDotNet.Exporters.Xml\n{\n    internal class SummaryDto\n    {\n        public string Title => summary.Title;\n\n        public HostEnvironmentInfoDto HostEnvironmentInfo =>\n            new HostEnvironmentInfoDto(summary.HostEnvironmentInfo);\n\n        [PublicAPI]\n        public IEnumerable<BenchmarkReportDto> Benchmarks { get; }\n\n        private readonly Summary summary;\n\n        public SummaryDto(Summary summary, bool excludeMeasurements = false)\n        {\n            this.summary = summary;\n            Benchmarks = summary.Reports.Select(\n                report => new BenchmarkReportDto(report, excludeMeasurements));\n        }\n    }\n\n    internal class HostEnvironmentInfoDto\n    {\n        public string BenchmarkDotNetCaption => HostEnvironmentInfo.BenchmarkDotNetCaption;\n        public string BenchmarkDotNetVersion => hei.BenchmarkDotNetVersion;\n        public string OsVersion => hei.Os.Value.ToBrandString();\n        public string ProcessorName => hei.Cpu.Value.ToShortBrandName();\n        public string PhysicalProcessorCount => hei.Cpu.Value?.PhysicalProcessorCount?.ToString() ?? \"\";\n        public string PhysicalCoreCount => hei.Cpu.Value?.PhysicalCoreCount?.ToString() ?? \"\";\n        public string LogicalCoreCount => hei.Cpu.Value?.LogicalCoreCount?.ToString() ?? \"\";\n        public string RuntimeVersion => hei.RuntimeVersion;\n        public string Architecture => hei.Architecture;\n        public bool HasAttachedDebugger => hei.HasAttachedDebugger;\n        public bool HasRyuJit => hei.HasRyuJit;\n        public string Configuration => hei.Configuration;\n        public string DotNetSdkVersion => hei.DotNetSdkVersion.Value;\n        public ChronometerDto ChronometerFrequency => new ChronometerDto(hei.ChronometerFrequency);\n        public string HardwareTimerKind => hei.HardwareTimerKind.ToString();\n\n        private readonly HostEnvironmentInfo hei;\n\n        public HostEnvironmentInfoDto(HostEnvironmentInfo hei) => this.hei = hei;\n    }\n\n    internal class ChronometerDto\n    {\n        public double Hertz => frequency.Hertz;\n\n        private readonly Frequency frequency;\n\n        public ChronometerDto(Frequency frequency) => this.frequency = frequency;\n    }\n\n    internal class BenchmarkReportDto\n    {\n        public string DisplayInfo => report.BenchmarkCase.DisplayInfo;\n        public string Namespace => report.BenchmarkCase.Descriptor.Type.Namespace ?? \"\";\n        public string Type => report.BenchmarkCase.Descriptor.Type.Name;\n        public string Method => report.BenchmarkCase.Descriptor.WorkloadMethod.Name;\n        public string MethodTitle => report.BenchmarkCase.Descriptor.WorkloadMethodDisplayInfo;\n        public string Parameters => report.BenchmarkCase.Parameters.PrintInfo;\n        public Statistics? Statistics => report.ResultStatistics;\n        public IEnumerable<Metric> Metrics => report.Metrics.Values;\n\n        public GcStats Memory => new GcStats()\n        {\n            Gen0Collections = report.GcStats.Gen0Collections,\n            Gen1Collections = report.GcStats.Gen1Collections,\n            Gen2Collections = report.GcStats.Gen2Collections,\n            TotalOperations = report.GcStats.TotalOperations,\n            BytesAllocatedPerOperation = report.GcStats.GetBytesAllocatedPerOperation(report.BenchmarkCase)\n        };\n\n        [PublicAPI] public IEnumerable<Measurement> Measurements { get; }\n\n        private readonly BenchmarkReport report;\n\n        public BenchmarkReportDto(BenchmarkReport report, bool excludeMeasurements = false)\n        {\n            this.report = report;\n            Measurements = excludeMeasurements ? [] : report.AllMeasurements;\n        }\n    }\n\n    /// <summary>\n    /// This type is used to ensure that the allocated bytes are persisted in the XML\n    /// report when serialized, as the original <see cref=\"Engines.GcStats\"/> type does\n    /// not contain a property for the value so the report would otherwise lack it.\n    /// See https://github.com/dotnet/BenchmarkDotNet/pull/1919 for more details.\n    /// </summary>\n    internal struct GcStats\n    {\n        public int Gen0Collections { get; set; }\n        public int Gen1Collections { get; set; }\n        public int Gen2Collections { get; set; }\n        public long TotalOperations { get; set; }\n        public long? BytesAllocatedPerOperation { get; set; }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Exporters/Xml/XmlExporter.cs",
    "content": "﻿using JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Exporters.Xml\n{\n    public class XmlExporter : XmlExporterBase\n    {\n        public static readonly IExporter Brief = new XmlExporter(\"-brief\", indentXml: true, excludeMeasurements: true);\n        public static readonly IExporter Full = new XmlExporter(\"-full\", indentXml: true, excludeMeasurements: false);\n        public static readonly IExporter BriefCompressed = new XmlExporter(\"-brief-compressed\", indentXml: false, excludeMeasurements: true);\n        public static readonly IExporter FullCompressed = new XmlExporter(\"-full-compressed\", indentXml: false, excludeMeasurements: false);\n\n        public static readonly IExporter Default = Brief;\n\n        protected override string FileNameSuffix { get; } = string.Empty;\n\n        public XmlExporter(string fileNameSuffix = \"\",\n                           bool indentXml = false,\n                           bool excludeMeasurements = false)\n            : base(indentXml, excludeMeasurements)\n        {\n            FileNameSuffix = fileNameSuffix;\n        }\n\n        [PublicAPI]\n        public static IExporter Custom(string fileNameSuffix = \"\",\n                                       bool indentXml = false,\n                                       bool excludeMeasurements = false) =>\n            new XmlExporter(fileNameSuffix, indentXml, excludeMeasurements);\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Exporters/Xml/XmlExporterBase.cs",
    "content": "﻿using System.IO;\nusing System.Linq;\nusing System.Text;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Mathematics;\nusing BenchmarkDotNet.Reports;\n\nnamespace BenchmarkDotNet.Exporters.Xml\n{\n    public abstract class XmlExporterBase : ExporterBase\n    {\n        protected override string FileExtension => \"xml\";\n\n        private readonly bool indentXml;\n        private readonly bool excludeMeasurements;\n\n        protected XmlExporterBase(bool indentXml = false, bool excludeMeasurements = false)\n        {\n            this.indentXml = indentXml;\n            this.excludeMeasurements = excludeMeasurements;\n        }\n\n        public override void ExportToLog(Summary summary, ILogger logger)\n        {\n            var serializer = BuildSerializer(summary);\n\n            // Use custom UTF-8 StringWriter because the default writes UTF-16\n            var stringBuilder = new StringBuilder();\n            using (var textWriter = new Utf8StringWriter(stringBuilder))\n            {\n                using (var writer = new SimpleXmlWriter(textWriter, indentXml))\n                {\n                    serializer.Serialize(writer, new SummaryDto(summary));\n                }\n            }\n\n            logger.WriteLine(stringBuilder.ToString());\n        }\n\n        private IXmlSerializer BuildSerializer(Summary summary)\n        {\n            var builder =\n                XmlSerializer.GetBuilder(typeof(SummaryDto))\n                               .WithRootName(nameof(Summary))\n                               .WithCollectionItemName(nameof(BenchmarkReportDto.Measurements),\n                                                       nameof(Measurement))\n                               .WithCollectionItemName(nameof(SummaryDto.Benchmarks),\n                                                       nameof(BenchmarkReport.BenchmarkCase))\n                               .WithCollectionItemName(nameof(Statistics.AllOutliers), \"Outlier\");\n\n            if (!summary.BenchmarksCases.Any(benchmark => benchmark.Config.HasMemoryDiagnoser()))\n            {\n                builder.WithExcludedProperty(nameof(BenchmarkReportDto.Memory));\n            }\n\n            if (excludeMeasurements)\n            {\n                builder.WithExcludedProperty(nameof(BenchmarkReportDto.Measurements));\n            }\n\n            return builder.Build();\n        }\n    }\n\n    internal class Utf8StringWriter : StringWriter\n    {\n        public override Encoding Encoding => Encoding.UTF8;\n\n        public Utf8StringWriter(StringBuilder builder) :base(builder) { }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Exporters/Xml/XmlSerializer.cs",
    "content": "﻿using System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Diagnostics.CodeAnalysis;\nusing System.Globalization;\nusing System.Linq;\nusing System.Reflection;\n\nnamespace BenchmarkDotNet.Exporters.Xml\n{\n    internal class XmlSerializer : IXmlSerializer\n    {\n        private readonly Type type;\n        private readonly string rootName;\n        private readonly IReadOnlyDictionary<string, string> collectionItemNameMap;\n        private readonly IReadOnlyCollection<string> excludedPropertyNames;\n\n        private IXmlWriter writer = default!;\n\n        public const string DefaultItemName = \"Item\";\n\n        private XmlSerializer(XmlSerializerBuilder builder)\n        {\n            type = builder.Type;\n            rootName = builder.RootName;\n            collectionItemNameMap = builder.CollectionItemNameMap;\n            excludedPropertyNames = builder.ExcludedPropertyNames;\n        }\n\n        public static XmlSerializerBuilder GetBuilder(Type type) => new XmlSerializerBuilder(type);\n\n        public void Serialize(IXmlWriter newWriter, object source)\n        {\n            ArgumentNullException.ThrowIfNull(source);\n\n            if (source.GetType() != type)\n                throw new ArgumentException(nameof(source));\n\n            writer = newWriter ?? throw new ArgumentNullException(nameof(newWriter));\n\n            Write(source);\n        }\n\n        private void Write(object source)\n        {\n            writer.WriteStartDocument();\n            WriteRoot(source, rootName);\n            writer.WriteEndDocument();\n        }\n\n        private void WriteRoot(object source, string elementName)\n        {\n            writer.WriteStartElement(elementName);\n\n            foreach (var property in type.GetProperties())\n            {\n                WriteProperty(source, property);\n            }\n\n            writer.WriteEndElement();\n        }\n\n        private void WriteProperty(object? source, PropertyInfo property)\n        {\n            if (source == null || excludedPropertyNames.Contains(property.Name))\n                return;\n\n            if (IsSimple(property.PropertyType.GetTypeInfo()))\n            {\n                WriteSimpleProperty(source, property);\n            }\n            else if (IsCollection(property))\n            {\n                WriteCollectionProperty(source, property);\n            }\n            else\n            {\n                WriteComplexProperty(property.GetValue(source), property);\n            }\n        }\n\n        private void WriteSimpleProperty(object source, PropertyInfo property)\n        {\n            string value = string.Format(\n                CultureInfo.InvariantCulture, \"{0}\", property.GetValue(source));\n\n            if (!string.IsNullOrEmpty(value))\n            {\n                writer.WriteElementString(property.Name, value);\n            }\n        }\n\n        private void WriteComplexProperty(object? source, PropertyInfo propertyInfo)\n        {\n            writer.WriteStartElement(propertyInfo.Name);\n\n            foreach (var property in propertyInfo.PropertyType.GetProperties())\n            {\n                WriteProperty(source, property);\n            }\n\n            writer.WriteEndElement();\n        }\n\n        [SuppressMessage(\"ReSharper\", \"PossibleMultipleEnumeration\")]\n        private void WriteCollectionProperty(object source, PropertyInfo property)\n        {\n            var collection = (IEnumerable?)property.GetValue(source);\n\n            if (collection == null || !IsCollectionWritable(collection))\n                return;\n\n            writer.WriteStartElement(property.Name);\n\n            string? itemName = null;\n\n            foreach (var item in collection)\n            {\n                if (itemName == null)\n                {\n                    itemName = collectionItemNameMap.ContainsKey(property.Name) ? collectionItemNameMap[property.Name] : DefaultItemName;\n                }\n\n                if (IsSimple(item.GetType().GetTypeInfo()))\n                {\n                    writer.WriteElementString(itemName,\n                        string.Format(CultureInfo.InvariantCulture, \"{0}\", item));\n                }\n                else\n                {\n                    WriteComplexItem(item, itemName);\n                }\n            }\n\n            writer.WriteEndElement();\n        }\n\n        private void WriteComplexItem(object item, string itemName)\n        {\n            writer.WriteStartElement(itemName);\n\n            foreach (var property in item.GetType().GetProperties())\n            {\n                WriteProperty(item, property);\n            }\n\n            writer.WriteEndElement();\n        }\n\n        private static bool IsSimple(TypeInfo type)\n        {\n            return type.IsPrimitive\n                       || type.IsEnum\n                       || type == typeof(string)\n                       || type == typeof(decimal);\n        }\n\n        private static bool IsCollection(PropertyInfo property)\n            => typeof(IEnumerable).IsAssignableFrom(property.PropertyType);\n\n        private static bool IsCollectionWritable(IEnumerable collection)\n            => collection.Cast<object>().FirstOrDefault() != null;\n\n        internal class XmlSerializerBuilder\n        {\n            private readonly Dictionary<string, string> collectionItemNameMap = [];\n            private readonly HashSet<string> excludedPropertyNames = [];\n\n            public Type Type { get; }\n            public string RootName { get; private set; }\n            public IReadOnlyDictionary<string, string> CollectionItemNameMap => collectionItemNameMap;\n            public IReadOnlyCollection<string> ExcludedPropertyNames => excludedPropertyNames;\n\n            public XmlSerializerBuilder(Type type)\n            {\n                ArgumentNullException.ThrowIfNull(type);\n\n                Type = type;\n                RootName = type.Name;\n            }\n\n            public XmlSerializerBuilder WithRootName(string rootName)\n            {\n                if (string.IsNullOrWhiteSpace(rootName))\n                    throw new ArgumentException(nameof(rootName));\n\n                RootName = rootName;\n                return this;\n            }\n\n            public XmlSerializerBuilder WithCollectionItemName(string collectionName, string itemName)\n            {\n                if (string.IsNullOrWhiteSpace(collectionName))\n                    throw new ArgumentException(nameof(collectionName));\n                if (string.IsNullOrWhiteSpace(itemName))\n                    throw new ArgumentException(nameof(itemName));\n\n                collectionItemNameMap.Add(collectionName, itemName);\n                return this;\n            }\n\n            public XmlSerializerBuilder WithExcludedProperty(string propertyName)\n            {\n                if (string.IsNullOrWhiteSpace(propertyName))\n                    throw new ArgumentException(nameof(propertyName));\n\n                excludedPropertyNames.Add(propertyName);\n                return this;\n            }\n\n            public IXmlSerializer Build() => new XmlSerializer(this);\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Extensions/AssemblyExtensions.cs",
    "content": "﻿using System;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Reflection;\n\nnamespace BenchmarkDotNet.Extensions\n{\n    internal static class AssemblyExtensions\n    {\n        internal static bool? IsJitOptimizationDisabled(this Assembly? assembly)\n            => GetDebuggableAttribute(assembly)?.IsJitOptimizerDisabled();\n\n        internal static bool? IsDebug(this Assembly? assembly)\n            => GetDebuggableAttribute(assembly)?.IsJitTrackingEnabled();\n\n        internal static bool IsTrue(this bool? valueOrNothing) => valueOrNothing.HasValue && valueOrNothing.Value;\n\n        private static DebuggableAttribute? GetDebuggableAttribute(Assembly? assembly)\n        {\n            try\n            {\n                return assembly?.GetCustomAttributes().OfType<DebuggableAttribute>().SingleOrDefault();\n            }\n            catch (Exception)\n            {\n                return null;\n            }\n        }\n\n        private static bool? IsJitOptimizerDisabled(this DebuggableAttribute? attribute) => attribute?.IsJITOptimizerDisabled;\n\n        private static bool? IsJitTrackingEnabled(this DebuggableAttribute? attribute) => attribute?.IsJITTrackingEnabled;\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Extensions/CommonExtensions.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Diagnostics.CodeAnalysis;\nusing System.IO;\nusing System.Linq;\nusing BenchmarkDotNet.Columns;\nusing BenchmarkDotNet.Reports;\n\nnamespace BenchmarkDotNet.Extensions\n{\n    internal static class CommonExtensions\n    {\n        /// <summary>\n        /// Gets column title formatted using the specified style\n        /// </summary>\n        public static string GetColumnTitle(this IColumn column, SummaryStyle style)\n        {\n            if (!style.PrintUnitsInHeader)\n                return column.ColumnName;\n\n            switch (column.UnitType)\n            {\n                case UnitType.CodeSize:\n                    return $\"{column.ColumnName} [{style.CodeSizeUnit.Abbreviation}]\";\n                case UnitType.Size:\n                    return style.SizeUnit != null\n                        ? $\"{column.ColumnName} [{style.SizeUnit.Abbreviation}]\"\n                        : $\"{column.ColumnName}\";\n                case UnitType.Time:\n                    return style.TimeUnit != null\n                        ? $\"{column.ColumnName} [{style.TimeUnit.Abbreviation}]\"\n                        : $\"{column.ColumnName}\";\n                case UnitType.Dimensionless:\n                    return column.ColumnName;\n                default:\n                    return column.ColumnName;\n            }\n        }\n\n        public static bool IsNullOrEmpty<T>([NotNullWhen(false)] this IReadOnlyCollection<T>? value) => value == null || value.Count == 0;\n        public static bool IsEmpty<T>(this IReadOnlyCollection<T> value) => value.Count == 0;\n        public static bool IsEmpty<T>(this IEnumerable<T> value) => !value.Any();\n\n        public static IEnumerable<T> WhereNotNull<T>(this IEnumerable<T?> values) => values.Where(value => value != null).Cast<T>();\n\n        public static void AddRange<T>(this HashSet<T> hashSet, IEnumerable<T> collection)\n        {\n            foreach (var item in collection)\n                hashSet.Add(item);\n        }\n\n        public static void AddRangeDistinct<T>(this List<T> list, IEnumerable<T> items, IEqualityComparer<T>? comparer = null)\n        {\n            var hashSet = new HashSet<T>(list, comparer);\n            foreach (var item in items)\n            {\n                if (hashSet.Add(item))\n                    list.Add(item);\n            }\n        }\n\n#if NETSTANDARD2_0\n        public static TValue? GetValueOrDefault<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key)\n            => dictionary.TryGetValue(key, out var value) ? value : default;\n#endif\n\n        public static double Sqr(this double x) => x * x;\n        public static double Pow(this double x, double k) => Math.Pow(x, k);\n\n#if NETSTANDARD\n        internal static IEnumerable<TItem> DistinctBy<TItem, TValue>(this IEnumerable<TItem> items, Func<TItem, TValue> selector)\n            => DistinctBy(items, selector, EqualityComparer<TValue>.Default);\n\n        private static IEnumerable<TItem> DistinctBy<TItem, TValue>(this IEnumerable<TItem> items, Func<TItem, TValue> selector,\n            IEqualityComparer<TValue> equalityComparer)\n        {\n            var seen = new HashSet<TValue>(equalityComparer);\n\n            foreach (var item in items)\n                if (seen.Add(selector(item)))\n                    yield return item;\n        }\n#endif\n\n        internal static void ForEach<T>(this IList<T> source, Action<T> command)\n        {\n            foreach (var item in source)\n                command(item);\n        }\n\n        internal static string CreateIfNotExists(this string directoryPath)\n        {\n            if (!Directory.Exists(directoryPath))\n                Directory.CreateDirectory(directoryPath);\n\n            return directoryPath;\n        }\n\n        internal static DirectoryInfo CreateIfNotExists(this DirectoryInfo directory)\n        {\n            if (!directory.Exists)\n                directory.Create();\n\n            return directory;\n        }\n\n        internal static string DeleteFileIfExists(this string filePath)\n        {\n            if (File.Exists(filePath))\n                File.Delete(filePath);\n\n            return filePath;\n        }\n\n        internal static string EnsureFolderExists(this string filePath)\n        {\n            string? directoryPath = Path.GetDirectoryName(filePath);\n            if (directoryPath == null)\n                throw new ArgumentException($\"Can't get directory path from '{filePath}'\");\n\n            if (!Directory.Exists(directoryPath))\n                Directory.CreateDirectory(directoryPath);\n\n            return filePath;\n        }\n\n        internal static bool IsNotNullButDoesNotExist(this FileSystemInfo? fileInfo)\n            => fileInfo != null && !fileInfo.Exists;\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Extensions/ConfigurationExtensions.cs",
    "content": "﻿using BenchmarkDotNet.Environments;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Extensions\n{\n    public static class ConfigurationExtensions\n    {\n        [PublicAPI]\n        public static string ToConfig(this Platform platform)\n        {\n            switch (platform)\n            {\n                case Platform.AnyCpu:\n                    return \"AnyCPU\";\n                case Platform.X86:\n                    return \"x86\";\n                case Platform.X64:\n                    return \"x64\";\n                case Platform.Arm:\n                    return \"ARM\";\n                case Platform.Arm64:\n                    return \"ARM64\";\n                default:\n                    return \"AnyCPU\";\n            }\n        }\n\n        public static string ToConfig(this Jit jit) => jit == Jit.LegacyJit ? \"1\" : \"0\";\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Extensions/CultureInfoExtensions.cs",
    "content": "using System.Globalization;\nusing BenchmarkDotNet.Helpers;\n\nnamespace BenchmarkDotNet.Extensions\n{\n    internal static class CultureInfoExtensions\n    {\n        public static string GetActualListSeparator(this CultureInfo? cultureInfo)\n        {\n            cultureInfo = cultureInfo ?? DefaultCultureInfo.Instance;\n            string listSeparator = cultureInfo.TextInfo.ListSeparator;\n\n            // On .NET Core + Linux, TextInfo.ListSeparator returns NumberFormat.NumberGroupSeparator\n            // To workaround this behavior, we patch empty ListSeparator with \";\"\n            // See also: https://github.com/dotnet/runtime/issues/536\n            if (string.IsNullOrWhiteSpace(listSeparator))\n                listSeparator = \";\";\n\n            return listSeparator;\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Extensions/DoubleExtensions.cs",
    "content": "using System.Globalization;\n\nnamespace BenchmarkDotNet.Extensions\n{\n    internal static class DoubleExtensions\n    {\n        public static string ToInvariantString(this double value) => value.ToString(CultureInfo.InvariantCulture);\n        public static string ToInvariantString(this double value, string format) => value.ToString(format, CultureInfo.InvariantCulture);\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Extensions/EncodingExtensions.cs",
    "content": "﻿using System.Text;\n\nnamespace BenchmarkDotNet.Extensions\n{\n    internal static class EncodingExtensions\n    {\n        internal static string ToTemplateString(this Encoding encoding)\n        {\n            const string result = \"System.Text.Encoding.\";\n            switch (encoding)\n            {\n                case UnicodeEncoding u:\n                    return result + u.EncodingName;\n                default:\n                    return result + \"ASCII\";\n            }\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Extensions/Hashing.cs",
    "content": "// Licensed to the .NET Foundation under one or more agreements.\n// The .NET Foundation licenses this file to you under the MIT license.\n// See the LICENSE file in the project root for more information.\n\n// file copied from https://github.com/dotnet/machinelearning/blob/b31bdee6671bfe50460f9279609dd948f8ce081c/src/Microsoft.ML.Core/Utilities/Hashing.cs\n\nusing System;\nusing System.Runtime.CompilerServices;\n\nnamespace BenchmarkDotNet.Extensions\n{\n    internal static class Hashing\n    {\n        private const uint _defaultSeed = (5381 << 16) + 5381;\n\n        internal static uint HashString(string str) => MurmurHash(_defaultSeed, str.AsSpan());\n\n        /// <summary>\n        /// Implements the murmur hash 3 algorithm, using a mock UTF-8 encoding.\n        /// The UTF-8 conversion ignores the possibilities of unicode planes other than the 0th.\n        /// That is, it simply converts char values to one, two, or three bytes according to\n        /// the following rules:\n        /// * 0x0000 to 0x007F : 0xxxxxxx\n        /// * 0x0080 to 0x07FF : 110xxxxx 10xxxxxx\n        /// * 0x0800 to 0xFFFF : 1110xxxx 10xxxxxx 10xxxxxx\n        /// NOTE: This MUST match the StringBuilder version below.\n        /// </summary>\n        private static uint MurmurHash(uint hash, ReadOnlySpan<char> span, bool toUpper = false)\n        {\n            // Byte length (in pseudo UTF-8 form).\n            int len = 0;\n\n            // Current bits, value and count.\n            ulong cur = 0;\n            int bits = 0;\n            for (int ich = 0; ich < span.Length; ich++)\n            {\n                uint ch = toUpper ? char.ToUpperInvariant(span[ich]) : span[ich];\n                if (ch <= 0x007F)\n                {\n                    cur |= ch << bits;\n                    bits += 8;\n                }\n                else if (ch <= 0x07FF)\n                {\n                    cur |= (ulong)((ch & 0x003F) | ((ch << 2) & 0x1F00) | 0xC080) << bits;\n                    bits += 16;\n                }\n                else\n                {\n                    cur |= (ulong)((ch & 0x003F) | ((ch << 2) & 0x3F00) | ((ch << 4) & 0x0F0000) | 0xE08080) << bits;\n                    bits += 24;\n                }\n\n                if (bits >= 32)\n                {\n                    hash = MurmurRound(hash, (uint)cur);\n                    cur = cur >> 32;\n                    bits -= 32;\n                    len += 4;\n                }\n            }\n\n            if (bits > 0)\n            {\n                hash = MurmurRound(hash, (uint)cur);\n                len += bits / 8;\n            }\n\n            // Encode the length.\n            hash = MurmurRound(hash, (uint)len);\n\n            // Final mixing ritual for the hash.\n            hash = MixHash(hash);\n\n            return hash;\n        }\n\n        /// <summary>\n        /// Combines the given hash value with a uint value, using the murmur hash 3 algorithm.\n        /// Make certain to also use <see cref=\"MixHash\"/> on the final hashed value, if you\n        /// depend upon having distinct bits.\n        /// </summary>\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        private static uint MurmurRound(uint hash, uint chunk)\n        {\n            chunk *= 0xCC9E2D51;\n            chunk = Rotate(chunk, 15);\n            chunk *= 0x1B873593;\n\n            hash ^= chunk;\n            hash = Rotate(hash, 13);\n            hash *= 5;\n            hash += 0xE6546B64;\n\n            return hash;\n        }\n\n        /// <summary>\n        /// The final mixing ritual for the Murmur3 hashing algorithm. Most users of\n        /// <see cref=\"MurmurRound\"/> will want to close their progressive building of\n        /// a hash with a call to this method.\n        /// </summary>\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        private static uint MixHash(uint hash)\n        {\n            hash ^= hash >> 16;\n            hash *= 0x85ebca6b;\n            hash ^= hash >> 13;\n            hash *= 0xc2b2ae35;\n            hash ^= hash >> 16;\n            return hash;\n        }\n\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        private static uint Rotate(uint x, int r)\n        {\n            return (x << r) | (x >> (32 - r));\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Extensions/MathExtensions.cs",
    "content": "using System;\n\nnamespace BenchmarkDotNet.Extensions;\n\ninternal static class MathExtensions\n{\n    public static int RoundToInt(this double x) => (int)Math.Round(x);\n    public static long RoundToLong(this double x) => (long)Math.Round(x);\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Extensions/MethodInfoExtensions.cs",
    "content": "﻿#if NETSTANDARD2_0\nusing System;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Reflection;\n\nnamespace BenchmarkDotNet.Extensions;\n\ninternal static class MethodInfoExtensions\n{\n    public static T CreateDelegate<T>(this MethodInfo methodInfo)\n        where T : Delegate\n    {\n        return (T)methodInfo.CreateDelegate(typeof(T));\n    }\n\n    public static T CreateDelegate<T>(this MethodInfo methodInfo, object? target)\n       where T : Delegate\n    {\n        return (T)methodInfo.CreateDelegate(typeof(T), target);\n    }\n\n}\n#endif"
  },
  {
    "path": "src/BenchmarkDotNet/Extensions/PathFeatures.cs",
    "content": "﻿// Licensed to the .NET Foundation under one or more agreements.\n// The .NET Foundation licenses this file to you under the MIT license.\n// See the LICENSE file in the project root for more information.\n\n// file copied from https://github.com/dotnet/runtime/blob/bf2e135c12cbd34aeba2fa4a31d0e84184041a17/src/libraries/Common/tests/System/IO/PathFeatures.cs\n\nusing System;\nusing System.Reflection;\nusing System.Runtime.InteropServices;\n\nnamespace BenchmarkDotNet.Extensions\n{\n    internal static class PathFeatures\n    {\n        private enum State\n        {\n            Uninitialized,\n            True,\n            False\n        }\n\n        // Note that this class is using APIs that allow it to run on all platforms (including Core 5.0)\n        // That is why we have .GetTypeInfo(), don't use the Registry, etc...\n\n        private static State s_osEnabled;\n        private static State s_onCore;\n\n        /// <summary>\n        /// Returns true if you can use long paths, including long DOS style paths (e.g. over 260 without \\\\?\\).\n        /// </summary>\n        internal static bool AreAllLongPathsAvailable()\n        {\n            // We have support built-in for all platforms in Core\n            if (RunningOnCoreLib)\n                return true;\n\n            // Otherwise we're running on Windows, see if we've got the capability in .NET, and that the feature is enabled in the OS\n            return !AreLongPathsBlocked() && AreOsLongPathsEnabled();\n        }\n\n        internal static bool IsUsingLegacyPathNormalization()\n        {\n            return HasLegacyIoBehavior(\"UseLegacyPathHandling\");\n        }\n\n        /// <summary>\n        /// Returns true if > MAX_PATH (260) character paths are blocked.\n        /// Note that this doesn't reflect that you can actually use long paths without device syntax when on Windows.\n        /// Use AreAllLongPathsAvailable() to see that you can use long DOS style paths if on Windows.\n        /// </summary>\n        internal static bool AreLongPathsBlocked()\n        {\n            return HasLegacyIoBehavior(\"BlockLongPaths\");\n        }\n\n        private static bool HasLegacyIoBehavior(string propertyName)\n        {\n            // Core doesn't have legacy behaviors\n            if (RunningOnCoreLib)\n                return false;\n\n            Type t = typeof(object).GetTypeInfo().Assembly.GetType(\"System.AppContextSwitches\")!;\n            var p = t.GetProperty(propertyName, BindingFlags.Static | BindingFlags.Public);\n\n            // If the switch actually exists use it, otherwise we predate the switch and are effectively on\n            return (bool)(p?.GetValue(null) ?? true);\n        }\n\n        private static bool RunningOnCoreLib\n        {\n            get\n            {\n                // Not particularly elegant\n                if (s_onCore == State.Uninitialized)\n                    s_onCore = typeof(object).GetTypeInfo().Assembly.GetName().Name == \"System.Private.CoreLib\" ? State.True : State.False;\n\n                return s_onCore == State.True;\n            }\n        }\n\n        private static bool AreOsLongPathsEnabled()\n        {\n            if (s_osEnabled == State.Uninitialized)\n            {\n                // No official way to check yet this is good enough for tests\n                try\n                {\n                    s_osEnabled = RtlAreLongPathsEnabled() ? State.True : State.False;\n                }\n                catch\n                {\n                    s_osEnabled = State.False;\n                }\n            }\n\n            return s_osEnabled == State.True;\n        }\n\n        [DllImport(\"ntdll\", ExactSpelling = true)]\n        private static extern bool RtlAreLongPathsEnabled();\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Extensions/Polyfills/ArgumentExceptionExtensions.cs",
    "content": "﻿#if NET6_0 || NETSTANDARD2_0\nusing System.Diagnostics.CodeAnalysis;\nusing System.Runtime.CompilerServices;\n\nnamespace System;\n\ninternal static partial class ArgumentExceptionExtensions\n{\n    extension(ArgumentException)\n    {\n        public static void ThrowIfNullOrEmpty(\n            string? argument,\n            [CallerArgumentExpression(nameof(argument))] string? paramName = null)\n        {\n            if (argument is null)\n                throw new ArgumentNullException(paramName);\n\n            if (argument.Length == 0)\n                throw new ArgumentException(\"String cannot be empty.\", paramName);\n        }\n\n        public static void ThrowIfNullOrWhiteSpace([NotNull] string? argument, [CallerArgumentExpression(nameof(argument))] string? paramName = null)\n        {\n            if (argument is null)\n            {\n                throw new ArgumentNullException(paramName);\n            }\n\n            if (string.IsNullOrWhiteSpace(argument))\n            {\n                throw new ArgumentException(\"String cannot be empty or whitespace.\", paramName);\n            }\n        }\n    }\n}\n#endif\n"
  },
  {
    "path": "src/BenchmarkDotNet/Extensions/Polyfills/ArgumentNullExceptionExtensions.cs",
    "content": "﻿#if NET6_0 || NETSTANDARD2_0\nusing System.Diagnostics.CodeAnalysis;\nusing System.Runtime.CompilerServices;\n\nnamespace System;\n\ninternal static partial class ArgumentNullExceptionExtensions\n{\n    extension(ArgumentNullException)\n    {\n        public static void ThrowIfNull([NotNull] object? argument, [CallerArgumentExpression(nameof(argument))] string? paramName = null)\n        {\n            if (argument is null)\n            {\n                throw new ArgumentNullException(paramName);\n            }\n        }\n    }\n}\n#endif\n"
  },
  {
    "path": "src/BenchmarkDotNet/Extensions/Polyfills/EnumExtensions.cs",
    "content": "﻿#if NETSTANDARD2_0\nnamespace System;\n\ninternal static partial class EnumExtensions\n{\n    extension(Enum)\n    {\n        public static TEnum[] GetValues<TEnum>()\n            where TEnum : struct, Enum\n        {\n            var values = Enum.GetValues(typeof(TEnum));\n            var result = new TEnum[values.Length];\n            Array.Copy(values, result, values.Length);\n            return result;\n        }\n\n        public static TEnum Parse<TEnum>(string value)\n            where TEnum : struct, Enum\n        {\n            return (TEnum)Enum.Parse(typeof(TEnum), value);\n        }\n\n        public static string[] GetNames<TEnum>()\n            where TEnum : struct, Enum\n        {\n            return Enum.GetNames(typeof(TEnum));\n        }\n    }\n}\n#endif\n"
  },
  {
    "path": "src/BenchmarkDotNet/Extensions/ProcessExtensions.cs",
    "content": "using BenchmarkDotNet.Characteristics;\nusing BenchmarkDotNet.Detectors;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Helpers;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Portability;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Toolchains.CoreRun;\nusing JetBrains.Annotations;\nusing System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Diagnostics;\nusing System.IO;\n\nnamespace BenchmarkDotNet.Extensions\n{\n    // we need it public to reuse it in the auto-generated dll\n    // but we hide it from intellisense with following attribute\n    [EditorBrowsable(EditorBrowsableState.Never)]\n    [PublicAPI]\n    public static class ProcessExtensions\n    {\n        private static readonly TimeSpan DefaultKillTimeout = TimeSpan.FromSeconds(30);\n\n        public static void EnsureHighPriority(this Process process, ILogger logger)\n        {\n            try\n            {\n                process.PriorityClass = ProcessPriorityClass.High;\n            }\n            catch (Exception ex)\n            {\n                logger.WriteLineInfo($\"// Failed to set up high priority ({ex.Message}). In order to run benchmarks with high priority, make sure you have the right permissions.\");\n            }\n        }\n\n        internal static string ToPresentation(this IntPtr processorAffinity, int processorCount)\n            => (RuntimeInformation.Is64BitPlatform()\n                    ? Convert.ToString(processorAffinity.ToInt64(), 2)\n                    : Convert.ToString(processorAffinity.ToInt32(), 2))\n                .PadLeft(processorCount, '0');\n\n        private static IntPtr FixAffinity(IntPtr processorAffinity)\n        {\n            // Max supported affinity without CPU groups is 64\n            long cpuMask = Environment.ProcessorCount >= 64 ? unchecked((long)0xFFFF_FFFF_FFFF_FFFF) : (1L << Environment.ProcessorCount) - 1;\n\n            return RuntimeInformation.Is64BitPlatform()\n                ? new IntPtr(processorAffinity.ToInt64() & cpuMask)\n                : new IntPtr(processorAffinity.ToInt32() & cpuMask);\n        }\n\n        public static bool TrySetPriority(\n            this Process process,\n            ProcessPriorityClass priority,\n            ILogger logger)\n        {\n            try\n            {\n                process.PriorityClass = priority;\n                return true;\n            }\n            catch (Exception ex)\n            {\n                logger.WriteLineError(\n                    $\"// ! Failed to set up priority {priority} for process {process}. Make sure you have the right permissions. Message: {ex.Message}\");\n            }\n\n            return false;\n        }\n\n        public static bool TrySetAffinity(\n            this Process process,\n            IntPtr processorAffinity,\n            ILogger logger)\n        {\n            if (!OsDetector.IsWindows() && !OsDetector.IsLinux())\n                return false;\n\n            try\n            {\n                process.ProcessorAffinity = FixAffinity(processorAffinity);\n                return true;\n            }\n            catch (Exception ex)\n            {\n                logger.WriteLineError(\n                    $\"// ! Failed to set up processor affinity 0x{(long)processorAffinity:X} for process {process}. Make sure you have the right permissions. Message: {ex.Message}\");\n            }\n\n            return false;\n        }\n\n        public static IntPtr? TryGetAffinity(this Process process)\n        {\n            if (!OsDetector.IsWindows() && !OsDetector.IsLinux())\n                return null;\n\n            try\n            {\n                return process.ProcessorAffinity;\n            }\n            catch (PlatformNotSupportedException)\n            {\n                return null;\n            }\n        }\n\n        internal static void SetEnvironmentVariables(this ProcessStartInfo start, BenchmarkCase benchmarkCase, IResolver resolver)\n        {\n            if (benchmarkCase.Job.Environment.Runtime is ClrRuntime clrRuntime && clrRuntime.Version.IsNotBlank())\n                SetClrEnvironmentVariables(start, \"Version\", clrRuntime.Version);\n\n            if (benchmarkCase.Job.Environment.Runtime is MonoRuntime monoRuntime && monoRuntime.MonoBclPath.IsNotBlank())\n                start.EnvironmentVariables[\"MONO_PATH\"] = monoRuntime.MonoBclPath;\n\n            if (benchmarkCase.Config.HasPerfCollectProfiler())\n            {\n                // enable tracing configuration inside of CoreCLR (https://github.com/dotnet/coreclr/blob/master/Documentation/project-docs/linux-performance-tracing.md#collecting-a-trace)\n                SetClrEnvironmentVariables(start, \"PerfMapEnabled\", \"1\");\n                SetClrEnvironmentVariables(start, \"EnableEventLog\", \"1\");\n                // enable BDN Event Source (https://github.com/dotnet/coreclr/blob/master/Documentation/project-docs/linux-performance-tracing.md#filtering)\n                SetClrEnvironmentVariables(start, \"EventSourceFilter\", EngineEventSource.SourceName);\n                // workaround for https://github.com/dotnet/runtime/issues/71786, will be solved by next perf version\n                start.EnvironmentVariables[\"DOTNET_EnableWriteXorExecute\"] = \"0\";\n            }\n\n            // corerun does not understand runtimeconfig.json files;\n            // we have to set \"COMPlus_GC*\" environment variables as documented in\n            // https://docs.microsoft.com/en-us/dotnet/core/run-time-config/garbage-collector\n            if (benchmarkCase.Job.Infrastructure.Toolchain is CoreRunToolchain _)\n                start.SetCoreRunEnvironmentVariables(benchmarkCase, resolver);\n\n            // disable ReSharper's Dynamic Program Analysis (see https://github.com/dotnet/BenchmarkDotNet/issues/1871 for details)\n            start.EnvironmentVariables[\"JETBRAINS_DPA_AGENT_ENABLE\"] = \"0\";\n\n            if (benchmarkCase.Job.ResolveValueAsNullable(RunMode.RunStrategyCharacteristic) != RunStrategy.ColdStart\n                // CallCountingDelayMs=0 breaks DisassemblyDiagnoser, so we only set it if the job doesn't need disassembly. https://github.com/dotnet/runtime/issues/117339\n                && !benchmarkCase.Config.HasDisassemblyDiagnoser())\n            {\n                SetClrEnvironmentVariables(start, JitInfo.EnvCallCountingDelayMs, \"0\");\n            }\n\n            if (!benchmarkCase.Job.HasValue(EnvironmentMode.EnvironmentVariablesCharacteristic))\n                return;\n\n            foreach (var environmentVariable in benchmarkCase.Job.Environment.EnvironmentVariables ?? [])\n                start.EnvironmentVariables[environmentVariable.Key] = environmentVariable.Value;\n        }\n\n        // the code below was copy-pasted from https://github.com/dotnet/cli/blob/0bc24bff775e22352c2309ef990281280f92dbaa/test/Microsoft.DotNet.Tools.Tests.Utilities/Extensions/ProcessExtensions.cs#L13\n\n        public static void KillTree(this Process process) => process.KillTree(DefaultKillTimeout);\n\n        public static void KillTree(this Process process, TimeSpan timeout)\n        {\n            if (OsDetector.IsWindows())\n            {\n                RunProcessAndIgnoreOutput(\"taskkill\", $\"/T /F /PID {process.Id}\", timeout);\n            }\n            else\n            {\n                var children = new HashSet<int>();\n                GetAllChildIdsUnix(process.Id, children, timeout);\n                foreach (var childId in children)\n                {\n                    KillProcessUnix(childId, timeout);\n                }\n                KillProcessUnix(process.Id, timeout);\n            }\n        }\n\n        private static void KillProcessUnix(int processId, TimeSpan timeout)\n            => RunProcessAndIgnoreOutput(\"kill\", $\"-TERM {processId}\", timeout);\n\n        private static void GetAllChildIdsUnix(int parentId, HashSet<int> children, TimeSpan timeout)\n        {\n            var (exitCode, stdout) = RunProcessAndReadOutput(\"pgrep\", $\"-P {parentId}\", timeout);\n\n            if (exitCode == 0 && !string.IsNullOrEmpty(stdout))\n            {\n                using (var reader = new StringReader(stdout))\n                {\n                    while (true)\n                    {\n                        var text = reader.ReadLine();\n                        if (text == null)\n                            return;\n\n                        if (int.TryParse(text, out int id) && !children.Contains(id))\n                        {\n                            children.Add(id);\n                            // Recursively get the children\n                            GetAllChildIdsUnix(id, children, timeout);\n                        }\n                    }\n                }\n            }\n        }\n\n        private static (int exitCode, string output) RunProcessAndReadOutput(string fileName, string arguments, TimeSpan timeout)\n        {\n            using var process = new Process\n            {\n                StartInfo = new ProcessStartInfo\n                {\n                    FileName = fileName,\n                    Arguments = arguments,\n                    RedirectStandardOutput = true,\n                    RedirectStandardError = false,\n                    UseShellExecute = false,\n                    CreateNoWindow = true,\n                },\n                EnableRaisingEvents = true\n            };\n            using var processOutputReader = new AsyncProcessOutputReader(process, readStandardError: false);\n            using var consoleExitHandler = new ConsoleExitHandler(process, NullLogger.Instance);\n\n            process.Start();\n            processOutputReader.BeginRead();\n\n            bool isSuccess = process.WaitForExit((int)timeout.TotalMilliseconds);\n            if (!isSuccess)\n            {\n                processOutputReader.CancelRead();\n                consoleExitHandler.KillProcessTree();\n\n                return (process.HasExited ? process.ExitCode : -1, \"\");\n            }\n\n            processOutputReader.StopRead();\n            return (process.ExitCode, processOutputReader.GetOutputText());\n        }\n\n        private static int RunProcessAndIgnoreOutput(string fileName, string arguments, TimeSpan timeout)\n        {\n            var startInfo = new ProcessStartInfo\n            {\n                FileName = fileName,\n                Arguments = arguments,\n                RedirectStandardOutput = false,\n                RedirectStandardError = false,\n                UseShellExecute = false,\n                CreateNoWindow = true\n            };\n\n            using (var process = Process.Start(startInfo)!)\n            {\n                if (!process.WaitForExit((int)timeout.TotalMilliseconds))\n                    process.Kill();\n\n                return process.ExitCode;\n            }\n        }\n\n        private static void SetCoreRunEnvironmentVariables(this ProcessStartInfo start, BenchmarkCase benchmarkCase, IResolver resolver)\n        {\n            var gcMode = benchmarkCase.Job.Environment.Gc;\n\n            SetClrEnvironmentVariables(start, \"gcServer\", gcMode.ResolveValue(GcMode.ServerCharacteristic, resolver) ? \"1\" : \"0\");\n            SetClrEnvironmentVariables(start, \"gcConcurrent\", gcMode.ResolveValue(GcMode.ConcurrentCharacteristic, resolver) ? \"1\" : \"0\");\n\n            if (gcMode.HasValue(GcMode.CpuGroupsCharacteristic))\n                SetClrEnvironmentVariables(start, \"GCCpuGroup\", gcMode.ResolveValue(GcMode.CpuGroupsCharacteristic, resolver) ? \"1\" : \"0\");\n            if (gcMode.HasValue(GcMode.AllowVeryLargeObjectsCharacteristic))\n                SetClrEnvironmentVariables(start, \"gcAllowVeryLargeObjects\", gcMode.ResolveValue(GcMode.AllowVeryLargeObjectsCharacteristic, resolver) ? \"1\" : \"0\");\n            if (gcMode.HasValue(GcMode.RetainVmCharacteristic))\n                SetClrEnvironmentVariables(start, \"GCRetainVM\", gcMode.ResolveValue(GcMode.RetainVmCharacteristic, resolver) ? \"1\" : \"0\");\n            if (gcMode.HasValue(GcMode.NoAffinitizeCharacteristic))\n                SetClrEnvironmentVariables(start, \"GCNoAffinitize\", gcMode.ResolveValue(GcMode.NoAffinitizeCharacteristic, resolver) ? \"1\" : \"0\");\n            if (gcMode.HasValue(GcMode.HeapAffinitizeMaskCharacteristic))\n                SetClrEnvironmentVariables(start, \"GCHeapAffinitizeMask\", gcMode.HeapAffinitizeMask.ToString(\"X\"));\n            if (gcMode.HasValue(GcMode.HeapCountCharacteristic))\n                SetClrEnvironmentVariables(start, \"GCHeapCount\", gcMode.HeapCount.ToString(\"X\"));\n        }\n\n        private static void SetClrEnvironmentVariables(ProcessStartInfo start, string suffix, string value)\n        {\n            start.EnvironmentVariables[$\"DOTNET_{suffix}\"] = value;\n            start.EnvironmentVariables[$\"COMPlus_{suffix}\"] = value;\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Extensions/ReflectionExtensions.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Diagnostics.CodeAnalysis;\nusing System.Linq;\nusing System.Reflection;\nusing BenchmarkDotNet.Attributes;\n\nnamespace BenchmarkDotNet.Extensions\n{\n    internal static class ReflectionExtensions\n    {\n        internal static T? ResolveAttribute<T>(this Type? type) where T : Attribute =>\n            type?.GetTypeInfo().GetCustomAttributes(typeof(T), false).OfType<T>().FirstOrDefault();\n\n        internal static T? ResolveAttribute<T>(this MemberInfo? memberInfo) where T : Attribute =>\n            memberInfo?.GetCustomAttributes(typeof(T), false).FirstOrDefault() as T;\n\n        internal static bool HasAttribute<T>(this MemberInfo? memberInfo) where T : Attribute =>\n            memberInfo.ResolveAttribute<T>() != null;\n\n        internal static bool IsNullable(this Type type) => Nullable.GetUnderlyingType(type) != null;\n\n        public static bool IsInitOnly(this PropertyInfo propertyInfo)\n        {\n            var setMethodReturnParameter = propertyInfo.SetMethod?.ReturnParameter;\n            if (setMethodReturnParameter == null)\n                return false;\n\n            var isExternalInitType = typeof(System.Runtime.CompilerServices.Unsafe).Assembly\n                .GetType(\"System.Runtime.CompilerServices.IsExternalInit\");\n            if (isExternalInitType == null)\n                return false;\n\n            return setMethodReturnParameter.GetRequiredCustomModifiers().Contains(isExternalInitType);\n        }\n\n        /// <summary>\n        /// returns type name which can be used in generated C# code\n        /// </summary>\n        internal static string GetCorrectCSharpTypeName(this Type type, bool includeNamespace = true, bool includeGenericArgumentsNamespace = true, bool prefixWithGlobal = true)\n        {\n            while (!(type.IsPublic || type.IsNestedPublic) && type.BaseType != null)\n                type = type.BaseType;\n\n            // the reflection is missing information about types passed by ref (ie ref ValueTuple<int> is reported as NON generic type)\n            if (type.IsByRef && !type.IsGenericType)\n                type = type.GetElementType() ?? throw new NullReferenceException(nameof(type.GetElementType)); // https://github.com/dotnet/corefx/issues/29975#issuecomment-393134330\n\n            if (type == typeof(void))\n                return \"void\";\n            if (type == typeof(void*))\n                return \"void*\";\n\n            string prefix = \"\";\n\n            if (type.Namespace.IsNotBlank() && includeNamespace)\n            {\n                prefix += type.Namespace + \".\";\n\n                if (prefixWithGlobal)\n                    prefix = $\"global::{prefix}\";\n            }\n\n            if (type.GetTypeInfo().IsGenericParameter)\n                return type.Name;\n\n            if (type.IsArray)\n            {\n                var typeName = GetCorrectCSharpTypeName(type.GetElementType()!, includeNamespace, includeGenericArgumentsNamespace, prefixWithGlobal);\n                var parts = typeName.Split(['['], count: 2);\n\n                string repr = parts[0] + '[' + new string(',', type.GetArrayRank() - 1) + ']';\n\n                if (parts.Length == 2) return repr + '[' + parts[1];\n\n                return repr;\n            }\n\n            return prefix + string.Join(\".\", GetNestedTypeNames(type, includeGenericArgumentsNamespace, prefixWithGlobal).Reverse());\n        }\n\n        // from most nested to least\n        private static IEnumerable<string> GetNestedTypeNames(Type type, bool includeGenericArgumentsNamespace, bool prefixWithGlobal)\n        {\n            var allTypeParameters = new Stack<Type>(type.GetGenericArguments());\n\n            Type currentType = type;\n            while (currentType != null)\n            {\n                string name = currentType.Name.Replace(\"&\", string.Empty);\n\n                if (name.Contains('`'))\n                {\n                    var parts = name.Split('`');\n                    var mainName = parts[0];\n                    var parameterCount = int.Parse(parts[1]);\n\n                    var typeParameters = Enumerable\n                        .Range(0, parameterCount)\n                        .Select(_ => allTypeParameters.Pop())\n                        .Reverse();\n\n                    var args = string.Join(\", \", typeParameters.Select(T => GetCorrectCSharpTypeName(T, includeGenericArgumentsNamespace, includeGenericArgumentsNamespace, prefixWithGlobal)));\n                    name = $\"{mainName}<{args}>\";\n                }\n\n                yield return name;\n                currentType = currentType.DeclaringType!;\n            }\n        }\n\n        /// <summary>\n        /// returns simple, human friendly display name\n        /// </summary>\n        internal static string GetDisplayName(this Type type) => GetDisplayName(type.GetTypeInfo());\n\n        /// <summary>\n        /// returns simple, human friendly display name\n        /// </summary>\n        private static string GetDisplayName(this TypeInfo typeInfo)\n        {\n            if (!typeInfo.IsGenericType)\n                return typeInfo.Name;\n\n            string mainName = typeInfo.Name.Substring(0, typeInfo.Name.IndexOf('`'));\n            string args = string.Join(\", \", typeInfo.GetGenericArguments().Select(GetDisplayName).ToArray());\n            return $\"{mainName}<{args}>\";\n        }\n\n        internal static IEnumerable<MethodInfo> GetAllMethods(this Type type)\n        {\n            var typeInfo = type.GetTypeInfo();\n            while (typeInfo != null)\n            {\n                foreach (var methodInfo in typeInfo.DeclaredMethods)\n                    yield return methodInfo;\n                typeInfo = typeInfo.BaseType?.GetTypeInfo();\n            }\n        }\n\n        internal static IEnumerable<FieldInfo> GetAllFields(this Type type)\n        {\n            var typeInfo = type.GetTypeInfo();\n            while (typeInfo != null)\n            {\n                foreach (var fieldInfo in typeInfo.DeclaredFields)\n                    yield return fieldInfo;\n                typeInfo = typeInfo.BaseType?.GetTypeInfo();\n            }\n        }\n\n        internal static IEnumerable<PropertyInfo> GetAllProperties(this Type type)\n        {\n            var typeInfo = type.GetTypeInfo();\n            while (typeInfo != null)\n            {\n                foreach (var propertyInfo in typeInfo.DeclaredProperties)\n                    yield return propertyInfo;\n                typeInfo = typeInfo.BaseType?.GetTypeInfo();\n            }\n        }\n\n        internal static Type[] GetRunnableBenchmarks(this Assembly assembly)\n            => assembly\n                .GetTypes()\n                .Where(type => type.ContainsRunnableBenchmarks())\n                .OrderBy(t => t.Namespace)\n                .ThenBy(t => t.Name)\n                .ToArray();\n\n        internal static bool ContainsRunnableBenchmarks(this Type type)\n        {\n            var typeInfo = type.GetTypeInfo();\n\n            if (typeInfo.IsAbstract || typeInfo.IsGenericType && !IsRunnableGenericType(typeInfo))\n                return false;\n\n            return typeInfo.GetBenchmarks().Any();\n        }\n\n        private static MethodInfo[] GetBenchmarks(this TypeInfo typeInfo)\n            => typeInfo\n                .GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.Static) // we allow for Static now to produce a nice Validator warning later\n                .Where(method => method.GetCustomAttributes(true).OfType<BenchmarkAttribute>().Any())\n                .ToArray();\n\n        internal static (string Name, TAttribute Attribute, bool IsStatic, Type ParameterType)[]\n            GetTypeMembersWithGivenAttribute<TAttribute>(this Type type, BindingFlags reflectionFlags)\n            where TAttribute : Attribute\n        {\n            var fields = type\n                .GetFields(reflectionFlags)\n                .Select(f => Create(\n                    f.Name,\n                    f.ResolveAttribute<TAttribute>(),\n                    f.IsStatic,\n                    f.FieldType));\n\n            var properties = type\n                .GetProperties(reflectionFlags)\n                .Select(p => Create(\n                    p.Name,\n                    p.ResolveAttribute<TAttribute>(),\n                    p.GetSetMethod()?.IsStatic == true,\n                    p.PropertyType));\n\n            return fields.Concat(properties)\n                .WhereNotNull()\n                .Select(x => x!.Value)\n                .ToArray();\n\n            static (string Name, TAttribute Attribute, bool IsStatic, Type MemberType)?\n                Create(string name, TAttribute? attribute, bool isStatic, Type memberType)\n            {\n                if (attribute == null)\n                    return null;\n                return (name, attribute, isStatic, memberType);\n            }\n        }\n\n        internal static bool IsStackOnlyWithImplicitCast(this Type argumentType, [NotNullWhen(true)] object? argumentInstance)\n        {\n            if (argumentInstance == null)\n                return false;\n\n            if (!argumentType.IsByRefLike())\n                return false;\n\n            var instanceType = argumentInstance.GetType();\n\n            var implicitCastsDefinedInArgumentInstance = instanceType.GetMethods().Where(method => method.Name == \"op_Implicit\" && method.GetParameters().Any()).ToArray();\n            if (implicitCastsDefinedInArgumentInstance.Any(implicitCast => implicitCast.ReturnType == argumentType && implicitCast.GetParameters().All(p => p.ParameterType == instanceType)))\n                return true;\n\n            var implicitCastsDefinedInArgumentType = argumentType.GetMethods().Where(method => method.Name == \"op_Implicit\" && method.GetParameters().Any()).ToArray();\n            if (implicitCastsDefinedInArgumentType.Any(implicitCast => implicitCast.ReturnType == argumentType && implicitCast.GetParameters().All(p => p.ParameterType == instanceType)))\n                return true;\n\n            return false;\n        }\n\n        private static bool IsRunnableGenericType(TypeInfo typeInfo)\n            => // if it is an open generic - there must be GenericBenchmark attributes\n                (!typeInfo.IsGenericTypeDefinition || typeInfo.GenericTypeArguments.Any() || typeInfo.GetCustomAttributes(true).OfType<GenericTypeArgumentsAttribute>().Any())\n                    && typeInfo.DeclaredConstructors.Any(ctor => ctor.IsPublic && ctor.GetParameters().Length == 0); // we need public parameterless ctor to create it\n\n        internal static bool IsLinqPad(this Assembly assembly) => assembly.FullName!.IndexOf(\"LINQPAD\", StringComparison.OrdinalIgnoreCase) >= 0;\n\n        internal static bool IsByRefLike(this Type type)\n#if NETSTANDARD2_0\n            // Type.IsByRefLike is not available in netstandard2.0.\n            => type.IsValueType && type.CustomAttributes.Any(attr => attr.AttributeType.FullName == \"System.Runtime.CompilerServices.IsByRefLikeAttribute\");\n#else\n            => type.IsByRefLike;\n#endif\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Extensions/ReportExtensions.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Linq.Expressions;\nusing BenchmarkDotNet.Mathematics;\nusing BenchmarkDotNet.Reports;\n\nnamespace BenchmarkDotNet.Extensions\n{\n    public static class ReportExtensions\n    {\n        public static BenchmarkReport GetReportFor<T>(this Summary summary, Expression<Action<T>> actionExp)\n        {\n            if (actionExp.Body == null)\n                throw new ArgumentException(\"Extend a an Expression with a valid Body\", nameof(actionExp));\n\n            if (!(actionExp.Body is MethodCallExpression methodExp))\n                throw new ArgumentException(\"Extend a MethodCallExpression, but got a \" + actionExp.Body.GetType().Name, nameof(actionExp));\n\n            return summary.Reports.First(r => r.BenchmarkCase.Descriptor.WorkloadMethod == methodExp.Method);\n        }\n\n        public static IList<Measurement> GetRunsFor<T>(this Summary summary, Expression<Action<T>> actionExp)\n        {\n            return summary.GetReportFor(actionExp).GetResultRuns().ToList();\n        }\n\n        public static Statistics GetStatistics(this IReadOnlyCollection<Measurement> runs)\n        {\n            if (runs.IsEmpty())\n                throw new InvalidOperationException(\"List of measurements contains no elements\");\n            return new Statistics(runs.Select(r => r.GetAverageTime().Nanoseconds));\n        }\n\n        public static Statistics GetStatistics(this IEnumerable<Measurement> runs) =>\n            GetStatistics(runs.ToList());\n\n        public static bool HasError(this IEnumerable<Summary> summaries)\n        {\n            if (summaries.Count() == 0)\n            {\n                // When following argument specified. BenchmarkDotNet show information only.\n                var knownArguments = new HashSet<string>([\"--help\", \"--list\", \"--info\", \"--version\"]);\n                return !Environment.GetCommandLineArgs().Any(knownArguments.Contains);\n            }\n\n            if (summaries.Any(x => x.HasCriticalValidationErrors))\n                return true;\n\n            return summaries.Any(x => x.Reports.Any(r => !r.Success));\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Extensions/RuntimeMonikerExtensions.cs",
    "content": "﻿using BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Jobs;\nusing System;\n\nnamespace BenchmarkDotNet.Extensions\n{\n    internal static class RuntimeMonikerExtensions\n    {\n        internal static Runtime GetRuntime(this RuntimeMoniker runtimeMoniker)\n        {\n            switch (runtimeMoniker)\n            {\n                case RuntimeMoniker.Net461:\n                    return ClrRuntime.Net461;\n                case RuntimeMoniker.Net462:\n                    return ClrRuntime.Net462;\n                case RuntimeMoniker.Net47:\n                    return ClrRuntime.Net47;\n                case RuntimeMoniker.Net471:\n                    return ClrRuntime.Net471;\n                case RuntimeMoniker.Net472:\n                    return ClrRuntime.Net472;\n                case RuntimeMoniker.Net48:\n                    return ClrRuntime.Net48;\n                case RuntimeMoniker.Net481:\n                    return ClrRuntime.Net481;\n                case RuntimeMoniker.NetCoreApp20:\n                    return CoreRuntime.Core20;\n                case RuntimeMoniker.NetCoreApp21:\n                    return CoreRuntime.Core21;\n                case RuntimeMoniker.NetCoreApp22:\n                    return CoreRuntime.Core22;\n                case RuntimeMoniker.NetCoreApp30:\n                    return CoreRuntime.Core30;\n                case RuntimeMoniker.NetCoreApp31:\n                    return CoreRuntime.Core31;\n                case RuntimeMoniker.Net50:\n                    return CoreRuntime.Core50;\n                case RuntimeMoniker.Net60:\n                    return CoreRuntime.Core60;\n                case RuntimeMoniker.Net70:\n                    return CoreRuntime.Core70;\n                case RuntimeMoniker.Net80:\n                    return CoreRuntime.Core80;\n                case RuntimeMoniker.Net90:\n                    return CoreRuntime.Core90;\n                case RuntimeMoniker.Net10_0:\n                    return CoreRuntime.Core10_0;\n                case RuntimeMoniker.Net11_0:\n                    return CoreRuntime.Core11_0;\n                case RuntimeMoniker.Mono:\n                    return MonoRuntime.Default;\n                case RuntimeMoniker.NativeAot60:\n                    return NativeAotRuntime.Net60;\n                case RuntimeMoniker.NativeAot70:\n                    return NativeAotRuntime.Net70;\n                case RuntimeMoniker.NativeAot80:\n                    return NativeAotRuntime.Net80;\n                case RuntimeMoniker.NativeAot90:\n                    return NativeAotRuntime.Net90;\n                case RuntimeMoniker.NativeAot10_0:\n                    return NativeAotRuntime.Net10_0;\n                case RuntimeMoniker.NativeAot11_0:\n                    return NativeAotRuntime.Net11_0;\n                case RuntimeMoniker.Mono60:\n                    return MonoRuntime.Mono60;\n                case RuntimeMoniker.Mono70:\n                    return MonoRuntime.Mono70;\n                case RuntimeMoniker.Mono80:\n                    return MonoRuntime.Mono80;\n                case RuntimeMoniker.R2R80:\n                    return R2RRuntime.Net80;\n                case RuntimeMoniker.R2R90:\n                    return R2RRuntime.Net90;\n                case RuntimeMoniker.R2R10_0:\n                    return R2RRuntime.Net10_0;\n                case RuntimeMoniker.R2R11_0:\n                    return R2RRuntime.Net11_0;\n                default:\n                    throw new ArgumentOutOfRangeException(nameof(runtimeMoniker), runtimeMoniker, \"Runtime Moniker not supported\");\n            }\n        }\n\n        internal static Version GetRuntimeVersion(this RuntimeMoniker runtimeMoniker) => runtimeMoniker switch\n        {\n            RuntimeMoniker.Net461 => new Version(4, 6, 1),\n            RuntimeMoniker.Net462 => new Version(4, 6, 2),\n            RuntimeMoniker.Net47 => new Version(4, 7),\n            RuntimeMoniker.Net471 => new Version(4, 7, 1),\n            RuntimeMoniker.Net472 => new Version(4, 7, 2),\n            RuntimeMoniker.Net48 => new Version(4, 8),\n            RuntimeMoniker.Net481 => new Version(4, 8, 1),\n            RuntimeMoniker.NetCoreApp20 => new Version(2, 0),\n            RuntimeMoniker.NetCoreApp21 => new Version(2, 1),\n            RuntimeMoniker.NetCoreApp22 => new Version(2, 2),\n            RuntimeMoniker.NetCoreApp30 => new Version(3, 0),\n            RuntimeMoniker.NetCoreApp31 => new Version(3, 1),\n            RuntimeMoniker.Net50 => new Version(5, 0),\n            RuntimeMoniker.Net60 => new Version(6, 0),\n            RuntimeMoniker.Net70 => new Version(7, 0),\n            RuntimeMoniker.Net80 => new Version(8, 0),\n            RuntimeMoniker.Net90 => new Version(9, 0),\n            RuntimeMoniker.Net10_0 => new Version(10, 0),\n            RuntimeMoniker.Net11_0 => new Version(11, 0),\n            RuntimeMoniker.NativeAot60 => new Version(6, 0),\n            RuntimeMoniker.NativeAot70 => new Version(7, 0),\n            RuntimeMoniker.NativeAot80 => new Version(8, 0),\n            RuntimeMoniker.NativeAot90 => new Version(9, 0),\n            RuntimeMoniker.NativeAot10_0 => new Version(10, 0),\n            RuntimeMoniker.NativeAot11_0 => new Version(11, 0),\n            RuntimeMoniker.Mono60 => new Version(6, 0),\n            RuntimeMoniker.Mono70 => new Version(7, 0),\n            RuntimeMoniker.Mono80 => new Version(8, 0),\n            RuntimeMoniker.WasmNet80 => new Version(8, 0),\n            RuntimeMoniker.WasmNet90 => new Version(9, 0),\n            RuntimeMoniker.WasmNet10_0 => new Version(10, 0),\n            RuntimeMoniker.WasmNet11_0 => new Version(11, 0),\n            RuntimeMoniker.MonoAOTLLVM => Portability.RuntimeInformation.IsNetCore && CoreRuntime.TryGetVersion(out var version) ? version : new Version(6, 0),\n            RuntimeMoniker.MonoAOTLLVMNet60 => new Version(6, 0),\n            RuntimeMoniker.MonoAOTLLVMNet70 => new Version(7, 0),\n            RuntimeMoniker.MonoAOTLLVMNet80 => new Version(8, 0),\n            RuntimeMoniker.MonoAOTLLVMNet90 => new Version(9, 0),\n            RuntimeMoniker.MonoAOTLLVMNet10_0 => new Version(10, 0),\n            RuntimeMoniker.MonoAOTLLVMNet11_0 => new Version(11, 0),\n            RuntimeMoniker.R2R80 => new Version(8, 0),\n            RuntimeMoniker.R2R90 => new Version(9, 0),\n            RuntimeMoniker.R2R10_0 => new Version(10, 0),\n            RuntimeMoniker.R2R11_0 => new Version(11, 0),\n            _ => throw new NotImplementedException($\"{nameof(GetRuntimeVersion)} not implemented for {runtimeMoniker}\")\n        };\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Extensions/StatisticsExtensions.cs",
    "content": "﻿using System;\nusing System.Globalization;\nusing System.Linq;\nusing System.Text;\nusing BenchmarkDotNet.Helpers;\nusing BenchmarkDotNet.Mathematics;\nusing JetBrains.Annotations;\nusing Perfolizer.Horology;\nusing Perfolizer.Mathematics.Histograms;\nusing Perfolizer.Mathematics.Multimodality;\nusing Perfolizer.Metrology;\n\nnamespace BenchmarkDotNet.Extensions\n{\n    public static class StatisticsExtensions\n    {\n        private const string NullSummaryMessage = \"<Empty statistic (N=0)>\";\n\n        public static Func<double, string> CreateNanosecondFormatter(this Statistics s, CultureInfo cultureInfo, string format = \"N3\")\n        {\n            var timeUnit = TimeUnit.GetBestTimeUnit(s.Mean);\n            return x => PerfolizerMeasurementFormatter.Instance.Format(\n                TimeInterval.FromNanoseconds(x).ToMeasurement(timeUnit),\n                format, cultureInfo, UnitHelper.DefaultPresentation\n            );\n        }\n\n        [PublicAPI]\n        public static string ToString(this Statistics? s, CultureInfo cultureInfo, Func<double, string> formatter, bool calcHistogram = false)\n        {\n            if (s == null)\n                return NullSummaryMessage;\n\n            string listSeparator = cultureInfo.GetActualListSeparator();\n\n            var builder = new StringBuilder();\n            string errorPercent = (s.StandardError / s.Mean * 100).ToString(\"0.00\", cultureInfo);\n            var ci = s.PerfolizerConfidenceInterval;\n            string ciMarginPercent = (ci.Margin / s.Mean * 100).ToString(\"0.00\", cultureInfo);\n            double mValue = MValueCalculator.Calculate(s.Sample.Values);\n\n            builder.Append(\"Mean = \");\n            builder.Append(formatter(s.Mean));\n            builder.Append(listSeparator);\n            builder.Append(\" StdErr = \");\n            builder.Append(formatter(s.StandardError));\n            builder.Append(\" (\");\n            builder.Append(errorPercent);\n            builder.Append(\"%)\");\n            builder.Append(listSeparator);\n            builder.Append(\" N = \");\n            builder.Append(s.N.ToString(cultureInfo));\n            builder.Append(listSeparator);\n            builder.Append(\" StdDev = \");\n            builder.Append(formatter(s.StandardDeviation));\n            builder.AppendLine();\n\n            builder.Append(\"Min = \");\n            builder.Append(formatter(s.Min));\n            builder.Append(listSeparator);\n            builder.Append(\" Q1 = \");\n            builder.Append(formatter(s.Q1));\n            builder.Append(listSeparator);\n            builder.Append(\" Median = \");\n            builder.Append(formatter(s.Median));\n            builder.Append(listSeparator);\n            builder.Append(\" Q3 = \");\n            builder.Append(formatter(s.Q3));\n            builder.Append(listSeparator);\n            builder.Append(\" Max = \");\n            builder.Append(formatter(s.Max));\n            builder.AppendLine();\n\n            builder.Append(\"IQR = \");\n            builder.Append(formatter(s.InterquartileRange));\n            builder.Append(listSeparator);\n            builder.Append(\" LowerFence = \");\n            builder.Append(formatter(s.LowerFence));\n            builder.Append(listSeparator);\n            builder.Append(\" UpperFence = \");\n            builder.Append(formatter(s.UpperFence));\n            builder.AppendLine();\n\n            builder.Append(\"ConfidenceInterval = \");\n            builder.Append(\"[\" + formatter(s.PerfolizerConfidenceInterval.Lower) +\n                           \"; \" + formatter(s.PerfolizerConfidenceInterval.Upper) +\n                           $\"] (CI {s.PerfolizerConfidenceInterval.ConfidenceLevel})\");\n            builder.Append(listSeparator);\n            builder.Append(\" Margin = \");\n            builder.Append(formatter(ci.Margin));\n            builder.Append(\" (\");\n            builder.Append(ciMarginPercent);\n            builder.Append(\"% of Mean)\");\n            builder.AppendLine();\n\n            builder.Append(\"Skewness = \");\n            builder.Append(s.Skewness.ToString(\"0.##\", cultureInfo));\n            builder.Append(listSeparator);\n            builder.Append(\" Kurtosis = \");\n            builder.Append(s.Kurtosis.ToString(\"0.##\", cultureInfo));\n            builder.Append(listSeparator);\n            builder.Append(\" MValue = \");\n            builder.Append(mValue.ToString(\"0.##\", cultureInfo));\n            builder.AppendLine();\n\n            if (calcHistogram)\n            {\n                var histogram = HistogramBuilder.Adaptive.Build(s.Sample.Values);\n                MakePositive(histogram);\n                builder.AppendLine(\"-------------------- Histogram --------------------\");\n                builder.AppendLine(histogram.ToString(formatter));\n                builder.AppendLine(\"---------------------------------------------------\");\n            }\n            return builder.ToString().Trim();\n        }\n\n        // At the moment, `HistogramBuilder.Adaptive` may extend bin edges leading to negative lower value for the first bin.\n        // This could be fine in a generic case, but looks confusing for non-negative measurement values.\n        // To avoid confusing summary, we post-process the obtained bins.\n        // This workaround could be removed once a new histogram algorithm is introduced in perfolizer.\n        // See also: https://github.com/dotnet/BenchmarkDotNet/issues/1821\n        private static void MakePositive(Histogram histogram)\n        {\n            for (int i = 0; i < histogram.Bins.Length; i++)\n            {\n                var bin = histogram.Bins[i];\n                if (bin.Lower < 0)\n                    histogram.Bins[i] = new HistogramBin(bin.Values.Min(), bin.Upper, bin.Values);\n            }\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Extensions/StringAndTextExtensions.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Diagnostics.CodeAnalysis;\nusing System.IO;\nusing System.Linq;\nusing System.Text;\nusing System.Text.RegularExpressions;\n\nnamespace BenchmarkDotNet.Extensions\n{\n    // Renamed to \"StringAndTextExtensions\", so it doesn't clash with \"StringExtensions\" in BenchmarkDotNet.Portability\n    internal static class StringAndTextExtensions\n    {\n        private static readonly Lazy<Dictionary<string, string>> InvalidFileNameCharactersMappings\n            = new Lazy<Dictionary<string, string>>(BuildInvalidPathCharactersMappings);\n\n        internal static string ToLowerCase(this bool value) => value ? \"true\" : \"false\"; // to avoid .ToString().ToLower() allocation\n\n        // source: https://stackoverflow.com/a/12364234/5852046\n        internal static string EscapeCommandLine(this string cliArg)\n        {\n            if (string.IsNullOrEmpty(cliArg))\n                return cliArg;\n\n            string value = Regex.Replace(cliArg, @\"(\\\\*)\" + \"\\\"\", @\"$1\\$0\");\n            value = Regex.Replace(value, @\"^(.*\\s.*?)(\\\\*)$\", \"\\\"$1$2$2\\\"\", RegexOptions.Singleline);\n\n            return value;\n        }\n\n        /// <summary>\n        /// Escapes UNICODE control characters\n        /// </summary>\n        /// <param name=\"str\">string to escape</param>\n        /// <param name=\"quote\">True to put (double) quotes around the string literal</param>\n        internal static string EscapeSpecialCharacters(this string str, bool quote)\n        {\n            return Microsoft.CodeAnalysis.CSharp.SymbolDisplay.FormatLiteral(str, quote);\n        }\n\n        /// <summary>\n        /// Escapes UNICODE control character\n        /// </summary>\n        /// <param name=\"c\">char to escape</param>\n        /// <param name=\"quote\">True to put (single) quotes around the character literal.</param>\n        internal static string EscapeSpecialCharacter(this char c, bool quote)\n        {\n            return Microsoft.CodeAnalysis.CSharp.SymbolDisplay.FormatLiteral(c, quote);\n        }\n\n        /// <summary>\n        /// replaces all invalid file name chars with their number representation\n        /// </summary>\n        internal static string AsValidFileName(this string inputPath)\n        {\n            var validPathBuilder = new StringBuilder(inputPath);\n\n            foreach (var mapping in InvalidFileNameCharactersMappings.Value)\n            {\n                validPathBuilder.Replace(mapping.Key, mapping.Value);\n            }\n\n            return validPathBuilder.ToString();\n        }\n\n        private static Dictionary<string, string> BuildInvalidPathCharactersMappings()\n        {\n            var invalidFileNameChars = Path.GetInvalidFileNameChars().ToList();\n\n            // '\\\\' is a valid file name char on Unix\n            // which can be a problem when we are working with MSBuild\n            if (!invalidFileNameChars.Contains('\\\\'))\n                invalidFileNameChars.Add('\\\\');\n\n            return invalidFileNameChars.ToDictionary(\n                character => character.ToString(),\n                character => $\"char{(short)character}\");\n        }\n\n        /// <summary>\n        /// Returns an HTML encoded string\n        /// </summary>\n        /// <param name=\"s\">string to encode</param>\n        internal static string HtmlEncode(this string s)\n        {\n            var sb = new StringBuilder(s.Length);\n\n            foreach (char c in s)\n            {\n                switch (c)\n                {\n                    case '<':\n                        sb.Append(\"&lt;\");\n                        break;\n                    case '>':\n                        sb.Append(\"&gt;\");\n                        break;\n                    case '\"':\n                        sb.Append(\"&quot;\");\n                        break;\n                    case '\\'':\n                        sb.Append(\"&#39;\");\n                        break;\n                    case '&':\n                        sb.Append(\"&amp;\");\n                        break;\n                    default:\n                        sb.Append(c);\n                        break;\n                }\n            }\n            return sb.ToString();\n        }\n\n        /// <summary>\n        /// Returns file base name\n        /// </summary>\n        internal static string GetBaseName(this string path, string directory)\n        {\n            return path.Replace(directory, string.Empty).Trim('/', '\\\\');\n        }\n\n        /// <summary>\n        /// Standardizes the whitespace before/after arguments so that all arguments are separated by a single space\n        /// </summary>\n        /// <param name=\"stringBuilder\">The string builder that will hold the arguments</param>\n        /// <param name=\"argument\">The argument to append to this string builder</param>\n        /// <returns>The string builder with the arguments added</returns>\n        internal static StringBuilder AppendArgument(this StringBuilder stringBuilder, string? argument)\n        {\n            if (argument.IsBlank())\n            {\n                return stringBuilder;\n            }\n            argument = \" \" + argument.Trim();\n            stringBuilder.Append(argument);\n\n            return stringBuilder;\n        }\n\n        /// <summary>\n        /// Standardizes the whitespace before/after arguments so that all arguments are separated by a single space\n        /// </summary>\n        /// <param name=\"stringBuilder\">The string builder that will hold the arguments</param>\n        /// <param name=\"argument\">The argument to append to this string builder</param>\n        /// <returns>The string builder with the arguments added</returns>\n        internal static StringBuilder AppendArgument(this StringBuilder stringBuilder, object? argument)\n            => argument == null ? stringBuilder : AppendArgument(stringBuilder, argument.ToString()!);\n\n        public static bool IsBlank([NotNullWhen(false)] this string? value) => string.IsNullOrWhiteSpace(value);\n        public static bool IsNotBlank([NotNullWhen(true)] this string? value) => !value.IsBlank();\n\n        /// <summary>\n        /// Helper method to ensure not null value.\n        /// It's expected to be used for public API parameters handling.\n        /// </summary>\n        public static string EnsureNotNull(this string? value)\n        {\n            return value ?? \"\";\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Extensions/ThreadExtensions.cs",
    "content": "﻿using System;\nusing System.ComponentModel;\nusing System.Diagnostics.CodeAnalysis;\nusing System.Threading;\nusing BenchmarkDotNet.Loggers;\n\nnamespace BenchmarkDotNet.Extensions\n{\n    // we need it public to reuse it in the auto-generated dll\n    // but we hide it from intellisense with following attribute\n    [EditorBrowsable(EditorBrowsableState.Never)]\n    public static class ThreadExtensions\n    {\n        [SuppressMessage(\"ReSharper\", \"UnusedMethodReturnValue.Global\")] // TODO: check result\n        public static bool TrySetPriority(\n            this Thread thread,\n            ThreadPriority priority,\n            ILogger logger)\n        {\n            try\n            {\n                thread.Priority = priority;\n                return true;\n            }\n            catch (Exception ex)\n            {\n                logger.WriteLineError(\n                    $\"// ! Failed to set up priority {priority} for thread {thread}. Make sure you have the right permissions. Message: {ex.Message}\");\n            }\n\n            return false;\n\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Filters/AllCategoriesFilter.cs",
    "content": "using System.Linq;\nusing BenchmarkDotNet.Running;\n\nnamespace BenchmarkDotNet.Filters\n{\n    /// <summary>\n    /// Filter benchmarks which have all the target categories\n    /// </summary>\n    public class AllCategoriesFilter : IFilter\n    {\n        private readonly string[] targetCategories;\n\n        public AllCategoriesFilter(string[] targetCategories) => this.targetCategories = targetCategories;\n\n        public bool Predicate(BenchmarkCase benchmarkCase) => targetCategories.All(c => benchmarkCase.Descriptor.HasCategory(c));\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Filters/AnyCategoriesFilter.cs",
    "content": "using System.Linq;\nusing BenchmarkDotNet.Running;\n\nnamespace BenchmarkDotNet.Filters\n{\n    /// <summary>\n    /// Filter benchmarks which have any of the target categories\n    /// </summary>\n    public class AnyCategoriesFilter : IFilter\n    {\n        private readonly string[] targetCategories;\n\n        public AnyCategoriesFilter(string[] targetCategories) => this.targetCategories = targetCategories;\n\n        public bool Predicate(BenchmarkCase benchmarkCase) => targetCategories.Any(c => benchmarkCase.Descriptor.HasCategory(c));\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Filters/AttributesFilter.cs",
    "content": "using System;\nusing System.Linq;\nusing BenchmarkDotNet.Running;\n\nnamespace BenchmarkDotNet.Filters\n{\n    /// <summary>\n    /// filters benchmarks by provided attribute names\n    /// </summary>\n    public class AttributesFilter : IFilter\n    {\n        private readonly string[] attributes;\n\n        public AttributesFilter(string[] attributes) => this.attributes = attributes;\n\n        public bool Predicate(BenchmarkCase benchmarkCase)\n        {\n            var customTypeAttributes = benchmarkCase.Descriptor.Type.GetCustomAttributes(true).Select(attribute => attribute.GetType()).ToArray();\n            var customMethodsAttributes = benchmarkCase.Descriptor.WorkloadMethod.GetCustomAttributes(true).Select(attribute => attribute.GetType()).ToArray();\n\n            var allCustomAttributes = customTypeAttributes.Union(customMethodsAttributes).Distinct().ToArray();\n\n            return attributes.Any(attributeName => allCustomAttributes.Any(attribute => attribute.Name.StartsWith(attributeName, StringComparison.InvariantCultureIgnoreCase)));\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Filters/DisjunctionFilter.cs",
    "content": "using System.Linq;\nusing BenchmarkDotNet.Running;\n\nnamespace BenchmarkDotNet.Filters\n{\n    public class DisjunctionFilter : IFilter\n    {\n        private readonly IFilter[] filters;\n\n        public DisjunctionFilter(params IFilter[] filters) => this.filters = filters;\n\n        public bool Predicate(BenchmarkCase benchmarkCase) => filters.Any(filter => filter.Predicate(benchmarkCase));\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Filters/GlobFilter.cs",
    "content": "using System.Linq;\nusing System.Text.RegularExpressions;\nusing BenchmarkDotNet.Exporters;\nusing BenchmarkDotNet.Running;\n\nnamespace BenchmarkDotNet.Filters\n{\n    /// <summary>\n    /// filters benchmarks by provided glob patterns\n    /// </summary>\n    public class GlobFilter : IFilter\n    {\n        private readonly Regex[] patterns;\n\n        public GlobFilter(string[] patterns) => this.patterns = ToRegex(patterns);\n\n        public bool Predicate(BenchmarkCase benchmarkCase)\n        {\n            var benchmark = benchmarkCase.Descriptor.WorkloadMethod;\n            string nameWithoutArgs = benchmarkCase.Descriptor.GetFilterName();\n            string fullBenchmarkName = FullNameProvider.GetBenchmarkName(benchmarkCase);\n\n            return patterns.Any(pattern => pattern.IsMatch(fullBenchmarkName) || pattern.IsMatch(nameWithoutArgs));\n        }\n\n        internal static Regex[] ToRegex(string[] patterns)\n            => patterns.Select(pattern => new Regex(WildcardToRegex(pattern), RegexOptions.IgnoreCase | RegexOptions.CultureInvariant)).ToArray();\n\n        // https://stackoverflow.com/a/6907849/5852046 not perfect but should work for all we need\n        private static string WildcardToRegex(string pattern) => $\"^{Regex.Escape(pattern).Replace(@\"\\*\", \".*\").Replace(@\"\\?\", \".\")}$\";\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Filters/IFilter.cs",
    "content": "using BenchmarkDotNet.Running;\n\nnamespace BenchmarkDotNet.Filters\n{\n    public interface IFilter\n    {\n        bool Predicate(BenchmarkCase benchmarkCase);\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Filters/NameFilter.cs",
    "content": "using System;\n\nnamespace BenchmarkDotNet.Filters\n{\n    public class NameFilter : SimpleFilter\n    {\n        public NameFilter(Func<string, bool> predicate) : base(b => predicate(b.Descriptor.WorkloadMethod.Name)) { }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Filters/SimpleFilter.cs",
    "content": "using System;\nusing BenchmarkDotNet.Running;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Filters\n{\n    public class SimpleFilter : IFilter\n    {\n        private readonly Func<BenchmarkCase, bool> predicate;\n\n        [PublicAPI]\n        public SimpleFilter(Func<BenchmarkCase, bool> predicate) => this.predicate = predicate;\n\n        [PublicAPI]\n        public bool Predicate(BenchmarkCase benchmarkCase) => predicate(benchmarkCase);\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Filters/UnionFilter.cs",
    "content": "using System.Linq;\nusing BenchmarkDotNet.Running;\n\nnamespace BenchmarkDotNet.Filters\n{\n    public class UnionFilter : IFilter\n    {\n        private readonly IFilter[] filters;\n\n        public UnionFilter(params IFilter[] filters) => this.filters = filters;\n\n        public bool Predicate(BenchmarkCase benchmarkCase) => filters.All(filter => filter.Predicate(benchmarkCase));\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Helpers/ArtifactFileNameHelper.cs",
    "content": "﻿using BenchmarkDotNet.Detectors;\nusing BenchmarkDotNet.Diagnosers;\nusing BenchmarkDotNet.Exporters;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Toolchains;\nusing System;\nusing System.IO;\nusing System.Linq;\n\nnamespace BenchmarkDotNet.Helpers\n{\n    internal static class ArtifactFileNameHelper\n    {\n        private const int WindowsOldPathLimit = 260;\n        private const int CommonSenseLimit = 1024; // for benchmarks that use args like \"new string('a', 200_000)\"\n        private const int MaxFileNameLength = 255;\n\n        internal static string GetTraceFilePath(DiagnoserActionParameters details, DateTime creationTime, string fileExtension)\n        {\n            return GetFilePath(details, null, creationTime, fileExtension, \"userheap.etl\".Length - fileExtension.Length);\n        }\n\n        internal static string GetFilePath(DiagnoserActionParameters details, string? subfolder, DateTime? creationTime, string fileExtension, int reserve)\n        {\n            string nameNoLimit = GetFilePathNoLimits(details, subfolder, creationTime, fileExtension);\n\n            string fileNameOnly = Path.GetFileName(nameNoLimit);\n\n            // long paths can be enabled on Windows but it does not mean that everything is going to work fine..\n            // so we always use 260 as limit on Windows\n            int limit = OsDetector.IsWindows()\n                ? WindowsOldPathLimit - reserve\n                : CommonSenseLimit;\n\n            if (nameNoLimit.Length <= limit && fileNameOnly.Length <= MaxFileNameLength)\n            {\n                return nameNoLimit;\n            }\n\n            return GetLimitedFilePath(details, subfolder, creationTime, fileExtension, limit);\n        }\n\n        private static string GetFilePathNoLimits(DiagnoserActionParameters details, string? subfolder, DateTime? creationTime, string fileExtension)\n        {\n            string fileName = $@\"{FolderNameHelper.ToFolderName(details.BenchmarkCase.Descriptor.Type)}.{FullNameProvider.GetMethodName(details.BenchmarkCase)}\";\n\n            return GetFilePath(fileName, details, subfolder, creationTime, fileExtension);\n        }\n\n        private static string GetLimitedFilePath(DiagnoserActionParameters details, string? subfolder, DateTime? creationTime, string fileExtension, int limit)\n        {\n            string shortTypeName = FolderNameHelper.ToFolderName(details.BenchmarkCase.Descriptor.Type, includeNamespace: false);\n            string methodName = details.BenchmarkCase.Descriptor.WorkloadMethod.Name;\n            string parameters = details.BenchmarkCase.HasParameters\n                ? $\"-hash{Hashing.HashString(FullNameProvider.GetMethodName(details.BenchmarkCase))}\"\n                : string.Empty;\n\n            string fileName = $@\"{shortTypeName}.{methodName}{parameters}\";\n\n            string finalResult = GetFilePath(fileName, details, subfolder, creationTime, fileExtension);\n\n            if (finalResult.Length > limit)\n            {\n                throw new NotSupportedException($\"The full benchmark name: \\\"{fileName}\\\" combined with artifacts path: \\\"{details.Config.ArtifactsPath}\\\" is too long. \" +\n                   $\"Please set the value of {nameof(details.Config)}.{nameof(details.Config.ArtifactsPath)} to shorter path or rename the type or method.\");\n            }\n\n            return finalResult;\n        }\n\n        private static string GetFilePath(string fileName, DiagnoserActionParameters details, string? subfolder, DateTime? creationTime, string fileExtension)\n        {\n            // if we run for more than one toolchain, the output file name should contain the name too so we can differ net462 vs net8.0 etc\n            if (details.Config.GetJobs().Select(job => ToolchainExtensions.GetToolchain(job)).Distinct().Count() > 1)\n                fileName += $\"-{details.BenchmarkCase.Job.Environment.Runtime?.Name ?? details.BenchmarkCase.GetToolchain()?.Name ?? details.BenchmarkCase.Job.Id}\";\n\n            if (creationTime.HasValue)\n                fileName += $\"-{creationTime.Value.ToString(BenchmarkRunnerClean.DateTimeFormat)}\";\n\n            fileName = FolderNameHelper.ToFolderName(fileName);\n\n            if (!string.IsNullOrEmpty(fileExtension))\n                fileName = $\"{fileName}.{fileExtension}\";\n\n            return subfolder != null\n                ? Path.Combine(details.Config.ArtifactsPath, subfolder, fileName)\n                : Path.Combine(details.Config.ArtifactsPath, fileName);\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Helpers/AsciiHelper.cs",
    "content": "namespace BenchmarkDotNet.Helpers\n{\n    internal static class AsciiHelper\n    {\n        /// <summary>\n        /// The 'μ' symbol\n        /// </summary>\n        private const string Mu = \"\\u03BC\";\n\n        public static string ToAscii(this string s)\n        {\n            // We should replace all non-ASCII symbols that used in BenchmarkDotNet by ASCII-compatible analogues\n            return s.Replace(Mu, \"u\");\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Helpers/Assertion.cs",
    "content": "using System;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Helpers;\n\ninternal static class Assertion\n{\n    [AssertionMethod]\n    public static void NotNull(string name, object? value)\n    {\n        if (value == null)\n            throw new ArgumentNullException(name, $\"{name} can't be null\");\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Helpers/AwaitHelper.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Threading;\nusing System.Threading.Tasks;\n\nnamespace BenchmarkDotNet.Helpers\n{\n    public static class AwaitHelper\n    {\n        private class ValueTaskWaiter\n        {\n            // We use thread static field so that each thread uses its own individual callback and reset event.\n            [ThreadStatic]\n            private static ValueTaskWaiter? ts_current;\n            internal static ValueTaskWaiter Current => ts_current ??= new ValueTaskWaiter();\n\n            // We cache the callback to prevent allocations for memory diagnoser.\n            private readonly Action awaiterCallback;\n            private readonly ManualResetEventSlim resetEvent;\n\n            private ValueTaskWaiter()\n            {\n                resetEvent = new();\n                awaiterCallback = resetEvent.Set;\n            }\n\n            internal void Wait<TAwaiter>(TAwaiter awaiter) where TAwaiter : ICriticalNotifyCompletion\n            {\n                resetEvent.Reset();\n                awaiter.UnsafeOnCompleted(awaiterCallback);\n\n                // The fastest way to wait for completion is to spin a bit before waiting on the event. This is the same logic that Task.GetAwaiter().GetResult() uses.\n                var spinner = new SpinWait();\n                while (!resetEvent.IsSet)\n                {\n                    if (spinner.NextSpinWillYield)\n                    {\n                        resetEvent.Wait();\n                        return;\n                    }\n                    spinner.SpinOnce();\n                }\n            }\n        }\n\n        // we use GetAwaiter().GetResult() because it's fastest way to obtain the result in blocking way,\n        // and will eventually throw actual exception, not aggregated one\n        public static void GetResult(Task task) => task.GetAwaiter().GetResult();\n\n        public static T GetResult<T>(Task<T> task) => task.GetAwaiter().GetResult();\n\n        // ValueTask can be backed by an IValueTaskSource that only supports asynchronous awaits,\n        // so we have to hook up a callback instead of calling .GetAwaiter().GetResult() like we do for Task.\n        // The alternative is to convert it to Task using .AsTask(), but that causes allocations which we must avoid for memory diagnoser.\n        public static void GetResult(ValueTask task)\n        {\n            // Don't continue on the captured context, as that may result in a deadlock if the user runs this in-process.\n            var awaiter = task.ConfigureAwait(false).GetAwaiter();\n            if (!awaiter.IsCompleted)\n            {\n                ValueTaskWaiter.Current.Wait(awaiter);\n            }\n            awaiter.GetResult();\n        }\n\n        public static T GetResult<T>(ValueTask<T> task)\n        {\n            // Don't continue on the captured context, as that may result in a deadlock if the user runs this in-process.\n            var awaiter = task.ConfigureAwait(false).GetAwaiter();\n            if (!awaiter.IsCompleted)\n            {\n                ValueTaskWaiter.Current.Wait(awaiter);\n            }\n            return awaiter.GetResult();\n        }\n\n        internal static MethodInfo? GetGetResultMethod(Type taskType)\n        {\n            if (!taskType.IsGenericType)\n            {\n                return typeof(AwaitHelper).GetMethod(nameof(AwaitHelper.GetResult), BindingFlags.Public | BindingFlags.Static, null, new Type[1] { taskType }, null)!;\n            }\n\n            Type? compareType = taskType.GetGenericTypeDefinition() == typeof(ValueTask<>) ? typeof(ValueTask<>)\n                : typeof(Task).IsAssignableFrom(taskType.GetGenericTypeDefinition()) ? typeof(Task<>)\n                : null;\n            if (compareType == null)\n            {\n                return null;\n            }\n            var resultType = taskType\n                .GetMethod(nameof(Task.GetAwaiter), BindingFlags.Public | BindingFlags.Instance)!\n                .ReturnType\n                .GetMethod(nameof(TaskAwaiter.GetResult), BindingFlags.Public | BindingFlags.Instance)!\n                .ReturnType;\n            return typeof(AwaitHelper).GetMethods(BindingFlags.Public | BindingFlags.Static)\n                .First(m =>\n                {\n                    if (m.Name != nameof(AwaitHelper.GetResult)) return false;\n                    Type paramType = m.GetParameters().First().ParameterType;\n                    return paramType.IsGenericType && paramType.GetGenericTypeDefinition() == compareType;\n                })\n                .MakeGenericMethod(new[] { resultType });\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Helpers/CodeAnnotations.cs",
    "content": "﻿/* MIT License\n\nCopyright (c) 2016 JetBrains http://www.jetbrains.com\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE. */\n\n#nullable disable\n\nusing System;\n// ReSharper disable UnusedType.Global\n\n#pragma warning disable 1591\n// ReSharper disable UnusedMember.Global\n// ReSharper disable MemberCanBePrivate.Global\n// ReSharper disable UnusedAutoPropertyAccessor.Global\n// ReSharper disable IntroduceOptionalParameters.Global\n// ReSharper disable MemberCanBeProtected.Global\n// ReSharper disable InconsistentNaming\n\nnamespace JetBrains.Annotations\n{\n  /// <summary>\n  /// Indicates that the value of the marked element could be <c>null</c> sometimes,\n  /// so checking for <c>null</c> is required before its usage.\n  /// </summary>\n  /// <example><code>\n  /// [CanBeNull] object Test() => null;\n  ///\n  /// void UseTest() {\n  ///   var p = Test();\n  ///   var s = p.ToString(); // Warning: Possible 'System.NullReferenceException'\n  /// }\n  /// </code></example>\n  [AttributeUsage(\n    AttributeTargets.Method | AttributeTargets.Parameter | AttributeTargets.Property |\n    AttributeTargets.Delegate | AttributeTargets.Field | AttributeTargets.Event |\n    AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.GenericParameter)]\ninternal sealed class CanBeNullAttribute : Attribute { }\n\n  /// <summary>\n  /// Indicates that the value of the marked element can never be <c>null</c>.\n  /// </summary>\n  /// <example><code>\n  /// [NotNull] object Foo() {\n  ///   return null; // Warning: Possible 'null' assignment\n  /// }\n  /// </code></example>\n  [AttributeUsage(\n    AttributeTargets.Method | AttributeTargets.Parameter | AttributeTargets.Property |\n    AttributeTargets.Delegate | AttributeTargets.Field | AttributeTargets.Event |\n    AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.GenericParameter)]\ninternal sealed class NotNullAttribute : Attribute { }\n\n  /// <summary>\n  /// Can be applied to symbols of types derived from IEnumerable as well as to symbols of Task\n  /// and Lazy classes to indicate that the value of a collection item, of the Task.Result property\n  /// or of the Lazy.Value property can never be null.\n  /// </summary>\n  /// <example><code>\n  /// public void Foo([ItemNotNull]List&lt;string&gt; books)\n  /// {\n  ///   foreach (var book in books) {\n  ///     if (book != null) // Warning: Expression is always true\n  ///      Console.WriteLine(book.ToUpper());\n  ///   }\n  /// }\n  /// </code></example>\n  [AttributeUsage(\n    AttributeTargets.Method | AttributeTargets.Parameter | AttributeTargets.Property |\n    AttributeTargets.Delegate | AttributeTargets.Field)]\ninternal sealed class ItemNotNullAttribute : Attribute { }\n\n  /// <summary>\n  /// Can be applied to symbols of types derived from IEnumerable as well as to symbols of Task\n  /// and Lazy classes to indicate that the value of a collection item, of the Task.Result property\n  /// or of the Lazy.Value property can be null.\n  /// </summary>\n  /// <example><code>\n  /// public void Foo([ItemCanBeNull]List&lt;string&gt; books)\n  /// {\n  ///   foreach (var book in books)\n  ///   {\n  ///     // Warning: Possible 'System.NullReferenceException'\n  ///     Console.WriteLine(book.ToUpper());\n  ///   }\n  /// }\n  /// </code></example>\n  [AttributeUsage(\n    AttributeTargets.Method | AttributeTargets.Parameter | AttributeTargets.Property |\n    AttributeTargets.Delegate | AttributeTargets.Field)]\ninternal sealed class ItemCanBeNullAttribute : Attribute { }\n\n  /// <summary>\n  /// Indicates that the marked method builds a string by the format pattern and (optional) arguments.\n  /// The parameter, which contains the format string, should be given in the constructor. The format string\n  /// should be in <see cref=\"string.Format(IFormatProvider,string,object[])\"/>-like form.\n  /// </summary>\n  /// <example><code>\n  /// [StringFormatMethod(\"message\")]\n  /// void ShowError(string message, params object[] args) { /* do something */ }\n  ///\n  /// void Foo() {\n  ///   ShowError(\"Failed: {0}\"); // Warning: Non-existing argument in format string\n  /// }\n  /// </code></example>\n  [AttributeUsage(\n    AttributeTargets.Constructor | AttributeTargets.Method |\n    AttributeTargets.Property | AttributeTargets.Delegate)]\ninternal sealed class StringFormatMethodAttribute : Attribute\n  {\n    /// <param name=\"formatParameterName\">\n    /// Specifies which parameter of an annotated method should be treated as the format string.\n    /// </param>\n    public StringFormatMethodAttribute([NotNull] string formatParameterName)\n    {\n      FormatParameterName = formatParameterName;\n    }\n\n    [NotNull] public string FormatParameterName { get; }\n  }\n\n  /// <summary>\n  /// Indicates that the marked parameter is a message template where placeholders are to be replaced by the following arguments\n  /// in the order in which they appear.\n  /// </summary>\n  /// <example><code>\n  /// void LogInfo([StructuredMessageTemplate]string message, params object[] args) { /* do something */ }\n  ///\n  /// void Foo() {\n  ///   LogInfo(\"User created: {username}\"); // Warning: Non-existing argument in format string\n  /// }\n  /// </code></example>\n  [AttributeUsage(AttributeTargets.Parameter)]\ninternal sealed class StructuredMessageTemplateAttribute : Attribute {}\n\n  /// <summary>\n  /// Use this annotation to specify a type that contains static or const fields\n  /// with values for the annotated property/field/parameter.\n  /// The specified type will be used to improve completion suggestions.\n  /// </summary>\n  /// <example><code>\n  /// namespace TestNamespace\n  /// {\n  ///   public class Constants\n  ///   {\n  ///     public static int INT_CONST = 1;\n  ///     public const string STRING_CONST = \"1\";\n  ///   }\n  ///\n  ///   public class Class1\n  ///   {\n  ///     [ValueProvider(\"TestNamespace.Constants\")] public int myField;\n  ///     public void Foo([ValueProvider(\"TestNamespace.Constants\")] string str) { }\n  ///\n  ///     public void Test()\n  ///     {\n  ///       Foo(/*try completion here*/);//\n  ///       myField = /*try completion here*/\n  ///     }\n  ///   }\n  /// }\n  /// </code></example>\n  [AttributeUsage(\n    AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.Field,\n    AllowMultiple = true)]\ninternal sealed class ValueProviderAttribute : Attribute\n  {\n    public ValueProviderAttribute([NotNull] string name)\n    {\n      Name = name;\n    }\n\n    [NotNull] public string Name { get; }\n  }\n\n  /// <summary>\n  /// Indicates that the integral value falls into the specified interval.\n  /// It's allowed to specify multiple non-intersecting intervals.\n  /// Values of interval boundaries are inclusive.\n  /// </summary>\n  /// <example><code>\n  /// void Foo([ValueRange(0, 100)] int value) {\n  ///   if (value == -1) { // Warning: Expression is always 'false'\n  ///     ...\n  ///   }\n  /// }\n  /// </code></example>\n  [AttributeUsage(\n    AttributeTargets.Parameter | AttributeTargets.Field | AttributeTargets.Property |\n    AttributeTargets.Method | AttributeTargets.Delegate,\n    AllowMultiple = true)]\ninternal sealed class ValueRangeAttribute : Attribute\n  {\n    public object From { get; }\n    public object To { get; }\n\n    public ValueRangeAttribute(long from, long to)\n    {\n      From = from;\n      To = to;\n    }\n\n    public ValueRangeAttribute(ulong from, ulong to)\n    {\n      From = from;\n      To = to;\n    }\n\n    public ValueRangeAttribute(long value)\n    {\n      From = To = value;\n    }\n\n    public ValueRangeAttribute(ulong value)\n    {\n      From = To = value;\n    }\n  }\n\n  /// <summary>\n  /// Indicates that the integral value never falls below zero.\n  /// </summary>\n  /// <example><code>\n  /// void Foo([NonNegativeValue] int value) {\n  ///   if (value == -1) { // Warning: Expression is always 'false'\n  ///     ...\n  ///   }\n  /// }\n  /// </code></example>\n  [AttributeUsage(\n    AttributeTargets.Parameter | AttributeTargets.Field | AttributeTargets.Property |\n    AttributeTargets.Method | AttributeTargets.Delegate)]\ninternal sealed class NonNegativeValueAttribute : Attribute { }\n\n  /// <summary>\n  /// Indicates that the function argument should be a string literal and match\n  /// one of the parameters of the caller function. This annotation is used for parameters\n  /// like 'string paramName' parameter of the <see cref=\"System.ArgumentNullException\"/> constructor.\n  /// </summary>\n  /// <example><code>\n  /// void Foo(string param) {\n  ///   if (param == null)\n  ///     throw new ArgumentNullException(\"par\"); // Warning: Cannot resolve symbol\n  /// }\n  /// </code></example>\n  [AttributeUsage(AttributeTargets.Parameter)]\ninternal sealed class InvokerParameterNameAttribute : Attribute { }\n\n  /// <summary>\n  /// Indicates that the method is contained in a type that implements\n  /// <c>System.ComponentModel.INotifyPropertyChanged</c> interface and this method\n  /// is used to notify that some property value changed.\n  /// </summary>\n  /// <remarks>\n  /// The method should be non-static and conform to one of the supported signatures:\n  /// <list>\n  /// <item><c>NotifyChanged(string)</c></item>\n  /// <item><c>NotifyChanged(params string[])</c></item>\n  /// <item><c>NotifyChanged{T}(Expression{Func{T}})</c></item>\n  /// <item><c>NotifyChanged{T,U}(Expression{Func{T,U}})</c></item>\n  /// <item><c>SetProperty{T}(ref T, T, string)</c></item>\n  /// </list>\n  /// </remarks>\n  /// <example><code>\n  /// public class Foo : INotifyPropertyChanged {\n  ///   public event PropertyChangedEventHandler PropertyChanged;\n  ///\n  ///   [NotifyPropertyChangedInvocator]\n  ///   protected virtual void NotifyChanged(string propertyName) { ... }\n  ///\n  ///   string _name;\n  ///\n  ///   public string Name {\n  ///     get { return _name; }\n  ///     set { _name = value; NotifyChanged(\"LastName\"); /* Warning */ }\n  ///   }\n  /// }\n  /// </code>\n  /// Examples of generated notifications:\n  /// <list>\n  /// <item><c>NotifyChanged(\"Property\")</c></item>\n  /// <item><c>NotifyChanged(() =&gt; Property)</c></item>\n  /// <item><c>NotifyChanged((VM x) =&gt; x.Property)</c></item>\n  /// <item><c>SetProperty(ref myField, value, \"Property\")</c></item>\n  /// </list>\n  /// </example>\n  [AttributeUsage(AttributeTargets.Method)]\ninternal sealed class NotifyPropertyChangedInvocatorAttribute : Attribute\n  {\n    public NotifyPropertyChangedInvocatorAttribute() { }\n    public NotifyPropertyChangedInvocatorAttribute([NotNull] string parameterName)\n    {\n      ParameterName = parameterName;\n    }\n\n    [CanBeNull] public string ParameterName { get; }\n  }\n\n  /// <summary>\n  /// Describes dependence between method input and output.\n  /// </summary>\n  /// <syntax>\n  /// <p>Function Definition Table syntax:</p>\n  /// <list>\n  /// <item>FDT      ::= FDTRow [;FDTRow]*</item>\n  /// <item>FDTRow   ::= Input =&gt; Output | Output &lt;= Input</item>\n  /// <item>Input    ::= ParameterName: Value [, Input]*</item>\n  /// <item>Output   ::= [ParameterName: Value]* {halt|stop|void|nothing|Value}</item>\n  /// <item>Value    ::= true | false | null | notnull | canbenull</item>\n  /// </list>\n  /// If the method has a single input parameter, its name could be omitted.<br/>\n  /// Using <c>halt</c> (or <c>void</c>/<c>nothing</c>, which is the same) for the method output\n  /// means that the method doesn't return normally (throws or terminates the process).<br/>\n  /// Value <c>canbenull</c> is only applicable for output parameters.<br/>\n  /// You can use multiple <c>[ContractAnnotation]</c> for each FDT row, or use single attribute\n  /// with rows separated by the semicolon. There is no notion of order rows, all rows are checked\n  /// for applicability and applied per each program state tracked by the analysis engine.<br/>\n  /// </syntax>\n  /// <examples><list>\n  /// <item><code>\n  /// [ContractAnnotation(\"=&gt; halt\")]\n  /// public void TerminationMethod()\n  /// </code></item>\n  /// <item><code>\n  /// [ContractAnnotation(\"null &lt;= param:null\")] // reverse condition syntax\n  /// public string GetName(string surname)\n  /// </code></item>\n  /// <item><code>\n  /// [ContractAnnotation(\"s:null =&gt; true\")]\n  /// public bool IsNullOrEmpty(string s) // string.IsNullOrEmpty()\n  /// </code></item>\n  /// <item><code>\n  /// // A method that returns null if the parameter is null,\n  /// // and not null if the parameter is not null\n  /// [ContractAnnotation(\"null =&gt; null; notnull =&gt; notnull\")]\n  /// public object Transform(object data)\n  /// </code></item>\n  /// <item><code>\n  /// [ContractAnnotation(\"=&gt; true, result: notnull; =&gt; false, result: null\")]\n  /// public bool TryParse(string s, out Person result)\n  /// </code></item>\n  /// </list></examples>\n  [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]\ninternal sealed class ContractAnnotationAttribute : Attribute\n  {\n    public ContractAnnotationAttribute([NotNull] string contract)\n      : this(contract, false) { }\n\n    public ContractAnnotationAttribute([NotNull] string contract, bool forceFullStates)\n    {\n      Contract = contract;\n      ForceFullStates = forceFullStates;\n    }\n\n    [NotNull] public string Contract { get; }\n\n    public bool ForceFullStates { get; }\n  }\n\n  /// <summary>\n  /// Indicates whether the marked element should be localized.\n  /// </summary>\n  /// <example><code>\n  /// [LocalizationRequiredAttribute(true)]\n  /// class Foo {\n  ///   string str = \"my string\"; // Warning: Localizable string\n  /// }\n  /// </code></example>\n  [AttributeUsage(AttributeTargets.All)]\ninternal sealed class LocalizationRequiredAttribute : Attribute\n  {\n    public LocalizationRequiredAttribute() : this(true) { }\n\n    public LocalizationRequiredAttribute(bool required)\n    {\n      Required = required;\n    }\n\n    public bool Required { get; }\n  }\n\n  /// <summary>\n  /// Indicates that the value of the marked type (or its derivatives)\n  /// cannot be compared using '==' or '!=' operators and <c>Equals()</c>\n  /// should be used instead. However, using '==' or '!=' for comparison\n  /// with <c>null</c> is always permitted.\n  /// </summary>\n  /// <example><code>\n  /// [CannotApplyEqualityOperator]\n  /// class NoEquality { }\n  ///\n  /// class UsesNoEquality {\n  ///   void Test() {\n  ///     var ca1 = new NoEquality();\n  ///     var ca2 = new NoEquality();\n  ///     if (ca1 != null) { // OK\n  ///       bool condition = ca1 == ca2; // Warning\n  ///     }\n  ///   }\n  /// }\n  /// </code></example>\n  [AttributeUsage(AttributeTargets.Interface | AttributeTargets.Class | AttributeTargets.Struct)]\ninternal sealed class CannotApplyEqualityOperatorAttribute : Attribute { }\n\n  /// <summary>\n  /// When applied to a target attribute, specifies a requirement for any type marked\n  /// with the target attribute to implement or inherit the specific type or types.\n  /// </summary>\n  /// <example><code>\n  /// [BaseTypeRequired(typeof(IComponent)] // Specify requirement\n  /// class ComponentAttribute : Attribute { }\n  ///\n  /// [Component] // ComponentAttribute requires implementing IComponent interface\n  /// class MyComponent : IComponent { }\n  /// </code></example>\n  [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]\n  [BaseTypeRequired(typeof(Attribute))]\ninternal sealed class BaseTypeRequiredAttribute : Attribute\n  {\n    public BaseTypeRequiredAttribute([NotNull] Type baseType)\n    {\n      BaseType = baseType;\n    }\n\n    [NotNull] public Type BaseType { get; }\n  }\n\n  /// <summary>\n  /// Indicates that the marked symbol is used implicitly (e.g. via reflection, in external library),\n  /// so this symbol will be ignored by usage-checking inspections. <br/>\n  /// You can use <see cref=\"ImplicitUseKindFlags\"/> and <see cref=\"ImplicitUseTargetFlags\"/>\n  /// to configure how this attribute is applied.\n  /// </summary>\n  /// <example><code>\n  /// [UsedImplicitly]\n  /// public class TypeConverter {}\n  ///\n  /// public class SummaryData\n  /// {\n  ///   [UsedImplicitly(ImplicitUseKindFlags.InstantiatedWithFixedConstructorSignature)]\n  ///   public SummaryData() {}\n  /// }\n  ///\n  /// [UsedImplicitly(ImplicitUseTargetFlags.WithInheritors | ImplicitUseTargetFlags.Default)]\n  /// public interface IService {}\n  /// </code></example>\n  [AttributeUsage(AttributeTargets.All)]\ninternal sealed class UsedImplicitlyAttribute : Attribute\n  {\n    public UsedImplicitlyAttribute()\n      : this(ImplicitUseKindFlags.Default, ImplicitUseTargetFlags.Default) { }\n\n    public UsedImplicitlyAttribute(ImplicitUseKindFlags useKindFlags)\n      : this(useKindFlags, ImplicitUseTargetFlags.Default) { }\n\n    public UsedImplicitlyAttribute(ImplicitUseTargetFlags targetFlags)\n      : this(ImplicitUseKindFlags.Default, targetFlags) { }\n\n    public UsedImplicitlyAttribute(ImplicitUseKindFlags useKindFlags, ImplicitUseTargetFlags targetFlags)\n    {\n      UseKindFlags = useKindFlags;\n      TargetFlags = targetFlags;\n    }\n\n    public ImplicitUseKindFlags UseKindFlags { get; }\n\n    public ImplicitUseTargetFlags TargetFlags { get; }\n  }\n\n  /// <summary>\n  /// Can be applied to attributes, type parameters, and parameters of a type assignable from <see cref=\"System.Type\"/> .\n  /// When applied to an attribute, the decorated attribute behaves the same as <see cref=\"UsedImplicitlyAttribute\"/>.\n  /// When applied to a type parameter or to a parameter of type <see cref=\"System.Type\"/>,\n  /// indicates that the corresponding type is used implicitly.\n  /// </summary>\n  [AttributeUsage(AttributeTargets.Class | AttributeTargets.GenericParameter | AttributeTargets.Parameter)]\ninternal sealed class MeansImplicitUseAttribute : Attribute\n  {\n    public MeansImplicitUseAttribute()\n      : this(ImplicitUseKindFlags.Default, ImplicitUseTargetFlags.Default) { }\n\n    public MeansImplicitUseAttribute(ImplicitUseKindFlags useKindFlags)\n      : this(useKindFlags, ImplicitUseTargetFlags.Default) { }\n\n    public MeansImplicitUseAttribute(ImplicitUseTargetFlags targetFlags)\n      : this(ImplicitUseKindFlags.Default, targetFlags) { }\n\n    public MeansImplicitUseAttribute(ImplicitUseKindFlags useKindFlags, ImplicitUseTargetFlags targetFlags)\n    {\n      UseKindFlags = useKindFlags;\n      TargetFlags = targetFlags;\n    }\n\n    [UsedImplicitly] public ImplicitUseKindFlags UseKindFlags { get; }\n\n    [UsedImplicitly] public ImplicitUseTargetFlags TargetFlags { get; }\n  }\n\n  /// <summary>\n  /// Specifies the details of an implicitly used symbol when it is marked\n  /// with <see cref=\"MeansImplicitUseAttribute\"/> or <see cref=\"UsedImplicitlyAttribute\"/>.\n  /// </summary>\n  [Flags]\ninternal enum ImplicitUseKindFlags\n  {\n    Default = Access | Assign | InstantiatedWithFixedConstructorSignature,\n    /// <summary>Only entity marked with attribute considered used.</summary>\n    Access = 1,\n    /// <summary>Indicates implicit assignment to a member.</summary>\n    Assign = 2,\n    /// <summary>\n    /// Indicates implicit instantiation of a type with fixed constructor signature.\n    /// That means any unused constructor parameters won't be reported as such.\n    /// </summary>\n    InstantiatedWithFixedConstructorSignature = 4,\n    /// <summary>Indicates implicit instantiation of a type.</summary>\n    InstantiatedNoFixedConstructorSignature = 8,\n  }\n\n  /// <summary>\n  /// Specifies what is considered to be used implicitly when marked\n  /// with <see cref=\"MeansImplicitUseAttribute\"/> or <see cref=\"UsedImplicitlyAttribute\"/>.\n  /// </summary>\n  [Flags]\ninternal enum ImplicitUseTargetFlags\n  {\n    Default = Itself,\n    Itself = 1,\n    /// <summary>Members of the type marked with the attribute are considered used.</summary>\n    Members = 2,\n    /// <summary> Inherited entities are considered used. </summary>\n    WithInheritors = 4,\n    /// <summary>Entity marked with the attribute and all its members considered used.</summary>\n    WithMembers = Itself | Members\n  }\n\n  /// <summary>\n  /// This attribute is intended to mark publicly available APIs,\n  /// which should not be removed and so is treated as used.\n  /// </summary>\n  [MeansImplicitUse(ImplicitUseTargetFlags.WithMembers)]\n  [AttributeUsage(AttributeTargets.All, Inherited = false)]\ninternal sealed class PublicAPIAttribute : Attribute\n  {\n    public PublicAPIAttribute() { }\n\n    public PublicAPIAttribute([NotNull] string comment)\n    {\n      Comment = comment;\n    }\n\n    [CanBeNull] public string Comment { get; }\n  }\n\n  /// <summary>\n  /// Tells the code analysis engine if the parameter is completely handled when the invoked method is on stack.\n  /// If the parameter is a delegate, indicates that the delegate can only be invoked during method execution\n  /// (the delegate can be invoked zero or multiple times, but not stored to some field and invoked later,\n  /// when the containing method is no longer on the execution stack).\n  /// If the parameter is an enumerable, indicates that it is enumerated while the method is executed.\n  /// If <see cref=\"RequireAwait\"/> is true, the attribute will only take effect if the method invocation is located under the 'await' expression.\n  /// </summary>\n  [AttributeUsage(AttributeTargets.Parameter)]\ninternal sealed class InstantHandleAttribute : Attribute\n  {\n    /// <summary>\n    /// Require the method invocation to be used under the 'await' expression for this attribute to take effect on the code analysis engine.\n    /// Can be used for delegate/enumerable parameters of 'async' methods.\n    /// </summary>\n    public bool RequireAwait { get; set; }\n  }\n\n  /// <summary>\n  /// Indicates that a method does not make any observable state changes.\n  /// The same as <c>System.Diagnostics.Contracts.PureAttribute</c>.\n  /// </summary>\n  /// <example><code>\n  /// [Pure] int Multiply(int x, int y) => x * y;\n  ///\n  /// void M() {\n  ///   Multiply(123, 42); // Warning: Return value of pure method is not used\n  /// }\n  /// </code></example>\n  [AttributeUsage(AttributeTargets.Method)]\ninternal sealed class PureAttribute : Attribute { }\n\n  /// <summary>\n  /// Indicates that the return value of the method invocation must be used.\n  /// </summary>\n  /// <remarks>\n  /// Methods decorated with this attribute (in contrast to pure methods) might change state,\n  /// but make no sense without using their return value. <br/>\n  /// Similarly to <see cref=\"PureAttribute\"/>, this attribute\n  /// will help to detect usages of the method when the return value is not used.\n  /// Optionally, you can specify a message to use when showing warnings, e.g.\n  /// <code>[MustUseReturnValue(\"Use the return value to...\")]</code>.\n  /// </remarks>\n  [AttributeUsage(AttributeTargets.Method)]\ninternal sealed class MustUseReturnValueAttribute : Attribute\n  {\n    public MustUseReturnValueAttribute() { }\n\n    public MustUseReturnValueAttribute([NotNull] string justification)\n    {\n      Justification = justification;\n    }\n\n    [CanBeNull] public string Justification { get; }\n  }\n\n  /// <summary>\n  /// This annotation allows to enforce allocation-less usage patterns of delegates for performance-critical APIs.\n  /// When this annotation is applied to the parameter of delegate type, the IDE checks the input argument of this parameter:\n  /// * When a lambda expression or anonymous method is passed as an argument, the IDE verifies that the passed closure\n  ///   has no captures of the containing local variables and the compiler is able to cache the delegate instance\n  ///   to avoid heap allocations. Otherwise a warning is produced.\n  /// * The IDE warns when the method name or local function name is passed as an argument as this always results\n  ///   in heap allocation of the delegate instance.\n  /// </summary>\n  /// <remarks>\n  /// In C# 9.0+ code, the IDE will also suggest to annotate the anonymous function with the 'static' modifier\n  /// to make use of the similar analysis provided by the language/compiler.\n  /// </remarks>\n  [AttributeUsage(AttributeTargets.Parameter)]\ninternal sealed class RequireStaticDelegateAttribute : Attribute\n  {\n    public bool IsError { get; set; }\n  }\n\n  /// <summary>\n  /// Indicates the type member or parameter of some type that should be used instead of all other ways\n  /// to get the value of that type. This annotation is useful when you have some \"context\" value evaluated\n  /// and stored somewhere, meaning that all other ways to get this value must be consolidated with the existing one.\n  /// </summary>\n  /// <example><code>\n  /// class Foo {\n  ///   [ProvidesContext] IBarService _barService = ...;\n  ///\n  ///   void ProcessNode(INode node) {\n  ///     DoSomething(node, node.GetGlobalServices().Bar);\n  ///     //              ^ Warning: use value of '_barService' field\n  ///   }\n  /// }\n  /// </code></example>\n  [AttributeUsage(\n    AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Parameter | AttributeTargets.Method |\n    AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Struct | AttributeTargets.GenericParameter)]\ninternal sealed class ProvidesContextAttribute : Attribute { }\n\n  /// <summary>\n  /// Indicates that a parameter is a path to a file or a folder within a web project.\n  /// Path can be relative or absolute, starting from web root (~).\n  /// </summary>\n  [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Field | AttributeTargets.Property)]\ninternal sealed class PathReferenceAttribute : Attribute\n  {\n    public PathReferenceAttribute() { }\n\n    public PathReferenceAttribute([NotNull, PathReference] string basePath)\n    {\n      BasePath = basePath;\n    }\n\n    [CanBeNull] public string BasePath { get; }\n  }\n\n  /// <summary>\n  /// An extension method marked with this attribute is processed by code completion\n  /// as a 'Source Template'. When the extension method is completed over some expression, its source code\n  /// is automatically expanded like a template at the call site.\n  /// </summary>\n  /// <remarks>\n  /// Template method bodies can contain valid source code and/or special comments starting with '$'.\n  /// Text inside these comments is added as source code when the template is applied. Template parameters\n  /// can be used either as additional method parameters or as identifiers wrapped in two '$' signs.\n  /// Use the <see cref=\"MacroAttribute\"/> attribute to specify macros for parameters.\n  /// </remarks>\n  /// <example>\n  /// In this example, the 'forEach' method is a source template available over all values\n  /// of enumerable types, producing ordinary C# 'foreach' statement and placing the caret inside the block:\n  /// <code>\n  /// [SourceTemplate]\n  /// public static void forEach&lt;T&gt;(this IEnumerable&lt;T&gt; xs) {\n  ///   foreach (var x in xs) {\n  ///      //$ $END$\n  ///   }\n  /// }\n  /// </code>\n  /// </example>\n  [AttributeUsage(AttributeTargets.Method)]\ninternal sealed class SourceTemplateAttribute : Attribute { }\n\n  /// <summary>\n  /// Allows specifying a macro for a parameter of a <see cref=\"SourceTemplateAttribute\">source template</see>.\n  /// </summary>\n  /// <remarks>\n  /// You can apply the attribute on the whole method or on any of its additional parameters. The macro expression\n  /// is defined in the <see cref=\"MacroAttribute.Expression\"/> property. When applied on a method, the target\n  /// template parameter is defined in the <see cref=\"MacroAttribute.Target\"/> property. To apply the macro silently\n  /// for the parameter, set the <see cref=\"MacroAttribute.Editable\"/> property value to -1.\n  /// </remarks>\n  /// <example>\n  /// Applying the attribute on a source template method:\n  /// <code>\n  /// [SourceTemplate, Macro(Target = \"item\", Expression = \"suggestVariableName()\")]\n  /// public static void forEach&lt;T&gt;(this IEnumerable&lt;T&gt; collection) {\n  ///   foreach (var item in collection) {\n  ///     //$ $END$\n  ///   }\n  /// }\n  /// </code>\n  /// Applying the attribute on a template method parameter:\n  /// <code>\n  /// [SourceTemplate]\n  /// public static void something(this Entity x, [Macro(Expression = \"guid()\", Editable = -1)] string newguid) {\n  ///   /*$ var $x$Id = \"$newguid$\" + x.ToString();\n  ///   x.DoSomething($x$Id); */\n  /// }\n  /// </code>\n  /// </example>\n  [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method, AllowMultiple = true)]\ninternal sealed class MacroAttribute : Attribute\n  {\n    /// <summary>\n    /// Allows specifying a macro that will be executed for a <see cref=\"SourceTemplateAttribute\">source template</see>\n    /// parameter when the template is expanded.\n    /// </summary>\n    [CanBeNull] public string Expression { get; set; }\n\n    /// <summary>\n    /// Allows specifying which occurrence of the target parameter becomes editable when the template is deployed.\n    /// </summary>\n    /// <remarks>\n    /// If the target parameter is used several times in the template, only one occurrence becomes editable;\n    /// other occurrences are changed synchronously. To specify the zero-based index of the editable occurrence,\n    /// use values >= 0. To make the parameter non-editable when the template is expanded, use -1.\n    /// </remarks>\n    public int Editable { get; set; }\n\n    /// <summary>\n    /// Identifies the target parameter of a <see cref=\"SourceTemplateAttribute\">source template</see> if the\n    /// <see cref=\"MacroAttribute\"/> is applied on a template method.\n    /// </summary>\n    [CanBeNull] public string Target { get; set; }\n  }\n\n  /// <summary>\n  /// Indicates how a method, constructor invocation, or property access\n  /// over a collection type affects the contents of the collection.\n  /// When applied to a return value of a method, indicates if the returned collection\n  /// is created exclusively for the caller (CollectionAccessType.UpdatedContent) or\n  /// can be read/updated from outside (CollectionAccessType.Read | CollectionAccessType.UpdatedContent)\n  /// Use <see cref=\"CollectionAccessType\"/> to specify the access type.\n  /// </summary>\n  /// <remarks>\n  /// Using this attribute only makes sense if all collection methods are marked with this attribute.\n  /// </remarks>\n  /// <example><code>\n  /// public class MyStringCollection : List&lt;string&gt;\n  /// {\n  ///   [CollectionAccess(CollectionAccessType.Read)]\n  ///   public string GetFirstString()\n  ///   {\n  ///     return this.ElementAt(0);\n  ///   }\n  /// }\n  /// class Test\n  /// {\n  ///   public void Foo()\n  ///   {\n  ///     // Warning: Contents of the collection is never updated\n  ///     var col = new MyStringCollection();\n  ///     string x = col.GetFirstString();\n  ///   }\n  /// }\n  /// </code></example>\n  [AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Property | AttributeTargets.ReturnValue)]\ninternal sealed class CollectionAccessAttribute : Attribute\n  {\n    public CollectionAccessAttribute(CollectionAccessType collectionAccessType)\n    {\n      CollectionAccessType = collectionAccessType;\n    }\n\n    public CollectionAccessType CollectionAccessType { get; }\n  }\n\n  /// <summary>\n  /// Provides a value for the <see cref=\"CollectionAccessAttribute\"/> to define\n  /// how the collection method invocation affects the contents of the collection.\n  /// </summary>\n  [Flags]\ninternal enum CollectionAccessType\n  {\n    /// <summary>Method does not use or modify content of the collection.</summary>\n    None = 0,\n    /// <summary>Method only reads content of the collection but does not modify it.</summary>\n    Read = 1,\n    /// <summary>Method can change content of the collection but does not add new elements.</summary>\n    ModifyExistingContent = 2,\n    /// <summary>Method can add new elements to the collection.</summary>\n    UpdatedContent = ModifyExistingContent | 4\n  }\n\n  /// <summary>\n  /// Indicates that the marked method is an assertion method, i.e. it halts the control flow if\n  /// one of the conditions is satisfied. To set the condition, mark one of the parameters with\n  /// <see cref=\"AssertionConditionAttribute\"/> attribute.\n  /// </summary>\n  [AttributeUsage(AttributeTargets.Method)]\ninternal sealed class AssertionMethodAttribute : Attribute { }\n\n  /// <summary>\n  /// Indicates the condition parameter of the assertion method. The method itself should be\n  /// marked by the <see cref=\"AssertionMethodAttribute\"/> attribute. The mandatory argument of\n  /// the attribute is the assertion type.\n  /// </summary>\n  [AttributeUsage(AttributeTargets.Parameter)]\ninternal sealed class AssertionConditionAttribute : Attribute\n  {\n    public AssertionConditionAttribute(AssertionConditionType conditionType)\n    {\n      ConditionType = conditionType;\n    }\n\n    public AssertionConditionType ConditionType { get; }\n  }\n\n  /// <summary>\n  /// Specifies the assertion type. If the assertion method argument satisfies the condition,\n  /// then the execution continues. Otherwise, execution is assumed to be halted.\n  /// </summary>\ninternal enum AssertionConditionType\n  {\n    /// <summary>Marked parameter should be evaluated to true.</summary>\n    IS_TRUE = 0,\n    /// <summary>Marked parameter should be evaluated to false.</summary>\n    IS_FALSE = 1,\n    /// <summary>Marked parameter should be evaluated to null value.</summary>\n    IS_NULL = 2,\n    /// <summary>Marked parameter should be evaluated to not null value.</summary>\n    IS_NOT_NULL = 3,\n  }\n\n  /// <summary>\n  /// Indicates that the marked method unconditionally terminates control flow execution.\n  /// For example, it could unconditionally throw an exception.\n  /// </summary>\n  [Obsolete(\"Use [ContractAnnotation('=> halt')] instead\")]\n  [AttributeUsage(AttributeTargets.Method)]\ninternal sealed class TerminatesProgramAttribute : Attribute { }\n\n  /// <summary>\n  /// Indicates that the method is a pure LINQ method, with postponed enumeration (like Enumerable.Select,\n  /// .Where). This annotation allows inference of [InstantHandle] annotation for parameters\n  /// of delegate type by analyzing LINQ method chains.\n  /// </summary>\n  [AttributeUsage(AttributeTargets.Method)]\ninternal sealed class LinqTunnelAttribute : Attribute { }\n\n  /// <summary>\n  /// Indicates that IEnumerable passed as a parameter is not enumerated.\n  /// Use this annotation to suppress the 'Possible multiple enumeration of IEnumerable' inspection.\n  /// </summary>\n  /// <example><code>\n  /// static void ThrowIfNull&lt;T&gt;([NoEnumeration] T v, string n) where T : class\n  /// {\n  ///   // custom check for null but no enumeration\n  /// }\n  ///\n  /// void Foo(IEnumerable&lt;string&gt; values)\n  /// {\n  ///   ThrowIfNull(values, nameof(values));\n  ///   var x = values.ToList(); // No warnings about multiple enumeration\n  /// }\n  /// </code></example>\n  [AttributeUsage(AttributeTargets.Parameter)]\ninternal sealed class NoEnumerationAttribute : Attribute { }\n\n  /// <summary>\n  /// Indicates that the marked parameter, field, or property is a regular expression pattern.\n  /// </summary>\n  [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Field | AttributeTargets.Property)]\ninternal sealed class RegexPatternAttribute : Attribute { }\n\n  /// <summary>\n  /// Language of injected code fragment inside marked by the <see cref=\"LanguageInjectionAttribute\"/> string literal.\n  /// </summary>\ninternal enum InjectedLanguage\n  {\n    CSS,\n    HTML,\n    JAVASCRIPT,\n    JSON,\n    XML\n  }\n\n  /// <summary>\n  /// Indicates that the marked parameter, field, or property is accepting a string literal\n  /// containing code fragments in a specified language.\n  /// </summary>\n  /// <example><code>\n  /// void Foo([LanguageInjection(InjectedLanguage.CSS, Prefix = \"body{\", Suffix = \"}\")] string cssProps)\n  /// {\n  ///   // cssProps should only contains a list of CSS properties\n  /// }\n  /// </code></example>\n  /// <example><code>\n  /// void Bar([LanguageInjection(\"json\")] string json)\n  /// {\n  /// }\n  /// </code></example>\n  [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Field | AttributeTargets.Property)]\ninternal sealed class LanguageInjectionAttribute : Attribute\n  {\n    public LanguageInjectionAttribute(InjectedLanguage injectedLanguage)\n    {\n      InjectedLanguage = injectedLanguage;\n    }\n\n    public LanguageInjectionAttribute([NotNull] string injectedLanguage)\n    {\n      InjectedLanguageName = injectedLanguage;\n    }\n\n    /// <summary>Specifies a language of the injected code fragment.</summary>\n    public InjectedLanguage InjectedLanguage { get; }\n\n    /// <summary>Specifies a language name of the injected code fragment.</summary>\n    [CanBeNull] public string InjectedLanguageName { get; }\n\n    /// <summary>Specifies a string that \"precedes\" the injected string literal.</summary>\n    [CanBeNull] public string Prefix { get; set; }\n\n    /// <summary>Specifies a string that \"follows\" the injected string literal.</summary>\n    [CanBeNull] public string Suffix { get; set; }\n  }\n\n  /// <summary>\n  /// Prevents the Member Reordering feature from tossing members of the marked class.\n  /// </summary>\n  /// <remarks>\n  /// The attribute must be mentioned in your member reordering patterns.\n  /// </remarks>\n  [AttributeUsage(\n    AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Struct | AttributeTargets.Enum)]\ninternal sealed class NoReorderAttribute : Attribute { }\n\n  /// <summary>\n  /// <para>\n  /// Defines the code search template using the Structural Search and Replace syntax.\n  /// It allows you to find and, if necessary, replace blocks of code that match a specific pattern.\n  /// Search and replace patterns consist of a textual part and placeholders.\n  /// Textural part must contain only identifiers allowed in the target language and will be matched exactly (white spaces, tabulation characters, and line breaks are ignored).\n  /// Placeholders allow matching variable parts of the target code blocks.\n  /// A placeholder has the following format: $placeholder_name$- where placeholder_name is an arbitrary identifier.\n  /// </para>\n  /// <para>\n  /// Available placeholders:\n  /// <list type=\"bullet\">\n  /// <item>$this$ - expression of containing type</item>\n  /// <item>$thisType$ - containing type</item>\n  /// <item>$member$ - current member placeholder</item>\n  /// <item>$qualifier$ - this placeholder is available in the replace pattern and can be used to insert a qualifier expression matched by the $member$ placeholder.\n  /// (Note that if $qualifier$ placeholder is used, then $member$ placeholder will match only qualified references)</item>\n  /// <item>$expression$ - expression of any type</item>\n  /// <item>$identifier$ - identifier placeholder</item>\n  /// <item>$args$ - any number of arguments</item>\n  /// <item>$arg$ - single argument</item>\n  /// <item>$arg1$ ... $arg10$ - single argument</item>\n  /// <item>$stmts$ - any number of statements</item>\n  /// <item>$stmt$ - single statement</item>\n  /// <item>$stmt1$ ... $stmt10$ - single statement</item>\n  /// <item>$name{Expression, 'Namespace.FooType'}$ - expression with 'Namespace.FooType' type</item>\n  /// <item>$expression{'Namespace.FooType'}$ - expression with 'Namespace.FooType' type</item>\n  /// <item>$name{Type, 'Namespace.FooType'}$ - 'Namespace.FooType' type</item>\n  /// <item>$type{'Namespace.FooType'}$ - 'Namespace.FooType' type</item>\n  /// <item>$statement{1,2}$ - 1 or 2 statements</item>\n  /// </list>\n  /// </para>\n  /// <para>\n  /// Note that you can also define your own placeholders of the supported types and specify arguments for each placeholder type.\n  /// This can be done using the following format: $name{type, arguments}$. Where 'name' - is the name of your placeholder,\n  /// 'type' - is the type of your placeholder (one of the following: Expression, Type, Identifier, Statement, Argument, Member),\n  /// 'arguments' - arguments list for your placeholder. Each placeholder type supports its own arguments, check examples below for more details.\n  /// The placeholder type may be omitted and determined from the placeholder name, if the name has one of the following prefixes:\n  /// <list type=\"bullet\">\n  /// <item>expr, expression - expression placeholder, e.g. $exprPlaceholder{}$, $expressionFoo{}$</item>\n  /// <item>arg, argument - argument placeholder, e.g. $argPlaceholder{}$, $argumentFoo{}$</item>\n  /// <item>ident, identifier - identifier placeholder, e.g. $identPlaceholder{}$, $identifierFoo{}$</item>\n  /// <item>stmt, statement - statement placeholder, e.g. $stmtPlaceholder{}$, $statementFoo{}$</item>\n  /// <item>type - type placeholder, e.g. $typePlaceholder{}$, $typeFoo{}$</item>\n  /// <item>member - member placeholder, e.g. $memberPlaceholder{}$, $memberFoo{}$</item>\n  /// </list>\n  /// </para>\n  /// <para>\n  /// Expression placeholder arguments:\n  /// <list type=\"bullet\">\n  /// <item>expressionType - string value in single quotes, specifies full type name to match (empty string by default)</item>\n  /// <item>exactType - boolean value, specifies if expression should have exact type match (false by default)</item>\n  /// </list>\n  /// Examples:\n  /// <list type=\"bullet\">\n  /// <item>$myExpr{Expression, 'Namespace.FooType', true}$ - defines expression placeholder, matching expressions of the 'Namespace.FooType' type with exact matching.</item>\n  /// <item>$myExpr{Expression, 'Namespace.FooType'}$ - defines expression placeholder, matching expressions of the 'Namespace.FooType' type or expressions which can be implicitly converted to 'Namespace.FooType'.</item>\n  /// <item>$myExpr{Expression}$ - defines expression placeholder, matching expressions of any type.</item>\n  /// <item>$exprFoo{'Namespace.FooType', true}$ - defines expression placeholder, matching expressions of the 'Namespace.FooType' type with exact matching.</item>\n  /// </list>\n  /// </para>\n  /// <para>\n  /// Type placeholder arguments:\n  /// <list type=\"bullet\">\n  /// <item>type - string value in single quotes, specifies full type name to match (empty string by default)</item>\n  /// <item>exactType - boolean value, specifies if expression should have exact type match (false by default)</item>\n  /// </list>\n  /// Examples:\n  /// <list type=\"bullet\">\n  /// <item>$myType{Type, 'Namespace.FooType', true}$ - defines type placeholder, matching 'Namespace.FooType' types with exact matching.</item>\n  /// <item>$myType{Type, 'Namespace.FooType'}$ - defines type placeholder, matching 'Namespace.FooType' types or types, which can be implicitly converted to 'Namespace.FooType'.</item>\n  /// <item>$myType{Type}$ - defines type placeholder, matching any type.</item>\n  /// <item>$typeFoo{'Namespace.FooType', true}$ - defines types placeholder, matching 'Namespace.FooType' types with exact matching.</item>\n  /// </list>\n  /// </para>\n  /// <para>\n  /// Identifier placeholder arguments:\n  /// <list type=\"bullet\">\n  /// <item>nameRegex - string value in single quotes, specifies regex to use for matching (empty string by default)</item>\n  /// <item>nameRegexCaseSensitive - boolean value, specifies if name regex is case sensitive (true by default)</item>\n  /// <item>type - string value in single quotes, specifies full type name to match (empty string by default)</item>\n  /// <item>exactType - boolean value, specifies if expression should have exact type match (false by default)</item>\n  /// </list>\n  /// Examples:\n  /// <list type=\"bullet\">\n  /// <item>$myIdentifier{Identifier, 'my.*', false, 'Namespace.FooType', true}$ - defines identifier placeholder, matching identifiers (ignoring case) starting with 'my' prefix with 'Namespace.FooType' type.</item>\n  /// <item>$myIdentifier{Identifier, 'my.*', true, 'Namespace.FooType', true}$ - defines identifier placeholder, matching identifiers (case sensitively) starting with 'my' prefix with 'Namespace.FooType' type.</item>\n  /// <item>$identFoo{'my.*'}$ - defines identifier placeholder, matching identifiers (case sensitively) starting with 'my' prefix.</item>\n  /// </list>\n  /// </para>\n  /// <para>\n  /// Statement placeholder arguments:\n  /// <list type=\"bullet\">\n  /// <item>minimalOccurrences - minimal number of statements to match (-1 by default)</item>\n  /// <item>maximalOccurrences - maximal number of statements to match (-1 by default)</item>\n  /// </list>\n  /// Examples:\n  /// <list type=\"bullet\">\n  /// <item>$myStmt{Statement, 1, 2}$ - defines statement placeholder, matching 1 or 2 statements.</item>\n  /// <item>$myStmt{Statement}$ - defines statement placeholder, matching any number of statements.</item>\n  /// <item>$stmtFoo{1, 2}$ - defines statement placeholder, matching 1 or 2 statements.</item>\n  /// </list>\n  /// </para>\n  /// <para>\n  /// Argument placeholder arguments:\n  /// <list type=\"bullet\">\n  /// <item>minimalOccurrences - minimal number of arguments to match (-1 by default)</item>\n  /// <item>maximalOccurrences - maximal number of arguments to match (-1 by default)</item>\n  /// </list>\n  /// Examples:\n  /// <list type=\"bullet\">\n  /// <item>$myArg{Argument, 1, 2}$ - defines argument placeholder, matching 1 or 2 arguments.</item>\n  /// <item>$myArg{Argument}$ - defines argument placeholder, matching any number of arguments.</item>\n  /// <item>$argFoo{1, 2}$ - defines argument placeholder, matching 1 or 2 arguments.</item>\n  /// </list>\n  /// </para>\n  /// <para>\n  /// Member placeholder arguments:\n  /// <list type=\"bullet\">\n  /// <item>docId - string value in single quotes, specifies XML documentation id of the member to match (empty by default)</item>\n  /// </list>\n  /// Examples:\n  /// <list type=\"bullet\">\n  /// <item>$myMember{Member, 'M:System.String.IsNullOrEmpty(System.String)'}$ - defines member placeholder, matching 'IsNullOrEmpty' member of the 'System.String' type.</item>\n  /// <item>$memberFoo{'M:System.String.IsNullOrEmpty(System.String)'}$ - defines member placeholder, matching 'IsNullOrEmpty' member of the 'System.String' type.</item>\n  /// </list>\n  /// </para>\n  /// <para>\n  /// For more information please refer to the <a href=\"https://www.jetbrains.com/help/resharper/Navigation_and_Search__Structural_Search_and_Replace.html\">Structural Search and Replace</a> article.\n  /// </para>\n  /// </summary>\n  [AttributeUsage(\n    AttributeTargets.Method\n    | AttributeTargets.Constructor\n    | AttributeTargets.Property\n    | AttributeTargets.Field\n    | AttributeTargets.Event\n    | AttributeTargets.Interface\n    | AttributeTargets.Class\n    | AttributeTargets.Struct\n    | AttributeTargets.Enum,\n    AllowMultiple = true,\n    Inherited = false)]\ninternal sealed class CodeTemplateAttribute : Attribute\n  {\n    public CodeTemplateAttribute(string searchTemplate)\n    {\n      SearchTemplate = searchTemplate;\n    }\n\n    /// <summary>\n    /// Structural search pattern to use in the code template.\n    /// The pattern includes a textual part, which must contain only identifiers allowed in the target language,\n    /// and placeholders, which allow matching variable parts of the target code blocks.\n    /// </summary>\n    public string SearchTemplate { get; }\n\n    /// <summary>\n    /// Message to show when the search pattern was found.\n    /// You can also prepend the message text with \"Error:\", \"Warning:\", \"Suggestion:\" or \"Hint:\" prefix to specify the pattern severity.\n    /// Code patterns with replace templates produce suggestions by default.\n    /// However, if a replace template is not provided, then warning severity will be used.\n    /// </summary>\n    public string Message { get; set; }\n\n    /// <summary>\n    /// Structural search replace pattern to use in code template replacement.\n    /// </summary>\n    public string ReplaceTemplate { get; set; }\n\n    /// <summary>\n    /// The replace message to show in the light bulb.\n    /// </summary>\n    public string ReplaceMessage { get; set; }\n\n    /// <summary>\n    /// Apply code formatting after code replacement.\n    /// </summary>\n    public bool FormatAfterReplace { get; set; } = true;\n\n    /// <summary>\n    /// Whether similar code blocks should be matched.\n    /// </summary>\n    public bool MatchSimilarConstructs { get; set; }\n\n    /// <summary>\n    /// Automatically insert namespace import directives or remove qualifiers that become redundant after the template is applied.\n    /// </summary>\n    public bool ShortenReferences { get; set; }\n\n    /// <summary>\n    /// The string to use as a suppression key.\n    /// By default the following suppression key is used 'CodeTemplate_SomeType_SomeMember',\n    /// where 'SomeType' and 'SomeMember' are names of the associated containing type and member to which this attribute is applied.\n    /// </summary>\n    public string SuppressionKey { get; set; }\n  }\n\n  #region ASP.NET\n\n  [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]\ninternal sealed class AspChildControlTypeAttribute : Attribute\n  {\n    public AspChildControlTypeAttribute([NotNull] string tagName, [NotNull] Type controlType)\n    {\n      TagName = tagName;\n      ControlType = controlType;\n    }\n\n    [NotNull] public string TagName { get; }\n\n    [NotNull] public Type ControlType { get; }\n  }\n\n  [AttributeUsage(AttributeTargets.Property | AttributeTargets.Method)]\ninternal sealed class AspDataFieldAttribute : Attribute { }\n\n  [AttributeUsage(AttributeTargets.Property | AttributeTargets.Method)]\ninternal sealed class AspDataFieldsAttribute : Attribute { }\n\n  [AttributeUsage(AttributeTargets.Property)]\ninternal sealed class AspMethodPropertyAttribute : Attribute { }\n\n  [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]\ninternal sealed class AspRequiredAttributeAttribute : Attribute\n  {\n    public AspRequiredAttributeAttribute([NotNull] string attribute)\n    {\n      Attribute = attribute;\n    }\n\n    [NotNull] public string Attribute { get; }\n  }\n\n  [AttributeUsage(AttributeTargets.Property)]\ninternal sealed class AspTypePropertyAttribute : Attribute\n  {\n    public bool CreateConstructorReferences { get; }\n\n    public AspTypePropertyAttribute(bool createConstructorReferences)\n    {\n      CreateConstructorReferences = createConstructorReferences;\n    }\n  }\n\n  #endregion\n\n  #region ASP.NET MVC\n\n  [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = true)]\ninternal sealed class AspMvcAreaMasterLocationFormatAttribute : Attribute\n  {\n    public AspMvcAreaMasterLocationFormatAttribute([NotNull] string format)\n    {\n      Format = format;\n    }\n\n    [NotNull] public string Format { get; }\n  }\n\n  [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = true)]\ninternal sealed class AspMvcAreaPartialViewLocationFormatAttribute : Attribute\n  {\n    public AspMvcAreaPartialViewLocationFormatAttribute([NotNull] string format)\n    {\n      Format = format;\n    }\n\n    [NotNull] public string Format { get; }\n  }\n\n  [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = true)]\ninternal sealed class AspMvcAreaViewComponentViewLocationFormatAttribute : Attribute\n  {\n    public AspMvcAreaViewComponentViewLocationFormatAttribute([NotNull] string format)\n    {\n      Format = format;\n    }\n\n    [NotNull] public string Format { get; }\n  }\n\n  [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = true)]\ninternal sealed class AspMvcAreaViewLocationFormatAttribute : Attribute\n  {\n    public AspMvcAreaViewLocationFormatAttribute([NotNull] string format)\n    {\n      Format = format;\n    }\n\n    [NotNull] public string Format { get; }\n  }\n\n  [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = true)]\ninternal sealed class AspMvcMasterLocationFormatAttribute : Attribute\n  {\n    public AspMvcMasterLocationFormatAttribute([NotNull] string format)\n    {\n      Format = format;\n    }\n\n    [NotNull] public string Format { get; }\n  }\n\n  [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = true)]\ninternal sealed class AspMvcPartialViewLocationFormatAttribute : Attribute\n  {\n    public AspMvcPartialViewLocationFormatAttribute([NotNull] string format)\n    {\n      Format = format;\n    }\n\n    [NotNull] public string Format { get; }\n  }\n\n  [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = true)]\ninternal sealed class AspMvcViewComponentViewLocationFormatAttribute : Attribute\n  {\n    public AspMvcViewComponentViewLocationFormatAttribute([NotNull] string format)\n    {\n      Format = format;\n    }\n\n    [NotNull] public string Format { get; }\n  }\n\n  [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = true)]\ninternal sealed class AspMvcViewLocationFormatAttribute : Attribute\n  {\n    public AspMvcViewLocationFormatAttribute([NotNull] string format)\n    {\n      Format = format;\n    }\n\n    [NotNull] public string Format { get; }\n  }\n\n  /// <summary>\n  /// ASP.NET MVC attribute. If applied to a parameter, indicates that the parameter\n  /// is an MVC action. If applied to a method, the MVC action name is calculated\n  /// implicitly from the context. Use this attribute for custom wrappers similar to\n  /// <c>System.Web.Mvc.Html.ChildActionExtensions.RenderAction(HtmlHelper, String)</c>.\n  /// </summary>\n  [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method | AttributeTargets.Field | AttributeTargets.Property)]\ninternal sealed class AspMvcActionAttribute : Attribute\n  {\n    public AspMvcActionAttribute() { }\n\n    public AspMvcActionAttribute([NotNull] string anonymousProperty)\n    {\n      AnonymousProperty = anonymousProperty;\n    }\n\n    [CanBeNull] public string AnonymousProperty { get; }\n  }\n\n  /// <summary>\n  /// ASP.NET MVC attribute. Indicates that the marked parameter is an MVC area.\n  /// Use this attribute for custom wrappers similar to\n  /// <c>System.Web.Mvc.Html.ChildActionExtensions.RenderAction(HtmlHelper, String)</c>.\n  /// </summary>\n  [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Field | AttributeTargets.Property)]\ninternal sealed class AspMvcAreaAttribute : Attribute\n  {\n    public AspMvcAreaAttribute() { }\n\n    public AspMvcAreaAttribute([NotNull] string anonymousProperty)\n    {\n      AnonymousProperty = anonymousProperty;\n    }\n\n    [CanBeNull] public string AnonymousProperty { get; }\n  }\n\n  /// <summary>\n  /// ASP.NET MVC attribute. If applied to a parameter, indicates that the parameter is\n  /// an MVC controller. If applied to a method, the MVC controller name is calculated\n  /// implicitly from the context. Use this attribute for custom wrappers similar to\n  /// <c>System.Web.Mvc.Html.ChildActionExtensions.RenderAction(HtmlHelper, String, String)</c>.\n  /// </summary>\n  [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method | AttributeTargets.Field | AttributeTargets.Property)]\ninternal sealed class AspMvcControllerAttribute : Attribute\n  {\n    public AspMvcControllerAttribute() { }\n\n    public AspMvcControllerAttribute([NotNull] string anonymousProperty)\n    {\n      AnonymousProperty = anonymousProperty;\n    }\n\n    [CanBeNull] public string AnonymousProperty { get; }\n  }\n\n  /// <summary>\n  /// ASP.NET MVC attribute. Indicates that the marked parameter is an MVC Master. Use this attribute\n  /// for custom wrappers similar to <c>System.Web.Mvc.Controller.View(String, String)</c>.\n  /// </summary>\n  [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Field | AttributeTargets.Property)]\ninternal sealed class AspMvcMasterAttribute : Attribute { }\n\n  /// <summary>\n  /// ASP.NET MVC attribute. Indicates that the marked parameter is an MVC model type. Use this attribute\n  /// for custom wrappers similar to <c>System.Web.Mvc.Controller.View(String, Object)</c>.\n  /// </summary>\n  [AttributeUsage(AttributeTargets.Parameter)]\ninternal sealed class AspMvcModelTypeAttribute : Attribute { }\n\n  /// <summary>\n  /// ASP.NET MVC attribute. If applied to a parameter, indicates that the parameter is an MVC\n  /// partial view. If applied to a method, the MVC partial view name is calculated implicitly\n  /// from the context. Use this attribute for custom wrappers similar to\n  /// <c>System.Web.Mvc.Html.RenderPartialExtensions.RenderPartial(HtmlHelper, String)</c>.\n  /// </summary>\n  [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method | AttributeTargets.Field | AttributeTargets.Property)]\ninternal sealed class AspMvcPartialViewAttribute : Attribute { }\n\n  /// <summary>\n  /// ASP.NET MVC attribute. Allows disabling inspections for MVC views within a class or a method.\n  /// </summary>\n  [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]\ninternal sealed class AspMvcSuppressViewErrorAttribute : Attribute { }\n\n  /// <summary>\n  /// ASP.NET MVC attribute. Indicates that a parameter is an MVC display template.\n  /// Use this attribute for custom wrappers similar to\n  /// <c>System.Web.Mvc.Html.DisplayExtensions.DisplayForModel(HtmlHelper, String)</c>.\n  /// </summary>\n  [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Field | AttributeTargets.Property)]\ninternal sealed class AspMvcDisplayTemplateAttribute : Attribute { }\n\n  /// <summary>\n  /// ASP.NET MVC attribute. Indicates that the marked parameter is an MVC editor template.\n  /// Use this attribute for custom wrappers similar to\n  /// <c>System.Web.Mvc.Html.EditorExtensions.EditorForModel(HtmlHelper, String)</c>.\n  /// </summary>\n  [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Field | AttributeTargets.Property)]\ninternal sealed class AspMvcEditorTemplateAttribute : Attribute { }\n\n  /// <summary>\n  /// ASP.NET MVC attribute. Indicates that the marked parameter is an MVC template.\n  /// Use this attribute for custom wrappers similar to\n  /// <c>System.ComponentModel.DataAnnotations.UIHintAttribute(System.String)</c>.\n  /// </summary>\n  [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Field | AttributeTargets.Property)]\ninternal sealed class AspMvcTemplateAttribute : Attribute { }\n\n  /// <summary>\n  /// ASP.NET MVC attribute. If applied to a parameter, indicates that the parameter\n  /// is an MVC view component. If applied to a method, the MVC view name is calculated implicitly\n  /// from the context. Use this attribute for custom wrappers similar to\n  /// <c>System.Web.Mvc.Controller.View(Object)</c>.\n  /// </summary>\n  [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method | AttributeTargets.Field | AttributeTargets.Property)]\ninternal sealed class AspMvcViewAttribute : Attribute { }\n\n  /// <summary>\n  /// ASP.NET MVC attribute. If applied to a parameter, indicates that the parameter\n  /// is an MVC view component name.\n  /// </summary>\n  [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Field | AttributeTargets.Property)]\ninternal sealed class AspMvcViewComponentAttribute : Attribute { }\n\n  /// <summary>\n  /// ASP.NET MVC attribute. If applied to a parameter, indicates that the parameter\n  /// is an MVC view component view. If applied to a method, the MVC view component view name is default.\n  /// </summary>\n  [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method | AttributeTargets.Field | AttributeTargets.Property)]\ninternal sealed class AspMvcViewComponentViewAttribute : Attribute { }\n\n  /// <summary>\n  /// ASP.NET MVC attribute. When applied to a parameter of an attribute,\n  /// indicates that this parameter is an MVC action name.\n  /// </summary>\n  /// <example><code>\n  /// [ActionName(\"Foo\")]\n  /// public ActionResult Login(string returnUrl) {\n  ///   ViewBag.ReturnUrl = Url.Action(\"Foo\"); // OK\n  ///   return RedirectToAction(\"Bar\"); // Error: Cannot resolve action\n  /// }\n  /// </code></example>\n  [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property)]\ninternal sealed class AspMvcActionSelectorAttribute : Attribute { }\n\n  #endregion\n\n  #region ASP.NET Routing\n\n  /// <summary>\n  /// Indicates that the marked parameter, field, or property is a route template.\n  /// </summary>\n  /// <remarks>\n  /// This attribute allows IDE to recognize the use of web frameworks' route templates\n  /// to enable syntax highlighting, code completion, navigation, rename and other features in string literals.\n  /// </remarks>\n  [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Field | AttributeTargets.Property)]\ninternal sealed class RouteTemplateAttribute : Attribute { }\n\n  /// <summary>\n  /// Indicates that the marked type is custom route parameter constraint,\n  /// which is registered in the application's Startup with the name <c>ConstraintName</c>.\n  /// </summary>\n  /// <remarks>\n  /// You can specify <c>ProposedType</c> if target constraint matches only route parameters of specific type,\n  /// it will allow IDE to create method's parameter from usage in route template\n  /// with specified type instead of default <c>System.String</c>\n  /// and check if constraint's proposed type conflicts with matched parameter's type.\n  /// </remarks>\n  [AttributeUsage(AttributeTargets.Class)]\ninternal sealed class RouteParameterConstraintAttribute : Attribute\n  {\n    [NotNull] public string ConstraintName { get; }\n    [CanBeNull] public Type ProposedType { get; set; }\n\n    public RouteParameterConstraintAttribute([NotNull] string constraintName)\n    {\n      ConstraintName = constraintName;\n    }\n  }\n\n  /// <summary>\n  /// Indicates that the marked parameter, field, or property is an URI string.\n  /// </summary>\n  /// <remarks>\n  /// This attribute enables code completion, navigation, renaming and other features\n  /// in URI string literals assigned to annotated parameters, fields, or properties.\n  /// </remarks>\n  [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Field | AttributeTargets.Property)]\ninternal sealed class UriStringAttribute : Attribute\n  {\n    public UriStringAttribute() { }\n\n    public UriStringAttribute(string httpVerb)\n    {\n      HttpVerb = httpVerb;\n    }\n\n    [CanBeNull] public string HttpVerb { get; }\n  }\n\n  /// <summary>\n  /// Indicates that the marked method declares routing convention for ASP.NET.\n  /// </summary>\n  /// <remarks>\n  /// The IDE will analyze all usages of methods marked with this attribute,\n  /// and will add all routes to completion, navigation, and other features over URI strings.\n  /// </remarks>\n  [AttributeUsage(AttributeTargets.Method)]\ninternal sealed class AspRouteConventionAttribute : Attribute\n  {\n    public AspRouteConventionAttribute() { }\n\n    public AspRouteConventionAttribute(string predefinedPattern)\n    {\n      PredefinedPattern = predefinedPattern;\n    }\n\n    [CanBeNull] public string PredefinedPattern { get; }\n  }\n\n  /// <summary>\n  /// Indicates that the marked method parameter contains default route values of routing convention for ASP.NET.\n  /// </summary>\n  [AttributeUsage(AttributeTargets.Parameter)]\ninternal sealed class AspDefaultRouteValuesAttribute : Attribute { }\n\n  /// <summary>\n  /// Indicates that the marked method parameter contains constraints on route values of routing convention for ASP.NET.\n  /// </summary>\n  [AttributeUsage(AttributeTargets.Parameter)]\ninternal sealed class AspRouteValuesConstraintsAttribute : Attribute { }\n\n  /// <summary>\n  /// Indicates that the marked parameter or property contains routing order provided by ASP.NET routing attribute.\n  /// </summary>\n  [AttributeUsage(AttributeTargets.Property | AttributeTargets.Parameter)]\ninternal sealed class AspRouteOrderAttribute : Attribute { }\n\n  /// <summary>\n  /// Indicates that the marked parameter or property contains HTTP verbs provided by ASP.NET routing attribute.\n  /// </summary>\n  [AttributeUsage(AttributeTargets.Property | AttributeTargets.Parameter)]\ninternal sealed class AspRouteVerbsAttribute : Attribute { }\n\n  /// <summary>\n  /// Indicates that the marked attribute is used for attribute routing in ASP.NET.\n  /// </summary>\n  /// <remarks>\n  /// The IDE will analyze all usages of attributes marked with this attribute,\n  /// and will add all routes to completion, navigation and other features over URI strings.\n  /// </remarks>\n  [AttributeUsage(AttributeTargets.Class)]\ninternal sealed class AspAttributeRoutingAttribute : Attribute\n  {\n    public string HttpVerb { get; set; }\n  }\n\n  /// <summary>\n  /// Indicates that the marked method declares an ASP.NET Minimal API endpoint.\n  /// </summary>\n  /// <remarks>\n  /// The IDE will analyze all usages of methods marked with this attribute,\n  /// and will add all routes to completion, navigation and other features over URI strings.\n  /// </remarks>\n  [AttributeUsage(AttributeTargets.Method)]\ninternal sealed class AspMinimalApiDeclarationAttribute : Attribute\n  {\n    public string HttpVerb { get; set; }\n  }\n\n  /// <summary>\n  /// Indicates that the marked method declares an ASP.NET Minimal API endpoints group.\n  /// </summary>\n  [AttributeUsage(AttributeTargets.Method)]\ninternal sealed class AspMinimalApiGroupAttribute : Attribute { }\n\n  /// <summary>\n  /// Indicates that the marked parameter contains an ASP.NET Minimal API endpoint handler.\n  /// </summary>\n  [AttributeUsage(AttributeTargets.Parameter)]\ninternal sealed class AspMinimalApiHandlerAttribute : Attribute { }\n\n  #endregion\n\n  #region Razor\n\n  [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.Field)]\ninternal sealed class HtmlElementAttributesAttribute : Attribute\n  {\n    public HtmlElementAttributesAttribute() { }\n\n    public HtmlElementAttributesAttribute([NotNull] string name)\n    {\n      Name = name;\n    }\n\n    [CanBeNull] public string Name { get; }\n  }\n\n  [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Field | AttributeTargets.Property)]\ninternal sealed class HtmlAttributeValueAttribute : Attribute\n  {\n    public HtmlAttributeValueAttribute([NotNull] string name)\n    {\n      Name = name;\n    }\n\n    [NotNull] public string Name { get; }\n  }\n\n  /// <summary>\n  /// Razor attribute. Indicates that the marked parameter or method is a Razor section.\n  /// Use this attribute for custom wrappers similar to\n  /// <c>System.Web.WebPages.WebPageBase.RenderSection(String)</c>.\n  /// </summary>\n  [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method)]\ninternal sealed class RazorSectionAttribute : Attribute { }\n\n  [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]\ninternal sealed class RazorImportNamespaceAttribute : Attribute\n  {\n    public RazorImportNamespaceAttribute([NotNull] string name)\n    {\n      Name = name;\n    }\n\n    [NotNull] public string Name { get; }\n  }\n\n  [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]\ninternal sealed class RazorInjectionAttribute : Attribute\n  {\n    public RazorInjectionAttribute([NotNull] string type, [NotNull] string fieldName)\n    {\n      Type = type;\n      FieldName = fieldName;\n    }\n\n    [NotNull] public string Type { get; }\n\n    [NotNull] public string FieldName { get; }\n  }\n\n  [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]\ninternal sealed class RazorDirectiveAttribute : Attribute\n  {\n    public RazorDirectiveAttribute([NotNull] string directive)\n    {\n      Directive = directive;\n    }\n\n    [NotNull] public string Directive { get; }\n  }\n\n  [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]\ninternal sealed class RazorPageBaseTypeAttribute : Attribute\n  {\n      public RazorPageBaseTypeAttribute([NotNull] string baseType)\n      {\n        BaseType = baseType;\n      }\n      public RazorPageBaseTypeAttribute([NotNull] string baseType, string pageName)\n      {\n          BaseType = baseType;\n          PageName = pageName;\n      }\n\n      [NotNull] public string BaseType { get; }\n      [CanBeNull] public string PageName { get; }\n  }\n\n  [AttributeUsage(AttributeTargets.Method)]\ninternal sealed class RazorHelperCommonAttribute : Attribute { }\n\n  [AttributeUsage(AttributeTargets.Property)]\ninternal sealed class RazorLayoutAttribute : Attribute { }\n\n  [AttributeUsage(AttributeTargets.Method)]\ninternal sealed class RazorWriteLiteralMethodAttribute : Attribute { }\n\n  [AttributeUsage(AttributeTargets.Method)]\ninternal sealed class RazorWriteMethodAttribute : Attribute { }\n\n  [AttributeUsage(AttributeTargets.Parameter)]\ninternal sealed class RazorWriteMethodParameterAttribute : Attribute { }\n\n  #endregion\n\n  #region XAML\n\n  /// <summary>\n  /// XAML attribute. Indicates the type that has an <c>ItemsSource</c> property and should be treated\n  /// as an <c>ItemsControl</c>-derived type, to enable inner items <c>DataContext</c> type resolution.\n  /// </summary>\n  [AttributeUsage(AttributeTargets.Class)]\ninternal sealed class XamlItemsControlAttribute : Attribute { }\n\n  /// <summary>\n  /// XAML attribute. Indicates the property of some <c>BindingBase</c>-derived type, that\n  /// is used to bind some item of an <c>ItemsControl</c>-derived type. This annotation will\n  /// enable the <c>DataContext</c> type resolve for XAML bindings for such properties.\n  /// </summary>\n  /// <remarks>\n  /// The property should have the tree ancestor of the <c>ItemsControl</c> type, or\n  /// marked with the <see cref=\"XamlItemsControlAttribute\"/> attribute.\n  /// </remarks>\n  [AttributeUsage(AttributeTargets.Property)]\ninternal sealed class XamlItemBindingOfItemsControlAttribute : Attribute { }\n\n  /// <summary>\n  /// XAML attribute. Indicates the property of some <c>Style</c>-derived type that\n  /// is used to style items of an <c>ItemsControl</c>-derived type. This annotation will\n  /// enable the <c>DataContext</c> type resolve for XAML bindings for such properties.\n  /// </summary>\n  /// <remarks>\n  /// Property should have the tree ancestor of the <c>ItemsControl</c> type or\n  /// marked with the <see cref=\"XamlItemsControlAttribute\"/> attribute.\n  /// </remarks>\n  [AttributeUsage(AttributeTargets.Property)]\ninternal sealed class XamlItemStyleOfItemsControlAttribute : Attribute { }\n\n  /// <summary>\n  /// XAML attribute. Indicates that DependencyProperty has <c>OneWay</c> binding mode by default.\n  /// </summary>\n  /// <remarks>\n  /// This attribute must be applied to DependencyProperty's CLR accessor property if it is present, or to a DependencyProperty descriptor field otherwise.\n  /// </remarks>\n  [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]\ninternal sealed class XamlOneWayBindingModeByDefaultAttribute : Attribute { }\n\n  /// <summary>\n  /// XAML attribute. Indicates that DependencyProperty has <c>TwoWay</c> binding mode by default.\n  /// </summary>\n  /// <remarks>\n  /// This attribute must be applied to DependencyProperty's CLR accessor property if it is present, or to a DependencyProperty descriptor field otherwise.\n  /// </remarks>\n  [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]\ninternal sealed class XamlTwoWayBindingModeByDefaultAttribute : Attribute { }\n\n  #endregion\n\n  #region Unit Testing\n\n  /// <summary>\n  /// Specifies the subject being tested by a test class or a test method.\n  /// </summary>\n  /// <remarks>\n  /// The <see cref=\"TestSubjectAttribute\"/> can be applied to a test class or a test method to indicate what class\n  /// or interface the tests defined in them test. This information can be used by an IDE to provide better navigation\n  /// support or by test runners to group tests by subject and to provide better test reports.\n  /// </remarks>\n  [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = true)]\ninternal sealed class TestSubjectAttribute : Attribute\n  {\n    /// <summary>\n    /// Gets the type of the subject being tested.\n    /// </summary>\n    [NotNull] public Type Subject { get; }\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"TestSubjectAttribute\"/> class with the specified subject type.\n    /// </summary>\n    /// <param name=\"subject\">The type of the subject being tested.</param>\n    public TestSubjectAttribute([NotNull] Type subject)\n    {\n      Subject = subject;\n    }\n  }\n\n  /// <summary>\n  /// Signifies a generic argument as the test subject for a test class.\n  /// </summary>\n  /// <remarks>\n  /// The <see cref=\"MeansTestSubjectAttribute\"/> can be applied to a generic parameter of a base test class to indicate that\n  /// the type passed as the argument is the class being tested. This information can be used by an IDE to provide better\n  /// navigation support or by test runners to group tests by subject and to provide better test reports.\n  /// </remarks>\n  /// <example><code>\n  /// public class BaseTestClass&lt;[MeansTestSubject] T&gt;\n  /// {\n  ///   protected T Component { get; }\n  /// }\n  ///\n  /// public class CalculatorAdditionTests : BaseTestClass&lt;Calculator&gt;\n  /// {\n  ///   [Test]\n  ///   public void Should_add_two_numbers()\n  ///   {\n  ///      Assert.That(Component.Add(2, 3), Is.EqualTo(5));\n  ///   }\n  /// }\n  /// </code></example>\n  [AttributeUsage(AttributeTargets.GenericParameter)]\ninternal sealed class MeansTestSubjectAttribute : Attribute { }\n\n  #endregion\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Helpers/ConsoleExitHandler.cs",
    "content": "using System;\nusing System.Diagnostics;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Loggers;\n\nnamespace BenchmarkDotNet.Helpers\n{\n    internal class ConsoleExitHandler : IDisposable\n    {\n        private readonly Process process;\n        private readonly ILogger logger;\n\n        internal ConsoleExitHandler(Process process, ILogger logger)\n        {\n            this.process = process;\n            this.logger = logger;\n\n            Attach();\n        }\n\n        public void Dispose() => Detach();\n\n        private void Attach()\n        {\n            process.Exited += ProcessOnExited;\n            try\n            {\n                Console.CancelKeyPress += CancelKeyPressHandlerCallback;\n            }\n            catch (PlatformNotSupportedException)\n            {\n                // Thrown when running in Xamarin\n            }\n            AppDomain.CurrentDomain.ProcessExit += ProcessExitEventHandlerHandlerCallback;\n        }\n\n        private void Detach()\n        {\n            process.Exited -= ProcessOnExited;\n            try\n            {\n                Console.CancelKeyPress -= CancelKeyPressHandlerCallback;\n            }\n            catch (PlatformNotSupportedException)\n            {\n                // Thrown when running in Xamarin\n            }\n            AppDomain.CurrentDomain.ProcessExit -= ProcessExitEventHandlerHandlerCallback;\n        }\n\n        // the process has exited, so we detach the events\n        private void ProcessOnExited(object? sender, EventArgs e) => Detach();\n\n        // the user has clicked Ctrl+C so we kill the entire process tree\n        private void CancelKeyPressHandlerCallback(object? sender, ConsoleCancelEventArgs e) => KillProcessTree();\n\n        // the user has closed the console window so we kill the entire process tree\n        private void ProcessExitEventHandlerHandlerCallback(object? sender, EventArgs e) => KillProcessTree();\n\n        internal void KillProcessTree()\n        {\n            try\n            {\n                logger.Flush(); // Save log to file as soon as possible. Without it, the file log will be empty if the process has already died.\n\n                process.KillTree(); // we need to kill entire process tree, not just the process itself\n            }\n            catch\n            {\n                // we don't care about exceptions here, it's shutdown and we just try to cleanup whatever we can\n            }\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Helpers/DefaultCultureInfo.cs",
    "content": "using System.Globalization;\n\nnamespace BenchmarkDotNet.Helpers\n{\n    internal static class DefaultCultureInfo\n    {\n        public static readonly CultureInfo Instance;\n\n        static DefaultCultureInfo()\n        {\n            Instance = (CultureInfo) CultureInfo.InvariantCulture.Clone();\n            Instance.NumberFormat.NumberDecimalSeparator = \".\";\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Helpers/DirtyAssemblyResolveHelper.cs",
    "content": "﻿using System;\nusing System.IO;\nusing System.Reflection;\n\n// THIS TYPE MUST NOT HAVE ANY DEPENDENCIES TO BENCHMARKDOTNET, VALUE TUPLE, IMMUTABLE TYPES OR ANYTHING COMPLEX!!\n\n/// <summary>\n/// Sometimes NuGet/VS/other tool does not generate the right assembly binding redirects\n/// or just for any other magical reasons\n/// our users get FileNotFoundException when trying to run their benchmarks\n///\n/// We want our users to be happy and we try to help the .NET framework when it fails to load an assembly\n///\n/// It's not recommended to copy this code OR reuse it anywhere. It's an UGLY WORKAROUND.\n///\n/// If one day we can remove it, the person doing that should celebrate!!\n/// </summary>\n// ReSharper disable once CheckNamespace I did it on purpose to show that it MUST not touch any BenchmarkDotNet stuff\ninternal class DirtyAssemblyResolveHelper : IDisposable\n{\n    internal static IDisposable Create() => new DirtyAssemblyResolveHelper();\n\n    private DirtyAssemblyResolveHelper() => AppDomain.CurrentDomain.AssemblyResolve += HelpTheFrameworkToResolveTheAssembly;\n\n    public void Dispose() => AppDomain.CurrentDomain.AssemblyResolve -= HelpTheFrameworkToResolveTheAssembly;\n\n    /// <summary>\n    /// according to https://msdn.microsoft.com/en-us/library/ff527268(v=vs.110).aspx\n    /// \"the handler is invoked whenever the runtime fails to bind to an assembly by name.\"\n    /// </summary>\n    /// <returns>not null when we find it manually, null when can't help</returns>\n    private Assembly? HelpTheFrameworkToResolveTheAssembly(object? sender, ResolveEventArgs args)\n    {\n        var fullName = new AssemblyName(args.Name);\n        string simpleName = fullName.Name!;\n\n        string guessedPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, $\"{simpleName}.dll\");\n\n        if (!File.Exists(guessedPath))\n            return null; // we can't help, and we also don't call Assembly.Load which if fails comes back here, creates endless loop and causes StackOverflow\n\n        // the file is right there, but has most probably different version and there is no assembly redirect\n        // so we just load it and ignore the version mismatch\n        // we can at least try because benchmarks are not executed in the Host process,\n        // so even if we load some bad version of the assembly\n        // we might still produce the right exe with proper references\n\n        // we warn the user about that, in case some Super User want to be aware of that\n        Console.WriteLine($\"// Wrong assembly binding redirects for {simpleName}, loading it from disk anyway.\");\n\n        return Assembly.LoadFrom(guessedPath);\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Helpers/DisposeAtProcessTermination.cs",
    "content": "﻿using BenchmarkDotNet.Detectors;\nusing System;\nusing System.Runtime.InteropServices;\n\nnamespace BenchmarkDotNet.Helpers\n{\n    /// <summary>\n    /// Ensures that explicit Dispose is called at termination of the Process.\n    /// </summary>\n    /// <remarks>\n    /// <para>\n    /// This class exists to help in reverting system state where C#'s using statement does not\n    /// suffice. I.e. when Benchmark's process is aborted via Ctrl-C, Ctrl-Break or via click on the\n    /// X in the upper right of Window.\n    /// </para>\n    /// <para>\n    /// Usage: Derive your clas that changes system state of this class. Revert system state in\n    /// override of <see cref=\"Dispose\"/> implementation.\n    /// Use your class in C#'s using statement, to ensure system state is reverted in normal situations.\n    /// This class ensures your override is also called at process 'abort'.\n    /// </para>\n    /// <para>\n    /// Note: This class is explicitly not responsible for cleanup of Native resources. Of course,\n    /// derived classes can cleanup their Native resources (usually managed via\n    /// <see cref=\"SafeHandle\"/> derived classes), by delegating explicit Disposal to their\n    /// <see cref=\"IDisposable\"/> fields.\n    /// </para>\n    /// </remarks>\n    public abstract class DisposeAtProcessTermination : IDisposable\n    {\n        private static readonly bool ConsoleSupportsCancelKeyPress\n            = !(OsDetector.IsAndroid() || OsDetector.IsIOS() || OsDetector.IsTvOS() || Portability.RuntimeInformation.IsWasm);\n\n        protected DisposeAtProcessTermination()\n        {\n            AppDomain.CurrentDomain.ProcessExit += OnProcessExit;\n            if (ConsoleSupportsCancelKeyPress)\n            {\n                // Cancel key presses are not supported by .NET or do not exist for these\n                Console.CancelKeyPress += OnCancelKeyPress;\n            }\n\n            // It does not make sense to include a Finalizer. We do not manage any native resource and:\n            // as we are subscribed to static events, it would never be called.\n        }\n\n        /// <summary>\n        /// Called when the user presses Ctrl-C or Ctrl-Break.\n        /// </summary>\n        private void OnCancelKeyPress(object? sender, ConsoleCancelEventArgs e)\n        {\n            if (!e.Cancel) { Dispose(); }\n        }\n\n        /// <summary>\n        /// Called when the user clicks on the X in the upper right corner to close the Benchmark's Window.\n        /// </summary>\n        private void OnProcessExit(object? sender, EventArgs e) => Dispose();\n\n        public virtual void Dispose()\n        {\n            AppDomain.CurrentDomain.ProcessExit -= OnProcessExit;\n            if (ConsoleSupportsCancelKeyPress)\n            {\n                // Cancel key presses are not supported by .NET or do not exist for these\n                Console.CancelKeyPress -= OnCancelKeyPress;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Helpers/ExternalToolsHelper.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing BenchmarkDotNet.Detectors;\nusing BenchmarkDotNet.Portability;\n\nnamespace BenchmarkDotNet.Helpers\n{\n    public static class ExternalToolsHelper\n    {\n        /// <summary>\n        /// Output of the `system_profiler SPSoftwareDataType` command.\n        /// MacOSX only.\n        /// </summary>\n        public static readonly Lazy<Dictionary<string, string>> MacSystemProfilerData =\n            LazyParse(OsDetector.IsMacOS, \"system_profiler\", \"SPSoftwareDataType\", s => SectionsHelper.ParseSection(s, ':'));\n\n        private static Lazy<T> LazyParse<T>(Func<bool> isAvailable, string fileName, string arguments, Func<string?, T> parseFunc)\n        {\n            return new Lazy<T>(() =>\n            {\n                string? content = isAvailable() ? ProcessHelper.RunAndReadOutput(fileName, arguments) : \"\";\n                return parseFunc(content);\n            });\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Helpers/FolderNameHelper.cs",
    "content": "﻿using System;\nusing System.Globalization;\nusing System.IO;\nusing System.Text;\nusing BenchmarkDotNet.Extensions;\nusing Perfolizer.Horology;\n\nnamespace BenchmarkDotNet.Helpers\n{\n    public static class FolderNameHelper\n    {\n        public static string ToFolderName(object? value)\n        {\n            switch (value) {\n                case null:\n                    return \"null\";\n                case bool b:\n                    return b.ToLowerCase();\n                case string s:\n                    return Escape(new StringBuilder(s));\n                case char c:\n                    return ((int)c).ToString(); // TODO: rewrite\n                case float f:\n                    return f.ToString(\"F\", CultureInfo.InvariantCulture).Replace(\".\", \"-\");\n                case double d:\n                    return d.ToString(\"F\", CultureInfo.InvariantCulture).Replace(\".\", \"-\");\n                case decimal d:\n                    return d.ToString(\"F\", CultureInfo.InvariantCulture).Replace(\".\", \"-\");\n            }\n\n            var valueType = value.GetType();\n            if (valueType.IsEnum)\n                return value.ToString()!;\n            if (value is Type type)\n                return ToFolderName(type: type);\n            if (!valueType.IsValueType)\n                return valueType.Name;\n            if (value is TimeInterval interval)\n                return interval.Nanoseconds + \"ns\";\n\n            return value.ToString()!;\n        }\n\n        // we can't simply use type.FullName, because for generics it's too long\n        // example: typeof(List<int>).FullName => \"System.Collections.Generic.List`1[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]\"\n        public static string ToFolderName(Type type, bool includeNamespace = true, bool includeGenericArgumentsNamespace = false)\n            => Escape(new StringBuilder(type.GetCorrectCSharpTypeName(includeNamespace, includeGenericArgumentsNamespace, prefixWithGlobal: false)));\n\n        private static string Escape(StringBuilder builder)\n        {\n            foreach (char invalidPathChar in Path.GetInvalidFileNameChars())\n                builder.Replace(invalidPathChar, '_');\n\n            // >, <, and : are valid on Unix, but not on Windows. File names should be consistent across all OSes #981\n            builder.Replace('<', '_');\n            builder.Replace('>', '_');\n            builder.Replace(':', '_');\n\n            return builder.ToString();\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Helpers/FrameworkVersionHelper.cs",
    "content": "﻿using System;\nusing System.IO;\nusing System.Linq;\nusing System.Reflection;\nusing System.Runtime.Versioning;\nusing Microsoft.Win32;\n\nnamespace BenchmarkDotNet.Helpers\n{\n    internal static class FrameworkVersionHelper\n    {\n        // magic numbers come from https://docs.microsoft.com/en-us/dotnet/framework/migration-guide/how-to-determine-which-versions-are-installed\n        // should be ordered by release number\n        private static readonly (int minReleaseNumber, string version)[] FrameworkVersions =\n        [\n            (533320, \"4.8.1\"), // value taken from Windows 11 arm64 insider build\n            (528040, \"4.8\"),\n            (461808, \"4.7.2\"),\n            (461308, \"4.7.1\"),\n            (460798, \"4.7\"),\n            (394802, \"4.6.2\"),\n            (394254, \"4.6.1\")\n        ];\n\n        internal static string? GetTargetFrameworkVersion(Assembly? assembly)\n            // Look for a TargetFrameworkAttribute with a supported Framework version.\n            => assembly?.GetCustomAttribute<TargetFrameworkAttribute>()?.FrameworkName switch\n            {\n                \".NETFramework,Version=v4.6.1\" => \"4.6.1\",\n                \".NETFramework,Version=v4.6.2\" => \"4.6.2\",\n                \".NETFramework,Version=v4.7\" => \"4.7\",\n                \".NETFramework,Version=v4.7.1\" => \"4.7.1\",\n                \".NETFramework,Version=v4.7.2\" => \"4.7.2\",\n                \".NETFramework,Version=v4.8\" => \"4.8\",\n                \".NETFramework,Version=v4.8.1\" => \"4.8.1\",\n                // Null assembly, or TargetFrameworkAttribute not found, or the assembly targeted a version older than we support,\n                // or the assembly targeted a non-framework tfm (like netstandard2.0).\n                _ => null,\n            };\n\n        internal static Version? GetTargetCoreVersion(Assembly? assembly)\n        {\n            //.NETCoreApp,Version=vX.Y\n            const string FrameworkPrefix = \".NETCoreApp,Version=v\";\n\n            // Look for a TargetFrameworkAttribute with a supported Framework version.\n            string? framework = assembly?.GetCustomAttribute<TargetFrameworkAttribute>()?.FrameworkName;\n            if (framework?.StartsWith(FrameworkPrefix) == true\n                && Version.TryParse(framework[FrameworkPrefix.Length..], out var version)\n                // We don't support netcoreapp1.X\n                && version.Major >= 2)\n            {\n                return version;\n            }\n\n            // Null assembly, or TargetFrameworkAttribute not found, or the assembly targeted a version older than we support,\n            // or the assembly targeted a non-core tfm (like netstandard2.0).\n            return null;\n        }\n\n        internal static string GetFrameworkDescription()\n        {\n            var fullName = System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription; // sth like .NET Framework 4.7.3324.0\n            var servicingVersion = new string(fullName.SkipWhile(c => !char.IsDigit(c)).ToArray());\n            var releaseVersion = MapToReleaseVersion(servicingVersion);\n\n            return $\".NET Framework {releaseVersion} ({servicingVersion})\";\n        }\n\n        internal static string GetFrameworkReleaseVersion()\n        {\n            var fullName = System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription; // sth like .NET Framework 4.7.3324.0\n            var servicingVersion = new string(fullName.SkipWhile(c => !char.IsDigit(c)).ToArray());\n            return MapToReleaseVersion(servicingVersion);\n        }\n\n        internal static string MapToReleaseVersion(string servicingVersion)\n        {\n            // the following code assumes that .NET 4.6.1 is the oldest supported version\n            if (string.CompareOrdinal(servicingVersion, \"4.6.2\") < 0)\n                return \"4.6.1\";\n            if (string.CompareOrdinal(servicingVersion, \"4.7\") < 0)\n                return \"4.6.2\";\n            if (string.CompareOrdinal(servicingVersion, \"4.7.1\") < 0)\n                return \"4.7\";\n            if (string.CompareOrdinal(servicingVersion, \"4.7.2\") < 0)\n                return \"4.7.1\";\n            if (string.CompareOrdinal(servicingVersion, \"4.8\") < 0)\n                return \"4.7.2\";\n            if (string.CompareOrdinal(servicingVersion, \"4.8.9\") < 0)\n                return \"4.8\";\n\n            return \"4.8.1\"; // most probably the last major release of Full .NET Framework\n        }\n\n        [SupportedOSPlatform(\"windows\")]\n        private static int? GetReleaseNumberFromWindowsRegistry()\n        {\n            using var baseKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32);\n            using var ndpKey = baseKey.OpenSubKey(@\"SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v4\\Full\\\");\n            if (ndpKey == null)\n                return null;\n            return Convert.ToInt32(ndpKey.GetValue(\"Release\"));\n        }\n\n        [SupportedOSPlatform(\"windows\")]\n        internal static string? GetLatestNetDeveloperPackVersion()\n        {\n            if (GetReleaseNumberFromWindowsRegistry() is not int releaseNumber)\n                return null;\n\n            return FrameworkVersions\n                .FirstOrDefault(v => releaseNumber >= v.minReleaseNumber && IsDeveloperPackInstalled(v.version))\n                .version;\n        }\n\n        // Reference Assemblies exists when Developer Pack is installed\n        private static bool IsDeveloperPackInstalled(string version) => Directory.Exists(Path.Combine(\n            ProgramFilesX86DirectoryPath, @\"Reference Assemblies\\Microsoft\\Framework\\.NETFramework\", 'v' + version));\n\n        private static readonly string ProgramFilesX86DirectoryPath = Environment.GetFolderPath(\n            Environment.Is64BitOperatingSystem\n                ? Environment.SpecialFolder.ProgramFilesX86\n                : Environment.SpecialFolder.ProgramFiles);\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Helpers/GenericBenchmarksBuilder.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Extensions;\n\nnamespace BenchmarkDotNet.Helpers\n{\n    internal static class GenericBenchmarksBuilder\n    {\n        internal static Type[] GetRunnableBenchmarks(IEnumerable<Type> types)\n            => types.Where(type => type.ContainsRunnableBenchmarks())\n                    .SelectMany(BuildGenericsIfNeeded)\n                    .Where(x => x.isSuccess)\n                    .Select(x => x.result)\n                    .ToArray();\n\n        internal static IEnumerable<(bool isSuccess, Type result)> BuildGenericsIfNeeded(Type type)\n        {\n            var typeArguments = type.GetCustomAttributes(true).OfType<GenericTypeArgumentsAttribute>()\n                                                              .Select(x => x.GenericTypeArguments)\n                                                              .ToArray();\n\n            if (typeArguments.Any())\n                return BuildGenericTypes(type, typeArguments);\n\n            return [(true,  type)];\n        }\n\n        private static IEnumerable<(bool isSuccess, Type result)> BuildGenericTypes(Type type, IEnumerable<Type[]> typeArguments)\n            => typeArguments.Select(genericArg => (type.TryMakeGenericType(genericArg, out var builtType), builtType));\n\n        private static bool TryMakeGenericType(this Type type, Type[] typeArguments, out Type result)\n        {\n            try\n            {\n                result = type.MakeGenericType(typeArguments);\n                return true;\n            }\n            catch (ArgumentException) // thrown when number or type of generic arguments is invalid, https://msdn.microsoft.com/en-us/library/system.type.makegenerictype(v=vs.110).aspx?f=255&mspperror=-2147217396#Anchor_1\n            {\n                result = type;\n                return false;\n            }\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Helpers/HashCode.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Runtime.CompilerServices;\n\n// Mimics System.HashCode, which is missing in NetStandard2.0.\n// Placed in root namespace to avoid ambiguous reference with System.HashCode\n\n// ReSharper disable once CheckNamespace\nnamespace BenchmarkDotNet\n{\n    internal struct HashCode\n    {\n        private int hashCode;\n\n        public void Add<T>(T value)\n        {\n            hashCode = Hash(hashCode, value);\n        }\n\n        public void Add<T>(T value, IEqualityComparer<T> comparer)\n        {\n            hashCode = Hash(hashCode, value, comparer);\n        }\n\n        public readonly int ToHashCode() => hashCode;\n\n        public static int Combine<T1>(T1 value1)\n        {\n            int hashCode = 0;\n            hashCode = Hash(hashCode, value1);\n            return hashCode;\n        }\n\n        public static int Combine<T1, T2>(T1 value1, T2 value2)\n        {\n            int hashCode = 0;\n            hashCode = Hash(hashCode, value1);\n            hashCode = Hash(hashCode, value2);\n            return hashCode;\n        }\n\n        public static int Combine<T1, T2, T3>(T1 value1, T2 value2, T3 value3)\n        {\n            int hashCode = 0;\n            hashCode = Hash(hashCode, value1);\n            hashCode = Hash(hashCode, value2);\n            hashCode = Hash(hashCode, value3);\n            return hashCode;\n        }\n\n        public static int Combine<T1, T2, T3, T4>(T1 value1, T2 value2, T3 value3, T4 value4)\n        {\n            int hashCode = 0;\n            hashCode = Hash(hashCode, value1);\n            hashCode = Hash(hashCode, value2);\n            hashCode = Hash(hashCode, value3);\n            hashCode = Hash(hashCode, value4);\n            return hashCode;\n        }\n\n        public static int Combine<T1, T2, T3, T4, T5>(T1 value1, T2 value2, T3 value3, T4 value4, T5 value5)\n        {\n            int hashCode = 0;\n            hashCode = Hash(hashCode, value1);\n            hashCode = Hash(hashCode, value2);\n            hashCode = Hash(hashCode, value3);\n            hashCode = Hash(hashCode, value4);\n            hashCode = Hash(hashCode, value5);\n            return hashCode;\n        }\n\n        public static int Combine<T1, T2, T3, T4, T5, T6>(T1 value1, T2 value2, T3 value3, T4 value4, T5 value5, T6 value6)\n        {\n            int hashCode = 0;\n            hashCode = Hash(hashCode, value1);\n            hashCode = Hash(hashCode, value2);\n            hashCode = Hash(hashCode, value3);\n            hashCode = Hash(hashCode, value4);\n            hashCode = Hash(hashCode, value5);\n            hashCode = Hash(hashCode, value6);\n            return hashCode;\n        }\n\n        public static int Combine<T1, T2, T3, T4, T5, T6, T7>(T1 value1, T2 value2, T3 value3, T4 value4, T5 value5, T6 value6, T7 value7)\n        {\n            int hashCode = 0;\n            hashCode = Hash(hashCode, value1);\n            hashCode = Hash(hashCode, value2);\n            hashCode = Hash(hashCode, value3);\n            hashCode = Hash(hashCode, value4);\n            hashCode = Hash(hashCode, value5);\n            hashCode = Hash(hashCode, value6);\n            hashCode = Hash(hashCode, value7);\n            return hashCode;\n        }\n\n        public static int Combine<T1, T2, T3, T4, T5, T6, T7, T8>(T1 value1, T2 value2, T3 value3, T4 value4, T5 value5, T6 value6, T7 value7, T8 value8)\n        {\n            int hashCode = 0;\n            hashCode = Hash(hashCode, value1);\n            hashCode = Hash(hashCode, value2);\n            hashCode = Hash(hashCode, value3);\n            hashCode = Hash(hashCode, value4);\n            hashCode = Hash(hashCode, value5);\n            hashCode = Hash(hashCode, value6);\n            hashCode = Hash(hashCode, value7);\n            hashCode = Hash(hashCode, value8);\n            return hashCode;\n        }\n\n        public static int Combine<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(T1 value1, T2 value2, T3 value3, T4 value4, T5 value5, T6 value6, T7 value7,\n            T8 value8, T9 value9, T10 value10)\n        {\n            int hashCode = 0;\n            hashCode = Hash(hashCode, value1);\n            hashCode = Hash(hashCode, value2);\n            hashCode = Hash(hashCode, value3);\n            hashCode = Hash(hashCode, value4);\n            hashCode = Hash(hashCode, value5);\n            hashCode = Hash(hashCode, value6);\n            hashCode = Hash(hashCode, value7);\n            hashCode = Hash(hashCode, value8);\n            hashCode = Hash(hashCode, value9);\n            hashCode = Hash(hashCode, value10);\n            return hashCode;\n        }\n\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        private static int Hash<T>(int hashCode, T value)\n        {\n            unchecked\n            {\n                return (hashCode * 397) ^ (value?.GetHashCode() ?? 0);\n            }\n        }\n\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        private static int Hash<T>(int hashCode, T value, IEqualityComparer<T> comparer)\n        {\n            unchecked\n            {\n                return (hashCode * 397) ^ (value is null ? 0 : (comparer?.GetHashCode(value) ?? value.GetHashCode()));\n            }\n        }\n\n#pragma warning disable CS0809 // Obsolete member 'HashCode.GetHashCode()' overrides non-obsolete member 'object.GetHashCode()'\n        [Obsolete(\"HashCode is a mutable struct and should not be compared with other HashCodes. Use ToHashCode to retrieve the computed hash code.\",\n            error: true)]\n        [EditorBrowsable(EditorBrowsableState.Never)]\n        public override int GetHashCode() => throw new NotSupportedException();\n\n        [Obsolete(\"HashCode is a mutable struct and should not be compared with other HashCodes.\", error: true)]\n        [EditorBrowsable(EditorBrowsableState.Never)]\n        public override bool Equals(object? obj) => throw new NotSupportedException();\n#pragma warning restore CS0809 // Obsolete member 'HashCode.GetHashCode()' overrides non-obsolete member 'object.GetHashCode()'\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Helpers/LinuxOsReleaseHelper.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing BenchmarkDotNet.Extensions;\n\nnamespace BenchmarkDotNet.Helpers\n{\n    internal static class LinuxOsReleaseHelper\n    {\n        public static string? GetNameByOsRelease(string[] lines)\n        {\n            try\n            {\n                var values = new Dictionary<string, string>();\n                foreach (string line in lines)\n                {\n                    string[] parts = line.Split(['='], 2);\n\n                    if (parts.Length == 2)\n                    {\n                        string key = parts[0].Trim();\n                        string value = parts[1].Trim();\n\n                        // remove quotes if value is quoted\n                        if (value.Length >= 2 &&\n                            ((value.StartsWith(\"\\\"\") && value.EndsWith(\"\\\"\")) ||\n                             (value.StartsWith(\"'\") && value.EndsWith(\"'\"))))\n                        {\n                            value = value.Substring(1, value.Length - 2);\n                        }\n\n                        values[key] = value;\n                    }\n                }\n\n                string? id = values.GetValueOrDefault(\"ID\");\n                string? name = values.GetValueOrDefault(\"NAME\");\n                string? version = values.GetValueOrDefault(\"VERSION\");\n\n                string[] idsWithExtendedVersion = [\"ubuntu\", \"linuxmint\", \"solus\", \"kali\"];\n                if (id != null && idsWithExtendedVersion.Contains(id) && version.IsNotBlank() && name.IsNotBlank())\n                    return name + \" \" + version;\n\n                string? prettyName = values.GetValueOrDefault(\"PRETTY_NAME\");\n                if (prettyName != null)\n                    return prettyName;\n\n                if (name != null && version != null)\n                    return name + \" \" + version;\n\n                if (name != null)\n                    return name;\n\n                if (id != null)\n                    return id;\n\n                return null;\n            }\n            catch (Exception)\n            {\n                return null;\n            }\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Helpers/PowerManagementHelper.cs",
    "content": "﻿using System;\nusing System.Diagnostics.CodeAnalysis;\nusing System.Runtime.InteropServices;\nusing System.Text;\n\nnamespace BenchmarkDotNet.Helpers\n{\n    [SuppressMessage(\"ReSharper\", \"InconsistentNaming\")]\n    internal class PowerManagementHelper\n    {\n        private const uint ErrorMoreData = 234;\n        private const uint SuccessCode = 0;\n\n        internal static Guid? CurrentPlan\n        {\n            get\n            {\n                IntPtr activeGuidPtr = IntPtr.Zero;\n                uint res = PowerGetActiveScheme(IntPtr.Zero, ref activeGuidPtr);\n                if (res != SuccessCode)\n                    return null;\n\n                return Marshal.PtrToStructure<Guid>(activeGuidPtr);\n            }\n        }\n\n        internal static string CurrentPlanFriendlyName\n        {\n            get\n            {\n                uint buffSize = 0;\n                StringBuilder buffer = new StringBuilder();\n                IntPtr activeGuidPtr = IntPtr.Zero;\n                uint res = PowerGetActiveScheme(IntPtr.Zero, ref activeGuidPtr);\n                if (res != SuccessCode)\n                    return \"\";\n                res = PowerReadFriendlyName(IntPtr.Zero, activeGuidPtr, IntPtr.Zero, IntPtr.Zero, buffer, ref buffSize);\n                if (res == ErrorMoreData)\n                {\n                    buffer.Capacity = (int)buffSize;\n                    res = PowerReadFriendlyName(IntPtr.Zero, activeGuidPtr,\n                        IntPtr.Zero, IntPtr.Zero, buffer, ref buffSize);\n                }\n                if (res != SuccessCode)\n                    return \"\";\n\n                return buffer.ToString();\n            }\n        }\n\n        internal static bool Set(Guid newPolicy)\n        {\n            return PowerSetActiveScheme(IntPtr.Zero, ref newPolicy) == 0;\n        }\n\n        [DllImport(\"powrprof.dll\", CharSet = CharSet.Unicode, ExactSpelling = true)]\n        private static extern uint PowerReadFriendlyName(IntPtr RootPowerKey, IntPtr SchemeGuid, IntPtr SubGroupOfPowerSettingGuid, IntPtr PowerSettingGuid, StringBuilder Buffer, ref uint BufferSize);\n\n        [DllImport(\"powrprof.dll\", ExactSpelling = true)]\n        private static extern int PowerSetActiveScheme(IntPtr ReservedZero, ref Guid policyGuid);\n\n        [DllImport(\"powrprof.dll\", ExactSpelling = true)]\n        private static extern uint PowerGetActiveScheme(IntPtr UserRootPowerKey, ref IntPtr ActivePolicyGuid);\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Helpers/PowerShellLocator.cs",
    "content": "﻿using System;\nusing System.IO;\nusing System.Linq;\nusing System.Runtime.Versioning;\nusing System.Text.RegularExpressions;\nusing BenchmarkDotNet.Detectors;\n\nnamespace BenchmarkDotNet.Helpers;\n\n/// <summary>\n/// Locates PowerShell on a system, currently only supports on Windows.\n/// </summary>\ninternal class PowerShellLocator\n{\n    private static readonly string WindowsPowershellPath =\n        $\"{Environment.SystemDirectory}{Path.DirectorySeparatorChar}WindowsPowerShell{Path.DirectorySeparatorChar}\" +\n        $\"v1.0{Path.DirectorySeparatorChar}powershell.exe\";\n\n        [SupportedOSPlatform(\"windows\")]\n    internal static string? LocateOnWindows()\n    {\n        if (OsDetector.IsWindows() == false)\n            return null;\n\n        string powershellPath;\n\n        try\n        {\n            string programFiles = Environment.Is64BitOperatingSystem\n                ? Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles)\n                : Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86);\n\n            string powershell7PlusPath = $\"{programFiles}{Path.DirectorySeparatorChar}Powershell{Path.DirectorySeparatorChar}\";\n\n            bool checkForPowershell7Plus = true;\n\n            if (Directory.Exists(powershell7PlusPath))\n            {\n                string[] subDirectories = Directory.EnumerateDirectories(powershell7PlusPath, \"*\", SearchOption.AllDirectories)\n                    .ToArray();\n\n                //Use the highest number string directory for PowerShell so that we get the newest major PowerShell version\n                // Example version directories are 6, 7, and in the future 8.\n                string? subDirectory = subDirectories.Where(x => Regex.IsMatch(x, \"[0-9]\"))\n                    .Select(x => x)\n                    .OrderByDescending(x => x)\n                    .FirstOrDefault();\n\n                if (subDirectory is not null)\n                {\n                    powershell7PlusPath = $\"{subDirectory}{Path.DirectorySeparatorChar}pwsh.exe\";\n                }\n                else\n                {\n                    checkForPowershell7Plus = false;\n                }\n            }\n\n            // Optimistically, use Cross-platform new PowerShell when available but fallback to Windows PowerShell if not available.\n            if (checkForPowershell7Plus)\n            {\n                powershellPath = File.Exists(powershell7PlusPath) ? powershell7PlusPath : WindowsPowershellPath;\n            }\n            else\n            {\n                powershellPath = WindowsPowershellPath;\n            }\n\n            if (File.Exists(powershellPath) == false)\n                powershellPath = \"PowerShell\";\n        }\n        catch\n        {\n            powershellPath = \"PowerShell\";\n        }\n\n        return powershellPath;\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Helpers/ProcessHelper.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Collections.Immutable;\nusing System.Diagnostics;\nusing System.Diagnostics.CodeAnalysis;\nusing System.IO;\nusing BenchmarkDotNet.Detectors;\nusing BenchmarkDotNet.Loggers;\n\nnamespace BenchmarkDotNet.Helpers\n{\n    internal static class ProcessHelper\n    {\n        /// <summary>\n        /// Run external process and return the console output.\n        /// In the case of any exception, null will be returned.\n        /// </summary>\n        internal static string? RunAndReadOutput(string fileName, string arguments = \"\", ILogger? logger = null,\n            Dictionary<string, string>? environmentVariables = null)\n        {\n            var processStartInfo = new ProcessStartInfo\n            {\n                FileName = fileName,\n                WorkingDirectory = \"\",\n                Arguments = arguments,\n                UseShellExecute = false,\n                CreateNoWindow = true,\n                RedirectStandardOutput = true,\n            };\n\n            foreach (var variable in environmentVariables ?? [])\n                processStartInfo.Environment[variable.Key] = variable.Value;\n\n            using (var process = new Process { StartInfo = processStartInfo })\n            using (new ConsoleExitHandler(process, logger ?? NullLogger.Instance))\n            {\n                try\n                {\n                    process.Start();\n                }\n                catch (Exception)\n                {\n                    return null;\n                }\n                string output = process.StandardOutput.ReadToEnd();\n                process.WaitForExit();\n                return output;\n            }\n        }\n\n        internal static (int exitCode, ImmutableArray<string> output) RunAndReadOutputLineByLine(string fileName, string arguments = \"\", string workingDirectory = \"\",\n            Dictionary<string, string>? environmentVariables = null, bool includeErrors = false, ILogger? logger = null)\n        {\n            var processStartInfo = new ProcessStartInfo\n            {\n                FileName = fileName,\n                WorkingDirectory = workingDirectory,\n                Arguments = arguments,\n                UseShellExecute = false,\n                CreateNoWindow = true,\n                RedirectStandardOutput = true,\n                RedirectStandardError = true\n            };\n\n            foreach (var environmentVariable in environmentVariables ?? [])\n                processStartInfo.Environment[environmentVariable.Key] = environmentVariable.Value;\n\n            using (var process = new Process { StartInfo = processStartInfo })\n            using (var outputReader = new AsyncProcessOutputReader(process))\n            using (new ConsoleExitHandler(process, logger ?? NullLogger.Instance))\n            {\n                process.Start();\n\n                outputReader.BeginRead();\n\n                process.WaitForExit();\n\n                outputReader.StopRead();\n\n                var output = includeErrors ? outputReader.GetOutputAndErrorLines() : outputReader.GetOutputLines();\n\n                return (process.ExitCode, output);\n            }\n        }\n\n        internal static bool TestCommandExists(string commandName, string arguments = \"--version\")\n        {\n            // Check command existence by using where/which command.\n            try\n            {\n                using var process = Process.Start(new ProcessStartInfo\n                {\n                    FileName = OsDetector.IsWindows() ? \"where\" : \"which\",\n                    Arguments = commandName,\n                    UseShellExecute = false,\n                    CreateNoWindow = true\n                })!;\n                process.WaitForExit();\n                return process.ExitCode == 0;\n            }\n            catch\n            {\n                // On some environment. which command is not installed. (e.g. Alpine Linux)\n            }\n\n            // Check command existence by executing actual command with --version argument.\n            try\n            {\n                using var process = Process.Start(new ProcessStartInfo\n                {\n                    FileName = commandName,\n                    Arguments = arguments,\n                    UseShellExecute = false,\n                    CreateNoWindow = true\n                })!;\n                process.WaitForExit();\n                return process.ExitCode == 0;\n            }\n            catch\n            {\n                return false;\n            }\n        }\n\n        internal static bool TryResolveExecutableInPath(string? value, [NotNullWhen(true)] out string? result)\n        {\n            result = value!;\n\n            if (string.IsNullOrWhiteSpace(value))\n                return false;\n\n            if (File.Exists(value))\n                return true;\n\n            // Typed to char[] because it could be a string or char[] with newer .net versions\n            var directories = Environment.GetEnvironmentVariable(\"PATH\")!\n                .Split((char[])[Path.PathSeparator], StringSplitOptions.RemoveEmptyEntries);\n\n            if (OsDetector.IsWindows())\n            {\n                var extensions = Environment.GetEnvironmentVariable(\"PATHEXT\")!\n                    .Split((char[])[Path.PathSeparator], StringSplitOptions.RemoveEmptyEntries);\n\n                foreach (var directory in directories)\n                {\n                    foreach (var ext in extensions)\n                    {\n                        var candidate = Path.Combine(directory, value + ext);\n                        if (File.Exists(candidate))\n                        {\n                            result = candidate;\n                            return true;\n                        }\n                    }\n                }\n            }\n            else\n            {\n                foreach (var directory in directories)\n                {\n                    var candidate = Path.Combine(directory, value);\n                    if (File.Exists(Path.Combine(directory, value)))\n                    {\n                        result = candidate;\n                        return true;\n                    }\n                }\n            }\n\n            return false;\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Helpers/Reflection.Emit/EmitParameterInfo.cs",
    "content": "﻿using System;\nusing System.Reflection;\n\nnamespace BenchmarkDotNet.Helpers.Reflection.Emit\n{\n    internal class EmitParameterInfo : ParameterInfo\n    {\n        public static ParameterInfo CreateReturnVoidParameter()\n        {\n            return CreateReturnParameter(typeof(void), ParameterAttributes.None);\n        }\n\n        public static ParameterInfo CreateReturnParameter(Type parameterType)\n        {\n            return CreateReturnParameter(parameterType, ParameterAttributes.None);\n        }\n\n        public static ParameterInfo CreateReturnParameter(Type parameterType, ParameterAttributes parameterAttributes)\n        {\n            return new EmitParameterInfo(-1, null, parameterType, parameterAttributes, null);\n        }\n\n        public EmitParameterInfo(int position, string name, Type parameterType)\n            : this(position, name, parameterType, ParameterAttributes.None, null)\n        {\n        }\n\n        public EmitParameterInfo(\n            int position,\n            string? name,\n            Type parameterType,\n            ParameterAttributes parameterAttributes,\n            MemberInfo? member)\n        {\n            PositionImpl = position;\n            NameImpl = name;\n            ClassImpl = parameterType;\n            AttrsImpl = parameterAttributes;\n            if (member != null)\n                MemberImpl = member;\n        }\n\n        public ParameterInfo SetMember(MemberInfo member)\n        {\n            MemberImpl = member;\n            return this;\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Helpers/Reflection.Emit/IlGeneratorCallExtensions.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Reflection;\nusing System.Reflection.Emit;\n\nnamespace BenchmarkDotNet.Helpers.Reflection.Emit\n{\n    internal static class IlGeneratorCallExtensions\n    {\n        public static void EmitStaticCall(\n            this ILGenerator ilBuilder,\n            MethodInfo methodToCall,\n            params LocalBuilder[] argLocals)\n        {\n            if (!methodToCall.IsStatic)\n                throw new ArgumentException($\"Method {methodToCall} should be static method.\");\n\n            EmitCallCore(ilBuilder, null, methodToCall, argLocals);\n        }\n\n        public static void EmitInstanceCallThisValueOnStack(\n            this ILGenerator ilBuilder,\n            LocalBuilder optionalLocalThis,\n            MethodInfo methodToCall,\n            params LocalBuilder[] argLocals) =>\n            EmitInstanceCallThisValueOnStack(ilBuilder, optionalLocalThis, methodToCall, argLocals, false);\n\n        public static void EmitInstanceCallThisValueOnStack(\n            this ILGenerator ilBuilder,\n            LocalBuilder? optionalLocalThis,\n            MethodInfo methodToCall,\n            IEnumerable<LocalBuilder> argLocals,\n            bool forceDirectCall = false)\n        {\n            if (methodToCall.DeclaringType == null)\n                throw new ArgumentException($\"The {nameof(methodToCall)} should have non-null {nameof(methodToCall.DeclaringType)}.\");\n\n            if (methodToCall.IsStatic)\n                throw new ArgumentException($\"Method {methodToCall} should be instance method.\");\n\n            /*\n                IL_0005: stloc.s 11\n                ...\n                IL_0007: callvirt instance valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter`1<!0> class [mscorlib]System.Threading.Tasks.Task`1<int32>::GetAwaiter()\n                --or-\n                IL_000d: ldloca.s 11\n                IL_000f: call instance !0 valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter`1<int32>::GetResult()\n            */\n            if (methodToCall.DeclaringType.IsValueType)\n            {\n                ArgumentNullException.ThrowIfNull(optionalLocalThis);\n\n                ilBuilder.EmitStloc(optionalLocalThis);\n                EmitCallCore(ilBuilder, optionalLocalThis, methodToCall, argLocals, forceDirectCall);\n            }\n            else\n            {\n                EmitCallCore(ilBuilder, null, methodToCall, argLocals, forceDirectCall);\n            }\n        }\n\n        private static void EmitCallCore(\n            this ILGenerator ilBuilder,\n            LocalBuilder? optionalLocalThis,\n            MethodInfo methodToCall,\n            IEnumerable<LocalBuilder> argLocals,\n            bool forceDirectCall = false)\n        {\n            if (methodToCall.DeclaringType == null)\n                throw new ArgumentException($\"The {nameof(methodToCall)} should have non-null {nameof(methodToCall.DeclaringType)}.\");\n\n            /*\n                IL_0000: call class [mscorlib]System.Threading.Tasks.Task [mscorlib]System.Threading.Tasks.Task::get_CompletedTask()\n                -or-\n                IL_0007: callvirt instance valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter`1<!0> class [mscorlib]System.Threading.Tasks.Task`1<int32>::GetAwaiter()\n                --or-\n                IL_000d: ldloca.s 0\n                IL_000f: call instance !0 valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter`1<int32>::GetResult()\n            */\n            if (methodToCall.IsStatic)\n            {\n                if (optionalLocalThis != null)\n                    throw new ArgumentException($\"The {nameof(optionalLocalThis)} should be null for static calls\", nameof(optionalLocalThis));\n\n                ilBuilder.EmitLdLocals(argLocals);\n                ilBuilder.Emit(OpCodes.Call, methodToCall);\n            }\n            else if (methodToCall.DeclaringType.IsValueType)\n            {\n                ArgumentNullException.ThrowIfNull(optionalLocalThis);\n\n                ilBuilder.EmitLdloca(optionalLocalThis);\n                ilBuilder.EmitLdLocals(argLocals);\n                ilBuilder.Emit(OpCodes.Call, methodToCall);\n            }\n            else\n            {\n                if (optionalLocalThis != null)\n                    ilBuilder.EmitLdloc(optionalLocalThis);\n\n                ilBuilder.EmitLdLocals(argLocals);\n\n                if (forceDirectCall)\n                    ilBuilder.Emit(OpCodes.Call, methodToCall);\n                else\n                    ilBuilder.Emit(OpCodes.Callvirt, methodToCall);\n            }\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Helpers/Reflection.Emit/IlGeneratorEmitOpExtensions.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Reflection;\nusing System.Reflection.Emit;\n\nnamespace BenchmarkDotNet.Helpers.Reflection.Emit\n{\n    internal static class IlGeneratorEmitOpExtensions\n    {\n        public static void EmitStloc(this ILGenerator ilBuilder, LocalBuilder local)\n        {\n            switch (local.LocalIndex)\n            {\n                case 0:\n                    ilBuilder.Emit(OpCodes.Stloc_0);\n                    break;\n                case 1:\n                    ilBuilder.Emit(OpCodes.Stloc_1);\n                    break;\n                case 2:\n                    ilBuilder.Emit(OpCodes.Stloc_2);\n                    break;\n                case 3:\n                    ilBuilder.Emit(OpCodes.Stloc_3);\n                    break;\n                case var i when i < 255:\n                    ilBuilder.Emit(OpCodes.Stloc_S, (byte)local.LocalIndex);\n                    break;\n                default:\n                    ilBuilder.Emit(OpCodes.Stloc, checked((short)local.LocalIndex));\n                    break;\n            }\n        }\n\n        public static void EmitLdloc(this ILGenerator ilBuilder, LocalBuilder local)\n        {\n            switch (local.LocalIndex)\n            {\n                case 0:\n                    ilBuilder.Emit(OpCodes.Ldloc_0);\n                    break;\n                case 1:\n                    ilBuilder.Emit(OpCodes.Ldloc_1);\n                    break;\n                case 2:\n                    ilBuilder.Emit(OpCodes.Ldloc_2);\n                    break;\n                case 3:\n                    ilBuilder.Emit(OpCodes.Ldloc_3);\n                    break;\n                case var i when i < 255:\n                    ilBuilder.Emit(OpCodes.Ldloc_S, (byte)local.LocalIndex);\n                    break;\n                default:\n                    ilBuilder.Emit(OpCodes.Ldloc, checked((short)local.LocalIndex));\n                    break;\n            }\n        }\n\n        public static void EmitLdloca(this ILGenerator ilBuilder, LocalBuilder local)\n        {\n            switch (local.LocalIndex)\n            {\n                case var i when i < 255:\n                    ilBuilder.Emit(OpCodes.Ldloca_S, (byte)local.LocalIndex);\n                    break;\n                default:\n                    ilBuilder.Emit(OpCodes.Ldloca, checked((short)local.LocalIndex));\n                    break;\n            }\n        }\n\n        public static void EmitLdargs(this ILGenerator ilBuilder, IEnumerable<ParameterInfo> arguments)\n        {\n            foreach (var argument in arguments)\n            {\n                ilBuilder.EmitLdarg(argument);\n            }\n        }\n\n        public static void EmitLdLocals(this ILGenerator ilBuilder, IEnumerable<LocalBuilder> locals)\n        {\n            foreach (var local in locals)\n            {\n                ilBuilder.EmitLdloc(local);\n            }\n        }\n\n        public static void EmitLdarg(this ILGenerator ilBuilder, ParameterInfo argument)\n        {\n            // this is passed as Ldarg_0\n            var position = argument.Position;\n            if (!((MethodBase)argument.Member).IsStatic)\n                position++;\n\n            switch (position)\n            {\n                case 0:\n                    ilBuilder.Emit(OpCodes.Ldarg_0);\n                    break;\n                case 1:\n                    ilBuilder.Emit(OpCodes.Ldarg_1);\n                    break;\n                case 2:\n                    ilBuilder.Emit(OpCodes.Ldarg_2);\n                    break;\n                case 3:\n                    ilBuilder.Emit(OpCodes.Ldarg_3);\n                    break;\n                case var i when i < 255:\n                    ilBuilder.Emit(OpCodes.Ldarg_S, (byte)position);\n                    break;\n                default:\n                    ilBuilder.Emit(OpCodes.Ldarg, checked((short)position));\n                    break;\n            }\n        }\n\n        public static void EmitStarg(this ILGenerator ilBuilder, ParameterInfo argument)\n        {\n            var position = argument.Position;\n            if (!((MethodBase) argument.Member).IsStatic)\n                position++;\n\n            if (position < 255)\n            {\n                ilBuilder.Emit(OpCodes.Starg_S, (byte) position);\n            }\n            else\n            {\n                ilBuilder.Emit(OpCodes.Starg, checked((short) position));\n            }\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Helpers/Reflection.Emit/IlGeneratorStatementExtensions.cs",
    "content": "﻿using System;\nusing System.Reflection;\nusing System.Reflection.Emit;\n\nnamespace BenchmarkDotNet.Helpers.Reflection.Emit\n{\n    internal static class IlGeneratorStatementExtensions\n    {\n        public static void EmitCallBaseParameterlessCtor(this ILGenerator ilGenerator, ConstructorBuilder constructorBuilder)\n        {\n            if (constructorBuilder.IsStatic)\n                throw new ArgumentException($\"Can not emit base call for {constructorBuilder}\");\n            if (constructorBuilder.DeclaringType == null)\n                throw new ArgumentException($\"The {nameof(constructorBuilder)} should have non-null {nameof(constructorBuilder.DeclaringType)}.\");\n\n            /*\n                IL_0000: ldarg.0\n                IL_0001: call instance void [BenchmarkDotNet]BenchmarkDotNet.Samples.SampleBenchmark::.ctor()\n            */\n            var baseCtor = constructorBuilder.DeclaringType.BaseType?.GetConstructor([]);\n            if (baseCtor == null)\n                throw new ArgumentException(\n                    $\"Base type of {constructorBuilder.DeclaringType} has no public parameterless constructor.\");\n\n            ilGenerator.Emit(OpCodes.Ldarg_0);\n            ilGenerator.Emit(OpCodes.Call, baseCtor);\n        }\n\n        public static void EmitCtorReturn(this ILGenerator ilBuilder, ConstructorBuilder methodBuilder)\n        {\n            // IL_0000: ret\n            ilBuilder.Emit(OpCodes.Ret);\n        }\n\n        public static void EmitVoidReturn(this ILGenerator ilBuilder, MethodBuilder methodBuilder)\n        {\n            if (methodBuilder.ReturnType != typeof(void))\n                throw new InvalidOperationException(\n                    $\"[BUG] Attempt to emit empty return for non-void method {methodBuilder.Name}.\");\n\n            // IL_0000: ret\n            ilBuilder.Emit(OpCodes.Ret);\n        }\n\n        public static void EmitSetDelegateToThisField(\n            this ILGenerator ilBuilder,\n            FieldBuilder delegateField,\n            MethodInfo delegateMethod)\n        {\n            if (delegateField.IsStatic)\n                throw new ArgumentException(\"The field should be instance field\", nameof(delegateField));\n\n            if (delegateMethod != null)\n            {\n                /*\n                    // globalSetupAction = base.GlobalSetup; // instance\n                    IL_0006: ldarg.0\n                    IL_0007: ldarg.0\n                    IL_0008: ldftn instance void [BenchmarkDotNet]BenchmarkDotNet.Samples.SampleBenchmark::GlobalSetup()\n                    IL_000e: newobj instance void [mscorlib]System.Action::.ctor(object, native int)\n                    IL_0013: stfld class [mscorlib]System.Action BenchmarkDotNet.Autogenerated.Runnable_0::globalSetupAction\n                    // globalCleanupAction = BaseClass.GlobalCleanup; // static\n                    IL_0018: ldarg.0\n                    IL_0019: ldnull\n                    IL_001a: ldftn void [BenchmarkDotNet]BenchmarkDotNet.Samples.SampleBenchmark::GlobalCleanup()\n                    IL_0020: newobj instance void [mscorlib]System.Action::.ctor(object, native int)\n                    IL_0025: stfld class [mscorlib]System.Action BenchmarkDotNet.Autogenerated.Runnable_0::globalCleanupAction\n                 */\n                var delegateCtor = delegateField.FieldType.GetConstructor([typeof(object), typeof(IntPtr)]);\n                if (delegateCtor == null)\n                    throw new InvalidOperationException($\"Bug: field {delegateField.Name} is not a delegate field.\");\n\n                ilBuilder.Emit(OpCodes.Ldarg_0);\n                ilBuilder.Emit(delegateMethod.IsStatic ? OpCodes.Ldnull : OpCodes.Ldarg_0);\n                ilBuilder.Emit(OpCodes.Ldftn, delegateMethod);\n                ilBuilder.Emit(OpCodes.Newobj, delegateCtor);\n                ilBuilder.Emit(OpCodes.Stfld, delegateField);\n            }\n            else\n            {\n                ilBuilder.Emit(OpCodes.Ldarg_0);\n                ilBuilder.Emit(OpCodes.Ldnull);\n                ilBuilder.Emit(OpCodes.Stfld, delegateField);\n            }\n        }\n\n        public static void EmitLoopBeginFromArgToZero(\n            this ILGenerator ilBuilder,\n            out Label loopStartLabel,\n            out Label loopHeadLabel)\n        {\n            loopStartLabel = ilBuilder.DefineLabel();\n            loopHeadLabel = ilBuilder.DefineLabel();\n            // invokeCount passed as arg\n            /*\n                // while (--invokeCount >= 0)\n            */\n\n            // IL_0000: br.s IL_000e // loop head: IL_000e // we use long jump\n            ilBuilder.Emit(OpCodes.Br, loopHeadLabel);\n\n            // loop start (head: IL_000e)\n            ilBuilder.MarkLabel(loopStartLabel);\n        }\n\n        public static void EmitLoopEndFromArgToZero(\n            this ILGenerator ilBuilder,\n            Label loopStartLabel,\n            Label loopHeadLabel,\n            ParameterInfo arg)\n        {\n            // invokeCount passed as arg\n            /*\n                // while (--invokeCount >= 0)\n                IL_0008: ldarg.1\n                IL_0009: ldc.i4.1\n                IL_000a: conv.i8\n                IL_000b: sub\n                IL_000c: dup\n                IL_000d: starg.s invokeCount\n                IL_000f: ldc.i4.0\n                IL_0010: conv.i8\n                IL_0011: bge.s IL_0002\n                // end loop\n             */\n\n            // loop head\n            ilBuilder.MarkLabel(loopHeadLabel);\n            ilBuilder.EmitLdarg(arg);\n            ilBuilder.Emit(OpCodes.Ldc_I4_1);\n            ilBuilder.Emit(OpCodes.Conv_I8);\n            ilBuilder.Emit(OpCodes.Sub);\n            ilBuilder.Emit(OpCodes.Dup);\n            ilBuilder.EmitStarg(arg);\n            ilBuilder.Emit(OpCodes.Ldc_I4_0);\n            ilBuilder.Emit(OpCodes.Conv_I8);\n            ilBuilder.Emit(OpCodes.Bge, loopStartLabel);\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Helpers/Reflection.Emit/MethodBuilderExtensions.cs",
    "content": "﻿using BenchmarkDotNet.Portability;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Reflection;\nusing System.Reflection.Emit;\n\nnamespace BenchmarkDotNet.Helpers.Reflection.Emit\n{\n    internal static class MethodBuilderExtensions\n    {\n        public static ParameterInfo[] GetEmitParameters(this MethodBuilder method, IEnumerable<ParameterInfo> signatureParameters) =>\n            signatureParameters\n                .Select(p =>\n                    (ParameterInfo)new EmitParameterInfo(\n                        p.Position,\n                        p.Name,\n                        p.ParameterType,\n                        p.Attributes,\n                        method))\n                .ToArray();\n\n        public static MethodBuilder SetNoInliningImplementationFlag(this MethodBuilder methodBuilder)\n        {\n            methodBuilder.SetImplementationFlags(\n                methodBuilder.GetMethodImplementationFlags() | MethodImplAttributes.NoInlining);\n\n            return methodBuilder;\n        }\n\n        public static MethodBuilder SetNoOptimizationImplementationFlag(this MethodBuilder methodBuilder)\n        {\n            methodBuilder.SetImplementationFlags(\n                methodBuilder.GetMethodImplementationFlags() | MethodImplAttributes.NoOptimization);\n\n            return methodBuilder;\n        }\n\n        public static MethodBuilder SetAggressiveOptimizationImplementationFlag(this MethodBuilder methodBuilder)\n        {\n            methodBuilder.SetImplementationFlags(\n                methodBuilder.GetMethodImplementationFlags() | CodeGenHelper.AggressiveOptimizationOptionForEmit);\n\n            return methodBuilder;\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Helpers/Reflection.Emit/TypeBuilderExtensions.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing System.Reflection;\nusing System.Reflection.Emit;\n\nnamespace BenchmarkDotNet.Helpers.Reflection.Emit\n{\n    internal static class TypeBuilderExtensions\n    {\n        private static void DefineParameters(this ConstructorBuilder constructorBuilder, params ParameterInfo[] parameters)\n        {\n            foreach (var parameterInfo in parameters)\n            {\n                constructorBuilder.DefineParameter(parameterInfo.Position + 1, parameterInfo.Attributes, parameterInfo.Name);\n            }\n        }\n\n        private static void DefineParameters(this MethodBuilder methodBuilder, ParameterInfo returnType, params ParameterInfo[] parameters)\n        {\n            foreach (var parameterInfo in parameters)\n            {\n                methodBuilder.DefineParameter(parameterInfo.Position + 1, parameterInfo.Attributes, parameterInfo.Name);\n            }\n\n            methodBuilder.DefineParameter(0, returnType.Attributes, \"\");\n        }\n\n        public static ConstructorBuilder DefinePublicInstanceCtor(this TypeBuilder typeBuilder, params ParameterInfo[] parameters)\n        {\n            // .method public hidebysig specialname rtspecialname\n            //     instance void.ctor() cil managed\n            var result = typeBuilder.DefineConstructor(\n                MethodAttributes.Public\n                | MethodAttributes.HideBySig\n                | MethodAttributes.SpecialName\n                | MethodAttributes.RTSpecialName,\n                CallingConventions.HasThis,\n                parameters.Select(p => p.ParameterType).ToArray());\n            result.DefineParameters(parameters);\n\n            return result;\n        }\n\n        public static MethodBuilder DefinePublicNonVirtualVoidInstanceMethod(\n            this TypeBuilder typeBuilder,\n            string name,\n            params ParameterInfo[] parameters)\n        {\n            return DefineNonVirtualInstanceMethod(\n                typeBuilder,\n                name,\n                MethodAttributes.Public,\n                EmitParameterInfo.CreateReturnVoidParameter(),\n                parameters);\n        }\n\n        public static MethodBuilder DefinePrivateVoidInstanceMethod(\n            this TypeBuilder typeBuilder,\n            string name,\n            params ParameterInfo[] parameters)\n        {\n            return DefineNonVirtualInstanceMethod(\n                typeBuilder,\n                name,\n                MethodAttributes.Private,\n                EmitParameterInfo.CreateReturnVoidParameter(),\n                parameters);\n        }\n\n        public static MethodBuilder DefineNonVirtualInstanceMethod(\n            this TypeBuilder typeBuilder,\n            string name,\n            MethodAttributes visibility,\n            ParameterInfo returnType,\n            params ParameterInfo[] parameters)\n        {\n            // .method public hidebysig instance\n            var result = typeBuilder.DefineMethod(\n                name,\n                visibility\n                | MethodAttributes.HideBySig,\n                CallingConventions.HasThis,\n                returnType.ParameterType,\n                parameters.Select(p => p.ParameterType).ToArray()\n            );\n            result.DefineParameters(returnType, parameters);\n\n            return result;\n        }\n\n        public static MethodBuilder DefineStaticMethod(\n            this TypeBuilder typeBuilder,\n            string name,\n            MethodAttributes visibility,\n            ParameterInfo returnType,\n            params ParameterInfo[] parameters)\n        {\n            // .method public hidebysig static\n            var result = typeBuilder.DefineMethod(\n                name,\n                visibility\n                | MethodAttributes.HideBySig\n                | MethodAttributes.Static,\n                CallingConventions.Standard,\n                returnType.ParameterType,\n                parameters.Select(p => p.ParameterType).ToArray()\n            );\n            result.DefineParameters(returnType, parameters);\n\n            return result;\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Helpers/ResourceHelper.cs",
    "content": "﻿using System;\nusing System.IO;\nusing System.Reflection;\n\nnamespace BenchmarkDotNet.Helpers\n{\n    internal static class ResourceHelper\n    {\n        internal static string LoadTemplate(string name) => LoadResource(\"BenchmarkDotNet.Templates.\" + name);\n\n        internal static string LoadResource(string resourceName)\n        {\n            using (var stream = GetResourceStream(resourceName))\n            {\n                if (stream == null)\n                    throw new Exception($\"Resource {resourceName} not found\");\n                using (var reader = new StreamReader(stream))\n                    return reader.ReadToEnd();\n            }\n        }\n\n        private static Stream GetResourceStream(string resourceName)\n        {\n            return typeof(ResourceHelper).GetTypeInfo().Assembly.GetManifestResourceStream(resourceName)!;\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Helpers/SectionsHelper.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text.RegularExpressions;\n\nnamespace BenchmarkDotNet.Helpers\n{\n    internal static class SectionsHelper\n    {\n        public static Dictionary<string, string> ParseSection(string? content, char separator)\n        {\n            var values = new Dictionary<string, string>();\n            var list = content?.Split(['\\r', '\\n'], StringSplitOptions.RemoveEmptyEntries);\n            if (list != null)\n                foreach (string line in list)\n                    if (line.IndexOf(separator) != -1)\n                    {\n                        var lineParts = line.Split(separator);\n                        if (lineParts.Length >= 2)\n                            values[lineParts[0].Trim()] = lineParts[1].Trim();\n                    }\n            return values;\n        }\n\n        public static List<Dictionary<string, string>> ParseSections(string? content, char separator)\n        {\n            // wmic doubles the carriage return character due to a bug.\n            // Therefore, the * quantifier should be used to workaround it.\n            return\n                Regex.Split(content ?? \"\", \"(\\r*\\n){2,}\")\n                    .Select(s => ParseSection(s, separator))\n                    .Where(s => s.Count > 0)\n                    .ToList();\n        }\n\n        public static List<Dictionary<string, string>> ParseSectionsForPowershellWmi(string? content, char separator)\n        {\n            return\n                Regex.Split(content ?? \"\", \"(\\r*\\n)\")\n                    .Select(s => ParseSection(s, separator))\n                    .Where(s => s.Count > 0)\n                    .ToList();\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Helpers/SourceCodeHelper.cs",
    "content": "﻿using System;\nusing System.Diagnostics.CodeAnalysis;\nusing System.Globalization;\nusing System.Numerics;\nusing BenchmarkDotNet.Extensions;\nusing Perfolizer.Horology;\n\nnamespace BenchmarkDotNet.Helpers\n{\n    public static class SourceCodeHelper\n    {\n        public static string ToSourceCode(object? value)\n        {\n            switch (value) {\n                case null:\n                    return \"null\";\n                case bool b:\n                    return b.ToLowerCase();\n                case string text:\n                    return text.EscapeSpecialCharacters(true);\n                case char c:\n                    return c.EscapeSpecialCharacter(true);\n                case float f:\n                    return ToSourceCode(f);\n                case double d:\n                    return ToSourceCode(d);\n                case decimal f:\n                    return f.ToString(\"G\", CultureInfo.InvariantCulture) + \"m\";\n                case BigInteger bigInteger:\n                    return $\"System.Numerics.BigInteger.Parse(\\\"{bigInteger.ToString(CultureInfo.InvariantCulture)}\\\", System.Globalization.CultureInfo.InvariantCulture)\";\n                case DateTime dateTime:\n                    return $\"System.DateTime.Parse(\\\"{dateTime.ToString(CultureInfo.InvariantCulture)}\\\", System.Globalization.CultureInfo.InvariantCulture)\";\n                case Guid guid:\n                    return $\"System.Guid.Parse(\\\"{guid.ToString()}\\\")\";\n                // Multi-dimensional arrays are more complex, we only need single-dimension support for now.\n                case Array { Rank: 1 } array:\n                {\n                    var elementsSourceCode = new string[array.Length];\n                    for (int i = 0; i < array.Length; ++i)\n                    {\n                        elementsSourceCode[i] = ToSourceCode(array.GetValue(i));\n                    }\n                    return $\"new {array.GetType().GetElementType()!.GetCorrectCSharpTypeName()}[] {{ {string.Join(\", \", elementsSourceCode)} }}\";\n                }\n            }\n\n            var valueType = value.GetType();\n            if (valueType.IsEnum)\n                return $\"({valueType.GetCorrectCSharpTypeName()})({ToInvariantCultureString(value)})\";\n            if (value is Type type)\n                return \"typeof(\" + type.GetCorrectCSharpTypeName() + \")\";\n            if (!valueType.IsValueType)\n                return \"System.Activator.CreateInstance<\" + valueType.GetCorrectCSharpTypeName() + \">()\";\n\n            switch (value) {\n                case TimeInterval interval:\n                    return \"new Perfolizer.Horology.TimeInterval(\" + ToSourceCode(interval.Nanoseconds) + \")\";\n                case IntPtr ptr:\n                    return $\"new System.IntPtr({ptr})\";\n                case IFormattable formattable:\n                    return formattable.ToString(null, CultureInfo.InvariantCulture);\n            }\n\n            return value.ToString()!;\n        }\n\n        public static bool IsCompilationTimeConstant(object value)\n            => value == null || IsCompilationTimeConstant(value.GetType());\n\n        public static bool IsCompilationTimeConstant(Type type)\n        {\n            if (type == typeof(long) || type == typeof(ulong))\n                return true;\n            if (type == typeof(int) || type == typeof(uint))\n                return true;\n            if (type == typeof(short) || type == typeof(ushort))\n                return true;\n            if (type == typeof(byte) || type == typeof(sbyte))\n                return true;\n            if (type == typeof(bool))\n                return true;\n            if (type == typeof(string))\n                return true;\n            if (type == typeof(char))\n                return true;\n            if (type == typeof(float))\n                return true;\n            if (type == typeof(double))\n                return true;\n            if (type == typeof(decimal))\n                return true;\n            if (type.IsEnum)\n                return true;\n            if (type == typeof(Type))\n                return true;\n            if (type == typeof(TimeInterval))\n                return true;\n            if (type == typeof(IntPtr))\n                return true;\n            if (type == typeof(DateTime))\n                return true;\n            if (!type.IsValueType) // the difference!!\n                return false;\n            if (typeof(IFormattable).IsAssignableFrom(type))\n                return false;\n\n            return false;\n        }\n\n        [SuppressMessage(\"ReSharper\", \"CompareOfFloatsByEqualityOperator\")]\n        private static string ToSourceCode(double value)\n        {\n            if (double.IsNaN(value))\n                return \"System.Double.NaN\";\n            if (double.IsPositiveInfinity(value))\n                return \"System.Double.PositiveInfinity\";\n            if (double.IsNegativeInfinity(value))\n                return \"System.Double.NegativeInfinity\";\n            if (value == double.Epsilon)\n                return \"System.Double.Epsilon\";\n            if (value == double.MaxValue)\n                return \"System.Double.MaxValue\";\n            if (value == double.MinValue)\n                return \"System.Double.MinValue\";\n\n            return value.ToString(\"G\", CultureInfo.InvariantCulture) + \"d\";\n        }\n\n        [SuppressMessage(\"ReSharper\", \"CompareOfFloatsByEqualityOperator\")]\n        private static string ToSourceCode(float value)\n        {\n            if (float.IsNaN(value))\n                return \"System.Single.NaN\";\n            if (float.IsPositiveInfinity(value))\n                return \"System.Single.PositiveInfinity\";\n            if (float.IsNegativeInfinity(value))\n                return \"System.Single.NegativeInfinity\";\n            if (value == float.Epsilon)\n                return \"System.Single.Epsilon\";\n            if (value == float.MaxValue)\n                return \"System.Single.MaxValue\";\n            if (value == float.MinValue)\n                return \"System.Single.MinValue\";\n\n            return value.ToString(\"G\", CultureInfo.InvariantCulture) + \"f\";\n        }\n\n        private static string ToInvariantCultureString(object @enum)\n        {\n            switch (Type.GetTypeCode(Enum.GetUnderlyingType(@enum.GetType())))\n            {\n                case TypeCode.Byte:\n                    return ((byte)@enum).ToString(CultureInfo.InvariantCulture);\n                case TypeCode.Int16:\n                    return ((short)@enum).ToString(CultureInfo.InvariantCulture);\n                case TypeCode.Int32:\n                    return ((int)@enum).ToString(CultureInfo.InvariantCulture);\n                case TypeCode.Int64:\n                    return ((long)@enum).ToString(CultureInfo.InvariantCulture);\n                case TypeCode.SByte:\n                    return ((sbyte)@enum).ToString(CultureInfo.InvariantCulture);\n                case TypeCode.UInt16:\n                    return ((ushort)@enum).ToString(CultureInfo.InvariantCulture);\n                case TypeCode.UInt32:\n                    return ((uint)@enum).ToString(CultureInfo.InvariantCulture);\n                case TypeCode.UInt64:\n                    return ((ulong)@enum).ToString(CultureInfo.InvariantCulture);\n                default:\n                    throw new ArgumentOutOfRangeException(nameof(@enum));\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Helpers/TaskbarProgress.cs",
    "content": "﻿using System;\nusing System.Runtime.InteropServices;\nusing BenchmarkDotNet.Detectors;\n\nnamespace BenchmarkDotNet.Helpers\n{\n    internal enum TaskbarProgressState\n    {\n        NoProgress = 0,\n        Indeterminate = 0x1,\n        Normal = 0x2,\n        Error = 0x4,\n        Paused = 0x8,\n        Warning = Paused\n    }\n\n    internal class TaskbarProgress : DisposeAtProcessTermination\n    {\n        private static readonly bool OsVersionIsSupported = OsDetector.IsWindows()\n            // Must be windows 7 or greater\n            && Environment.OSVersion.Version >= new Version(6, 1);\n\n        private Com? com;\n        private Terminal? terminal;\n\n        private bool IsEnabled => com != null || terminal != null;\n\n        internal TaskbarProgress(TaskbarProgressState initialTaskbarState)\n        {\n            if (OsVersionIsSupported)\n            {\n                com = Com.MaybeCreateInstanceAndSetInitialState(initialTaskbarState);\n                terminal = Terminal.MaybeCreateInstanceAndSetInitialState(initialTaskbarState);\n            }\n        }\n\n        internal void SetState(TaskbarProgressState state)\n        {\n            com?.SetState(state);\n            terminal?.SetState(state);\n        }\n\n        internal void SetProgress(float progressValue)\n        {\n            bool isValidRange = progressValue >= 0 & progressValue <= 1;\n            if (!isValidRange)\n            {\n                throw new ArgumentOutOfRangeException(nameof(progressValue), \"progressValue must be between 0 and 1 inclusive.\");\n            }\n            uint value = (uint)(progressValue * 100);\n            com?.SetValue(value);\n            terminal?.SetValue(value);\n        }\n\n        public override void Dispose()\n        {\n            if (IsEnabled)\n            {\n                SetState(TaskbarProgressState.NoProgress);\n                com = null;\n                terminal = null;\n            }\n            base.Dispose();\n        }\n\n        private sealed class Com\n        {\n            [ComImport]\n            [Guid(\"ea1afb91-9e28-4b86-90e9-9e9f8a5eefaf\")]\n            [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]\n            private interface ITaskbarList3\n            {\n                // ITaskbarList\n                [PreserveSig]\n                void HrInit();\n                [PreserveSig]\n                void AddTab(IntPtr hwnd);\n                [PreserveSig]\n                void DeleteTab(IntPtr hwnd);\n                [PreserveSig]\n                void ActivateTab(IntPtr hwnd);\n                [PreserveSig]\n                void SetActiveAlt(IntPtr hwnd);\n\n                // ITaskbarList2\n                [PreserveSig]\n                void MarkFullscreenWindow(IntPtr hwnd, [MarshalAs(UnmanagedType.Bool)] bool fFullscreen);\n\n                // ITaskbarList3\n                [PreserveSig]\n                void SetProgressValue(IntPtr hwnd, ulong ullCompleted, ulong ullTotal);\n                [PreserveSig]\n                void SetProgressState(IntPtr hwnd, TaskbarProgressState state);\n            }\n\n            [Guid(\"56FDF344-FD6D-11d0-958A-006097C9A090\")]\n            [ClassInterface(ClassInterfaceType.None)]\n            [ComImport]\n            private class TaskbarInstance { }\n\n            [DllImport(\"kernel32.dll\")]\n            private static extern IntPtr GetConsoleWindow();\n\n            private readonly ITaskbarList3 taskbarInstance;\n            private readonly IntPtr consoleWindowHandle;\n\n            private Com(IntPtr handle)\n            {\n                taskbarInstance = (ITaskbarList3) new TaskbarInstance();\n                consoleWindowHandle = handle;\n            }\n\n            internal static Com? MaybeCreateInstanceAndSetInitialState(TaskbarProgressState initialTaskbarState)\n            {\n                try\n                {\n                    IntPtr handle = GetConsoleWindow();\n                    if (handle == IntPtr.Zero)\n                    {\n                        return null;\n                    }\n                    var com = new Com(handle);\n                    com.SetState(initialTaskbarState);\n                    return com;\n                }\n                // COM may be disabled, in which case this will throw (#2253).\n                // It could be NotSupportedException or COMException, we just catch all.\n                catch\n                {\n                    return null;\n                }\n            }\n\n            internal void SetState(TaskbarProgressState taskbarState)\n                => taskbarInstance.SetProgressState(consoleWindowHandle, taskbarState);\n\n            /// <summary>\n            /// Sets the progress value out of 100.\n            /// </summary>\n            internal void SetValue(uint progressValue)\n                => taskbarInstance.SetProgressValue(consoleWindowHandle, progressValue, 100);\n        }\n\n        private sealed class Terminal\n        {\n            [Flags]\n            private enum ConsoleModes : uint\n            {\n                ENABLE_PROCESSED_INPUT = 0x0001,\n                ENABLE_LINE_INPUT = 0x0002,\n                ENABLE_ECHO_INPUT = 0x0004,\n                ENABLE_WINDOW_INPUT = 0x0008,\n                ENABLE_MOUSE_INPUT = 0x0010,\n                ENABLE_INSERT_MODE = 0x0020,\n                ENABLE_QUICK_EDIT_MODE = 0x0040,\n                ENABLE_EXTENDED_FLAGS = 0x0080,\n                ENABLE_AUTO_POSITION = 0x0100,\n\n                ENABLE_PROCESSED_OUTPUT = 0x0001,\n                ENABLE_WRAP_AT_EOL_OUTPUT = 0x0002,\n                ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004,\n                DISABLE_NEWLINE_AUTO_RETURN = 0x0008,\n                ENABLE_LVB_GRID_WORLDWIDE = 0x0010\n            }\n\n            [DllImport(\"kernel32.dll\", SetLastError = true)]\n            private static extern bool GetConsoleMode(IntPtr hConsoleHandle, out ConsoleModes lpMode);\n            [DllImport(\"kernel32.dll\", SetLastError = true)]\n            private static extern bool SetConsoleMode(IntPtr hConsoleHandle, ConsoleModes dwMode);\n            [DllImport(\"kernel32.dll\", SetLastError = true)]\n            private static extern IntPtr GetStdHandle(int nStdHandle);\n            private const int STD_OUTPUT_HANDLE = -11;\n\n            private readonly IntPtr consoleHandle;\n            private uint currentProgress;\n\n            private Terminal(IntPtr handle)\n                => consoleHandle = handle;\n\n            internal static Terminal? MaybeCreateInstanceAndSetInitialState(TaskbarProgressState initialTaskbarState)\n            {\n                IntPtr handle = GetStdHandle(STD_OUTPUT_HANDLE);\n                if (handle == IntPtr.Zero)\n                {\n                    return null;\n                }\n                if (!GetConsoleMode(handle, out ConsoleModes previousConsoleMode)\n                    || !SetConsoleMode(handle, ConsoleModes.ENABLE_VIRTUAL_TERMINAL_PROCESSING | ConsoleModes.ENABLE_PROCESSED_OUTPUT))\n                {\n                    // If we failed to set virtual terminal processing mode, it is likely due to an older Windows version that does not support it,\n                    // or legacy console. In either case the TaskbarProgressCom will take care of the progress. See https://stackoverflow.com/a/44574463/5703407.\n                    // If we try to write without VT mode, the sequence will be printed for the user to see, which clutters the output.\n                    return null;\n                }\n                var terminal = new Terminal(handle);\n                terminal.WriteStateSequence(initialTaskbarState);\n                SetConsoleMode(handle, previousConsoleMode);\n                return terminal;\n            }\n\n            internal void SetState(TaskbarProgressState taskbarState)\n            {\n                GetConsoleMode(consoleHandle, out ConsoleModes previousConsoleMode);\n                SetConsoleMode(consoleHandle, ConsoleModes.ENABLE_VIRTUAL_TERMINAL_PROCESSING | ConsoleModes.ENABLE_PROCESSED_OUTPUT);\n                WriteStateSequence(taskbarState);\n                SetConsoleMode(consoleHandle, previousConsoleMode);\n            }\n\n            private void WriteStateSequence(TaskbarProgressState taskbarState)\n            {\n                // Write progress state to console for Windows Terminal (https://github.com/microsoft/terminal/issues/6700).\n                switch (taskbarState)\n                {\n                    case TaskbarProgressState.NoProgress:\n                        currentProgress = 100;\n                        Console.Write(\"\\x1b]9;4;0;0\\x1b\\\\\");\n                        break;\n                    case TaskbarProgressState.Indeterminate:\n                        currentProgress = 100;\n                        Console.Write(\"\\x1b]9;4;3;0\\x1b\\\\\");\n                        break;\n                    case TaskbarProgressState.Normal:\n                        // Normal state is set when progress is set.\n                        WriteProgressSequence(currentProgress);\n                        break;\n                    case TaskbarProgressState.Error:\n                        Console.Write($\"\\x1b]9;4;2;{currentProgress}\\x1b\\\\\");\n                        break;\n                    case TaskbarProgressState.Warning:\n                        Console.Write($\"\\x1b]9;4;4;{currentProgress}\\x1b\\\\\");\n                        break;\n                }\n            }\n\n            /// <summary>\n            /// Sets the progress value out of 100.\n            /// </summary>\n            internal void SetValue(uint progressValue)\n            {\n                currentProgress = progressValue;\n                // Write progress sequence to console for Windows Terminal (https://github.com/microsoft/terminal/discussions/14268).\n                GetConsoleMode(consoleHandle, out ConsoleModes previousConsoleMode);\n                SetConsoleMode(consoleHandle, ConsoleModes.ENABLE_VIRTUAL_TERMINAL_PROCESSING | ConsoleModes.ENABLE_PROCESSED_OUTPUT);\n                WriteProgressSequence(progressValue);\n                SetConsoleMode(consoleHandle, previousConsoleMode);\n            }\n\n            private static void WriteProgressSequence(uint progressValue)\n                => Console.Write($\"\\x1b]9;4;1;{progressValue}\\x1b\\\\\");\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Helpers/UnitHelper.cs",
    "content": "using Perfolizer.Horology;\nusing Perfolizer.Metrology;\nusing Pragmastat.Metrology;\n\nnamespace BenchmarkDotNet.Helpers;\n\npublic static class UnitHelper\n{\n    public static readonly UnitPresentation DefaultPresentation = new(true, 0, gap: true);\n\n    public static string ToDefaultString(this TimeInterval timeInterval, string? format = null) => timeInterval.ToString(format, null, DefaultPresentation);\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Helpers/UserInteractionHelper.cs",
    "content": "using BenchmarkDotNet.Detectors;\nusing BenchmarkDotNet.Portability;\n\nnamespace BenchmarkDotNet.Helpers\n{\n    internal static class UserInteractionHelper\n    {\n        /// <summary>\n        /// If you are going to show a command example which should be typed by user in a terminal,\n        /// all asterisk symbols ('*') should be escaped with the help of quotes\n        /// (read more here: <a href=\"https://www.shellscript.sh/escape.html\">https://www.shellscript.sh/escape.html</a>).\n        ///\n        /// This method escapes such characters on non-Windows platforms.\n        ///\n        /// </summary>\n        /// <remarks>\n        /// See also:\n        ///   <a href=\"https://github.com/dotnet/BenchmarkDotNet/issues/842\">#842</a>,\n        ///   <a href=\"https://github.com/dotnet/BenchmarkDotNet/issues/1147\">#1147</a>\n        /// </remarks>\n        public static string EscapeCommandExample(string input)\n        {\n            return !OsDetector.IsWindows() && input.IndexOf('*') >= 0 ? $\"'{input}'\" : input;\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Helpers/XUnitHelper.cs",
    "content": "using System;\nusing System.Linq;\n\nnamespace BenchmarkDotNet.Helpers;\n\ninternal static class XUnitHelper\n{\n    public static Lazy<bool> IsIntegrationTest =\n        new(() => AppDomain.CurrentDomain.GetAssemblies().Any(assembly => assembly.GetName().Name == \"BenchmarkDotNet.IntegrationTests\"));\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Jobs/AccuracyMode.cs",
    "content": "﻿using System.Diagnostics.CodeAnalysis;\nusing BenchmarkDotNet.Characteristics;\nusing Perfolizer.Horology;\nusing Perfolizer.Mathematics.OutlierDetection;\n\nnamespace BenchmarkDotNet.Jobs\n{\n    [SuppressMessage(\"ReSharper\", \"UnusedMember.Global\")]\n    public sealed class AccuracyMode : JobMode<AccuracyMode>\n    {\n        public static readonly Characteristic<double> MaxRelativeErrorCharacteristic = CreateCharacteristic<double>(nameof(MaxRelativeError));\n        public static readonly Characteristic<TimeInterval> MaxAbsoluteErrorCharacteristic = CreateCharacteristic<TimeInterval>(nameof(MaxAbsoluteError));\n        public static readonly Characteristic<TimeInterval> MinIterationTimeCharacteristic = CreateCharacteristic<TimeInterval>(nameof(MinIterationTime));\n        public static readonly Characteristic<int> MinInvokeCountCharacteristic = CreateCharacteristic<int>(nameof(MinInvokeCount));\n        public static readonly Characteristic<bool> EvaluateOverheadCharacteristic = CreateCharacteristic<bool>(nameof(EvaluateOverhead));\n        public static readonly Characteristic<OutlierMode> OutlierModeCharacteristic = CreateCharacteristic<OutlierMode>(nameof(OutlierMode));\n        public static readonly Characteristic<bool> AnalyzeLaunchVarianceCharacteristic = CreateCharacteristic<bool>(nameof(AnalyzeLaunchVariance));\n\n        /// <summary>\n        /// Maximum acceptable error for a benchmark (by default, BenchmarkDotNet continue iterations until the actual error is less than the specified error).\n        /// The default value is 0.02.\n        /// <remarks>If <see cref=\"MaxAbsoluteError\"/> is also provided, the smallest value is used as stop criteria.</remarks>\n        /// </summary>\n        public double MaxRelativeError\n        {\n            get => MaxRelativeErrorCharacteristic[this];\n            set => MaxRelativeErrorCharacteristic[this] = value;\n        }\n\n        /// <summary>\n        /// Maximum acceptable error for a benchmark (by default, BenchmarkDotNet continue iterations until the actual error is less than the specified error).\n        /// Doesn't have a default value.\n        /// <remarks>If <see cref=\"MaxRelativeError\"/> is also provided, the smallest value is used as stop criteria.</remarks>\n        /// </summary>\n        public TimeInterval MaxAbsoluteError\n        {\n            get => MaxAbsoluteErrorCharacteristic[this];\n            set => MaxAbsoluteErrorCharacteristic[this] = value;\n        }\n\n        /// <summary>\n        /// Minimum time of a single iteration. Unlike Run.IterationTime, this characteristic specifies only the lower limit. In case of need, BenchmarkDotNet can increase this value.\n        /// The default value is 500 milliseconds.\n        /// </summary>\n        public TimeInterval MinIterationTime\n        {\n            get => MinIterationTimeCharacteristic[this];\n            set => MinIterationTimeCharacteristic[this] = value;\n        }\n\n        /// <summary>\n        /// Minimum count of benchmark invocations per iteration.\n        /// The default value is 4.\n        /// </summary>\n        public int MinInvokeCount\n        {\n            get => MinInvokeCountCharacteristic[this];\n            set => MinInvokeCountCharacteristic[this] = value;\n        }\n\n        /// <summary>\n        /// Specifies if the overhead should be evaluated (Idle runs) and it's average value subtracted from every result.\n        /// True by default, very important for nano-benchmarks.\n        /// </summary>\n        public bool EvaluateOverhead\n        {\n            get => EvaluateOverheadCharacteristic[this];\n            set => EvaluateOverheadCharacteristic[this] = value;\n        }\n\n        /// <summary>\n        /// Specifies which outliers should be removed from the distribution.\n        /// </summary>\n        public OutlierMode OutlierMode\n        {\n            get => OutlierModeCharacteristic[this];\n            set => OutlierModeCharacteristic[this] = value;\n        }\n\n        public bool AnalyzeLaunchVariance\n        {\n            get => AnalyzeLaunchVarianceCharacteristic[this];\n            set => AnalyzeLaunchVarianceCharacteristic[this] = value;\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Jobs/Argument.cs",
    "content": "﻿using System;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Jobs\n{\n    public abstract class Argument: IEquatable<Argument>\n    {\n        [PublicAPI] public string TextRepresentation { get; }\n\n        protected Argument(string value)\n        {\n            TextRepresentation = value;\n        }\n\n        // CharacteristicPresenters call ToString(), this is why we need this override\n        public override string ToString() => TextRepresentation;\n\n        public bool Equals(Argument? other)\n        {\n            if (ReferenceEquals(null, other)) return false;\n            if (ReferenceEquals(this, other)) return true;\n            return TextRepresentation == other.TextRepresentation;\n        }\n\n        public override bool Equals(object? obj) => Equals(obj as Argument);\n\n        public override int GetHashCode() => HashCode.Combine(TextRepresentation);\n    }\n\n    /// <summary>\n    /// Argument passed directly to mono when executing benchmarks (mono [options])\n    /// example: new MonoArgument(\"--gc=sgen\")\n    /// </summary>\n    public class MonoArgument : Argument\n    {\n        public MonoArgument(string value) : base(value)\n        {\n            if (value == \"--llvm\" || value == \"--nollvm\")\n                throw new NotSupportedException(\"Please use job.Env.Jit to specify Jit in explicit way\");\n        }\n    }\n\n    /// <summary>\n    /// Argument passed to dotnet cli when restoring and building the project\n    /// example: new MsBuildArgument(\"/p:MyCustomSetting=123\")\n    /// </summary>\n    [PublicAPI]\n    public class MsBuildArgument : Argument\n    {\n        public MsBuildArgument(string value) : base(value) { }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Jobs/EnvironmentMode.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing BenchmarkDotNet.Characteristics;\nusing BenchmarkDotNet.Detectors;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Models;\nusing BenchmarkDotNet.Portability;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Jobs\n{\n    public sealed class EnvironmentMode : JobMode<EnvironmentMode>\n    {\n        public static readonly Characteristic<Platform> PlatformCharacteristic = CreateCharacteristic<Platform>(nameof(Platform));\n        public static readonly Characteristic<Jit> JitCharacteristic = CreateCharacteristic<Jit>(nameof(Jit));\n        public static readonly Characteristic<Runtime> RuntimeCharacteristic = CreateCharacteristic<Runtime>(nameof(Runtime));\n        public static readonly Characteristic<IntPtr> AffinityCharacteristic = CreateCharacteristic<IntPtr>(nameof(Affinity));\n        public static readonly Characteristic<GcMode> GcCharacteristic = CreateCharacteristic<GcMode>(nameof(Gc));\n\n        public static readonly Characteristic<IReadOnlyList<EnvironmentVariable>> EnvironmentVariablesCharacteristic =\n            CreateCharacteristic<IReadOnlyList<EnvironmentVariable>>(nameof(EnvironmentVariables));\n\n        public static readonly Characteristic<Guid?> PowerPlanModeCharacteristic = CreateCharacteristic<Guid?>(nameof(PowerPlanMode));\n        public static readonly Characteristic<bool> LargeAddressAwareCharacteristic = CreateCharacteristic<bool>(nameof(LargeAddressAware));\n\n        public static readonly EnvironmentMode LegacyJitX86 = new EnvironmentMode(nameof(LegacyJitX86), Jit.LegacyJit, Platform.X86).Freeze();\n        public static readonly EnvironmentMode LegacyJitX64 = new EnvironmentMode(nameof(LegacyJitX64), Jit.LegacyJit, Platform.X64).Freeze();\n        public static readonly EnvironmentMode RyuJitX64 = new EnvironmentMode(nameof(RyuJitX64), Jit.RyuJit, Platform.X64).Freeze();\n        public static readonly EnvironmentMode RyuJitX86 = new EnvironmentMode(nameof(RyuJitX86), Jit.RyuJit, Platform.X86).Freeze();\n\n        [PublicAPI]\n        public EnvironmentMode() : this(id: \"\") { }\n\n        [PublicAPI]\n        public EnvironmentMode(Runtime runtime) : this(runtime.ToString()) => Runtime = runtime;\n\n        [PublicAPI]\n        public EnvironmentMode(string id, Jit jit, Platform platform) : this(id)\n        {\n            Jit = jit;\n            Platform = platform;\n        }\n\n        [PublicAPI]\n        public EnvironmentMode(string id) : base(id)\n        {\n            GcCharacteristic[this] = new GcMode();\n        }\n\n        /// <summary>\n        /// Platform (x86 or x64)\n        /// </summary>\n        public Platform Platform\n        {\n            get { return PlatformCharacteristic[this]; }\n            set { PlatformCharacteristic[this] = value; }\n        }\n\n        /// <summary>\n        /// JIT (Just-In-Time compiler)\n        /// </summary>\n        public Jit Jit\n        {\n            get { return JitCharacteristic[this]; }\n            set { JitCharacteristic[this] = value; }\n        }\n\n        /// <summary>\n        /// Runtime\n        /// </summary>\n        public Runtime? Runtime\n        {\n            get { return RuntimeCharacteristic[this]; }\n            set { RuntimeCharacteristic[this] = value; }\n        }\n\n        /// <summary>\n        /// ProcessorAffinity for the benchmark process.\n        /// See also: https://msdn.microsoft.com/library/system.diagnostics.process.processoraffinity.aspx\n        /// </summary>\n        public IntPtr Affinity\n        {\n            get { return AffinityCharacteristic[this]; }\n            set { AffinityCharacteristic[this] = value; }\n        }\n\n        /// <summary>\n        /// GcMode\n        /// </summary>\n        public GcMode Gc => GcCharacteristic[this]!;\n\n        public IReadOnlyList<EnvironmentVariable> EnvironmentVariables\n        {\n            get => EnvironmentVariablesCharacteristic[this] ?? [];\n            set => EnvironmentVariablesCharacteristic[this] = value;\n        }\n\n        /// <summary>\n        /// Power Plan Mode\n        /// </summary>\n        /// <remarks>Supported only on Windows.</remarks>\n        public Guid? PowerPlanMode\n        {\n            get => PowerPlanModeCharacteristic[this];\n            set => PowerPlanModeCharacteristic[this] = value;\n        }\n\n        /// <summary>\n        /// Specifies that benchmark can handle addresses larger than 2 gigabytes.\n        /// <value>false: Benchmark uses the default (64-bit: enabled; 32-bit:disabled). This is the default.</value>\n        /// <value>true: Explicitly specify that benchmark can handle addresses larger than 2 gigabytes.</value>\n        /// </summary>\n        public bool LargeAddressAware\n        {\n            get => LargeAddressAwareCharacteristic[this];\n            set\n            {\n                if (value && !OsDetector.IsWindows())\n                {\n                    throw new NotSupportedException(\"LargeAddressAware is a Windows-specific concept.\");\n                }\n\n                LargeAddressAwareCharacteristic[this] = value;\n            }\n        }\n\n        /// <summary>\n        /// Adds the specified <paramref name=\"variable\"/> to <see cref=\"EnvironmentVariables\"/>.\n        /// If <see cref=\"EnvironmentVariables\"/> already contains a variable with the same key,\n        /// it will be overriden.\n        /// </summary>\n        /// <param name=\"variable\">The new environment variable which should be added to <see cref=\"EnvironmentVariables\"/></param>\n        public void SetEnvironmentVariable(EnvironmentVariable variable)\n        {\n            var newVariables = new List<EnvironmentVariable>();\n            newVariables.AddRange(EnvironmentVariables);\n            newVariables.RemoveAll(v => v.Key.Equals(variable.Key, StringComparison.Ordinal));\n            newVariables.Add(variable);\n            EnvironmentVariables = newVariables;\n        }\n\n        internal Runtime GetRuntime()\n        {\n            return HasValue(RuntimeCharacteristic) && Runtime != null\n                ? Runtime\n                : RuntimeInformation.GetCurrentRuntime();\n        }\n\n        internal BdnEnvironment ToPerfonar() => new()\n        {\n            Jit = HasValue(JitCharacteristic) ? Jit : null,\n            Runtime = HasValue(RuntimeCharacteristic) ? Runtime?.RuntimeMoniker : null,\n            Affinity = HasValue(AffinityCharacteristic) ? (int)Affinity : null\n        };\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Jobs/EnvironmentVariable.cs",
    "content": "﻿using System;\n\nnamespace BenchmarkDotNet.Jobs\n{\n    public class EnvironmentVariable : IEquatable<EnvironmentVariable>\n    {\n        public EnvironmentVariable(string key, string value)\n        {\n            Key = key ?? throw new ArgumentNullException(nameof(key));\n            Value = value ?? throw new ArgumentNullException(nameof(value));\n        }\n\n        public string Key { get; }\n\n        public string Value { get; }\n\n        // CharacteristicPresenters call ToString(), this is why we need this override\n        public override string ToString() => $\"{Key}={Value}\";\n\n        public bool Equals(EnvironmentVariable? other)\n        {\n            return string.Equals(Key, other?.Key) && string.Equals(Value, other?.Value);\n        }\n\n        public override bool Equals(object? obj)\n        {\n            if (ReferenceEquals(null, obj))\n                return false;\n            if (ReferenceEquals(this, obj))\n                return true;\n            if (obj.GetType() != GetType())\n                return false;\n            return Equals((EnvironmentVariable) obj);\n        }\n\n        public override int GetHashCode() => HashCode.Combine(Key, Value);\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Jobs/GcMode.cs",
    "content": "﻿using System;\nusing System.Diagnostics.CodeAnalysis;\nusing BenchmarkDotNet.Characteristics;\n\nnamespace BenchmarkDotNet.Jobs\n{\n    [SuppressMessage(\"ReSharper\", \"MemberCanBePrivate.Global\")]\n    [SuppressMessage(\"ReSharper\", \"UnusedMember.Global\")]\n    public sealed class GcMode : JobMode<GcMode>, IEquatable<GcMode>\n    {\n        public static readonly Characteristic<bool> ServerCharacteristic = CreateCharacteristic<bool>(nameof(Server));\n        public static readonly Characteristic<bool> ConcurrentCharacteristic = CreateCharacteristic<bool>(nameof(Concurrent));\n        public static readonly Characteristic<bool> CpuGroupsCharacteristic = CreateCharacteristic<bool>(nameof(CpuGroups));\n        public static readonly Characteristic<bool> ForceCharacteristic = CreateCharacteristic<bool>(nameof(Force));\n        public static readonly Characteristic<bool> AllowVeryLargeObjectsCharacteristic = CreateCharacteristic<bool>(nameof(AllowVeryLargeObjects));\n        public static readonly Characteristic<bool> RetainVmCharacteristic = CreateCharacteristic<bool>(nameof(RetainVm));\n        public static readonly Characteristic<bool> NoAffinitizeCharacteristic = CreateCharacteristic<bool>(nameof(NoAffinitize));\n        public static readonly Characteristic<int> HeapAffinitizeMaskCharacteristic = CreateCharacteristic<int>(nameof(HeapAffinitizeMask));\n        public static readonly Characteristic<int> HeapCountCharacteristic = CreateCharacteristic<int>(nameof(HeapCount));\n\n        /// <summary>\n        /// Specifies whether the common language runtime runs server garbage collection.\n        /// <value>false: Does not run server garbage collection. This is the default.</value>\n        /// <value>true: Runs server garbage collection.</value>\n        /// </summary>\n        public bool Server\n        {\n            get { return ServerCharacteristic[this]; }\n            set { ServerCharacteristic[this] = value; }\n        }\n\n        /// <summary>\n        /// Specifies whether the common language runtime runs garbage collection on a separate thread.\n        /// <value>false: Does not run garbage collection concurrently.</value>\n        /// <value>true: Runs garbage collection concurrently. This is the default.</value>\n        /// </summary>\n        public bool Concurrent\n        {\n            get { return ConcurrentCharacteristic[this]; }\n            set { ConcurrentCharacteristic[this] = value; }\n        }\n\n        /// <summary>\n        /// Specifies whether garbage collection supports multiple CPU groups.\n        /// <value>false: Garbage collection does not support multiple CPU groups. This is the default.</value>\n        /// <value>true: Garbage collection supports multiple CPU groups, if server garbage collection is enabled.</value>\n        /// </summary>\n        public bool CpuGroups\n        {\n            get { return CpuGroupsCharacteristic[this]; }\n            set { CpuGroupsCharacteristic[this] = value; }\n        }\n\n        /// <summary>\n        /// Specifies whether the BenchmarkDotNet's benchmark runner forces full garbage collection after each benchmark invocation\n        /// <value>false: Does not force garbage collection.</value>\n        /// <value>true: Forces full garbage collection after each benchmark invocation. This is the default.</value>\n        /// </summary>\n        public bool Force\n        {\n            get { return ForceCharacteristic[this]; }\n            set { ForceCharacteristic[this] = value; }\n        }\n\n        /// <summary>\n        /// On 64-bit platforms, enables arrays that are greater than 2 gigabytes (GB) in total size.\n        /// <value>false: Arrays greater than 2 GB in total size are not enabled. This is the default.</value>\n        /// <value>true: Arrays greater than 2 GB in total size are enabled on 64-bit platforms.</value>\n        /// </summary>\n        public bool AllowVeryLargeObjects\n        {\n            get { return AllowVeryLargeObjectsCharacteristic[this]; }\n            set { AllowVeryLargeObjectsCharacteristic[this] = value; }\n        }\n\n        /// <summary>\n        /// Put segments that should be deleted on a standby list for future use instead of releasing them back to the OS\n        /// <remarks>The default is false</remarks>\n        /// </summary>\n        public bool RetainVm\n        {\n            get { return RetainVmCharacteristic[this]; }\n            set { RetainVmCharacteristic[this] = value; }\n        }\n\n        /// <summary>\n        /// specify true to disable hard affinity of Server GC threads to CPUs\n        /// </summary>\n        public bool NoAffinitize\n        {\n            get { return NoAffinitizeCharacteristic[this]; }\n            set { NoAffinitizeCharacteristic[this] = value; }\n        }\n\n        /// <summary>\n        /// process mask, see <see href=\"https://support.microsoft.com/en-us/help/4014604/may-2017-description-of-the-quality-rollup-for-the-net-framework-4-6-4\">MSDN</see> for more.\n        /// </summary>\n        public int HeapAffinitizeMask\n        {\n            get { return HeapAffinitizeMaskCharacteristic[this]; }\n            set { HeapAffinitizeMaskCharacteristic[this] = value; }\n        }\n\n        /// <summary>\n        ///  specify the # of Server GC threads/heaps, must be smaller than the # of logical CPUs the process is allowed to run on,\n        ///  ie, if you don't specifically affinitize your process it means the # of total logical CPUs on the machine;\n        ///  otherwise this is the # of logical CPUs you affinitized your process to.\n        /// </summary>\n        public int HeapCount\n        {\n            get { return HeapCountCharacteristic[this]; }\n            set { HeapCountCharacteristic[this] = value; }\n        }\n\n        public bool Equals(GcMode? other)\n            => other != null\n                && other.AllowVeryLargeObjects == AllowVeryLargeObjects\n                && other.Concurrent == Concurrent\n                && other.CpuGroups == CpuGroups\n                && other.Force == Force\n                && other.NoAffinitize == NoAffinitize\n                && other.RetainVm == RetainVm\n                && other.Server == Server;\n\n        public override int GetHashCode()\n            => HashCode.Combine(AllowVeryLargeObjects, Concurrent, CpuGroups, Force, NoAffinitize, RetainVm, Server);\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Jobs/GcModeExtensions.cs",
    "content": "﻿using System;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Jobs\n{\n    public static class GcModeExtensions\n    {\n        /// <summary>\n        /// Specifies whether the common language runtime runs server garbage collection.\n        /// <value>false: Does not run server garbage collection. This is the default.</value>\n        /// <value>true: Runs server garbage collection.</value>\n        /// </summary>\n        [PublicAPI]\n        public static GcMode WithServer(this GcMode mode, bool value) => mode.WithCore(m => m.Server = value);\n\n        /// <summary>\n        /// Specifies whether the common language runtime runs garbage collection on a separate thread.\n        /// <value>false: Does not run garbage collection concurrently.</value>\n        /// <value>true: Runs garbage collection concurrently. This is the default.</value>\n        /// </summary>\n        [PublicAPI]\n        public static GcMode WithConcurrent(this GcMode mode, bool value) => mode.WithCore(m => m.Concurrent = value);\n\n        /// <summary>\n        /// Specifies whether garbage collection supports multiple CPU groups.\n        /// <value>false: Garbage collection does not support multiple CPU groups. This is the default.</value>\n        /// <value>true: Garbage collection supports multiple CPU groups, if server garbage collection is enabled.</value>\n        /// </summary>\n        [PublicAPI]\n        public static GcMode WithCpuGroups(this GcMode mode, bool value) => mode.WithCore(m => m.CpuGroups = value);\n\n        /// <summary>\n        /// Specifies whether the BenchmarkDotNet's benchmark runner forces full garbage collection after each benchmark invocation\n        /// <value>false: Does not force garbage collection.</value>\n        /// <value>true: Forces full garbage collection after each benchmark invocation. This is the default.</value>\n        /// </summary>\n        [PublicAPI]\n        public static GcMode WithForce(this GcMode mode, bool value) => mode.WithCore(m => m.Force = value);\n\n        /// <summary>\n        /// On 64-bit platforms, enables arrays that are greater than 2 gigabytes (GB) in total size.\n        /// <value>false: Arrays greater than 2 GB in total size are not enabled. This is the default.</value>\n        /// <value>true: Arrays greater than 2 GB in total size are enabled on 64-bit platforms.</value>\n        /// </summary>\n        [PublicAPI]\n        public static GcMode WithAllowVeryLargeObjects(this GcMode mode, bool value) => mode.WithCore(m => m.AllowVeryLargeObjects = value);\n\n        /// <summary>\n        /// Put segments that should be deleted on a standby list for future use instead of releasing them back to the OS\n        /// <remarks>The default is false</remarks>\n        /// </summary>\n        [PublicAPI]\n        public static GcMode WithRetainVm(this GcMode mode, bool value) => mode.WithCore(m => m.RetainVm = value);\n\n        /// <summary>\n        ///  specify the # of Server GC threads/heaps, must be smaller than the # of logical CPUs the process is allowed to run on,\n        ///  ie, if you don't specifically affinitize your process it means the # of total logical CPUs on the machine;\n        ///  otherwise this is the # of logical CPUs you affinitized your process to.\n        /// </summary>\n        [PublicAPI]\n        public static GcMode WithHeapCount(this GcMode mode, int heapCount) => mode.WithCore(m => m.HeapCount = heapCount);\n\n        /// <summary>\n        /// specify true to disable hard affinity of Server GC threads to CPUs\n        /// </summary>\n        [PublicAPI]\n        public static GcMode WithNoAffinitize(this GcMode mode, bool value) => mode.WithCore(m => m.NoAffinitize = value);\n\n        /// <summary>\n        /// process mask, see <see href=\"https://support.microsoft.com/en-us/help/4014604/may-2017-description-of-the-quality-rollup-for-the-net-framework-4-6-4\">MSDN</see> for more.\n        /// </summary>\n        [PublicAPI]\n        public static GcMode WithHeapAffinitizeMask(this GcMode mode, int heapAffinitizeMask) => mode.WithCore(m => m.HeapAffinitizeMask = heapAffinitizeMask);\n\n        private static GcMode WithCore(this GcMode mode, Action<GcMode> updateCallback)\n        {\n            mode = new GcMode().Apply(mode);\n            updateCallback(mode);\n            return mode;\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Jobs/InfrastructureMode.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Diagnostics.CodeAnalysis;\nusing BenchmarkDotNet.Characteristics;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Toolchains;\nusing BenchmarkDotNet.Toolchains.InProcess.Emit;\nusing Perfolizer.Horology;\n\nnamespace BenchmarkDotNet.Jobs\n{\n    [SuppressMessage(\"ReSharper\", \"UnusedMember.Global\")]\n    public sealed class InfrastructureMode : JobMode<InfrastructureMode>\n    {\n        public const string ReleaseConfigurationName = \"Release\";\n\n        public static readonly Characteristic<IToolchain> ToolchainCharacteristic = CreateCharacteristic<IToolchain>(nameof(Toolchain));\n        public static readonly Characteristic<IClock> ClockCharacteristic = CreateCharacteristic<IClock>(nameof(Clock));\n        public static readonly Characteristic<IEngineFactory> EngineFactoryCharacteristic = CreateCharacteristic<IEngineFactory>(nameof(EngineFactory));\n        public static readonly Characteristic<string> BuildConfigurationCharacteristic = CreateCharacteristic<string>(nameof(BuildConfiguration));\n        public static readonly Characteristic<IReadOnlyList<Argument>> ArgumentsCharacteristic = CreateCharacteristic<IReadOnlyList<Argument>>(nameof(Arguments));\n\n        public static readonly InfrastructureMode InProcess = new InfrastructureMode(InProcessEmitToolchain.Default);\n\n        public InfrastructureMode() { }\n\n        private InfrastructureMode(IToolchain toolchain)\n        {\n            Toolchain = toolchain;\n        }\n\n        public IToolchain? Toolchain\n        {\n            get { return ToolchainCharacteristic[this]; }\n            set { ToolchainCharacteristic[this] = value; }\n        }\n\n        public IClock? Clock\n        {\n            get { return ClockCharacteristic[this]; }\n            set { ClockCharacteristic[this] = value; }\n        }\n\n        /// <summary>\n        /// this type will be used in the auto-generated program to create engine in separate process\n        /// <remarks>it must have parameterless constructor</remarks>\n        /// </summary>\n        public IEngineFactory? EngineFactory\n        {\n            get { return EngineFactoryCharacteristic[this]; }\n            set { EngineFactoryCharacteristic[this] = value; }\n        }\n\n        public string? BuildConfiguration\n        {\n            get => BuildConfigurationCharacteristic[this];\n            set => BuildConfigurationCharacteristic[this] = value;\n        }\n\n        public IReadOnlyList<Argument>? Arguments\n        {\n            get => ArgumentsCharacteristic[this];\n            set => ArgumentsCharacteristic[this] = value;\n        }\n\n        public bool TryGetToolchain([NotNullWhen(true)]out IToolchain? toolchain)\n        {\n            toolchain = HasValue(ToolchainCharacteristic) ? Toolchain : default;\n            return toolchain != default;\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Jobs/Job.cs",
    "content": "﻿using BenchmarkDotNet.Characteristics;\nusing JetBrains.Annotations;\nusing System.Diagnostics.CodeAnalysis;\n\nnamespace BenchmarkDotNet.Jobs\n{\n    [SuppressMessage(\"ReSharper\", \"UnassignedReadonlyField\")]\n    public sealed class Job : JobMode<Job>\n    {\n        [PublicAPI] public static readonly Characteristic<EnvironmentMode> EnvironmentCharacteristic = CreateCharacteristic<EnvironmentMode>(nameof(Environment));\n        [PublicAPI] public static readonly Characteristic<RunMode> RunCharacteristic = CreateCharacteristic<RunMode>(nameof(Run));\n        [PublicAPI] public static readonly Characteristic<InfrastructureMode> InfrastructureCharacteristic = CreateCharacteristic<InfrastructureMode>(nameof(Infrastructure));\n        [PublicAPI] public static readonly Characteristic<AccuracyMode> AccuracyCharacteristic = CreateCharacteristic<AccuracyMode>(nameof(Accuracy));\n        [PublicAPI] public static readonly Characteristic<MetaMode> MetaCharacteristic = CreateCharacteristic<MetaMode>(nameof(Meta));\n\n        public static readonly Job LegacyJitX86 = new Job(nameof(LegacyJitX86), EnvironmentMode.LegacyJitX86).Freeze();\n        public static readonly Job LegacyJitX64 = new Job(nameof(LegacyJitX64), EnvironmentMode.LegacyJitX64).Freeze();\n        public static readonly Job RyuJitX64 = new Job(nameof(RyuJitX64), EnvironmentMode.RyuJitX64).Freeze();\n        public static readonly Job RyuJitX86 = new Job(nameof(RyuJitX86), EnvironmentMode.RyuJitX86).Freeze();\n\n        // Run\n        public static readonly Job Dry = new Job(nameof(Dry), RunMode.Dry).Freeze();\n\n        public static readonly Job ShortRun = new Job(nameof(ShortRun), RunMode.Short).Freeze();\n        public static readonly Job MediumRun = new Job(nameof(MediumRun), RunMode.Medium).Freeze();\n        public static readonly Job LongRun = new Job(nameof(LongRun), RunMode.Long).Freeze();\n        public static readonly Job VeryLongRun = new Job(nameof(VeryLongRun), RunMode.VeryLong).Freeze();\n\n        // Infrastructure\n        public static readonly Job InProcess = new Job(nameof(InProcess), InfrastructureMode.InProcess);\n\n        public Job() : this(\"\") { }\n\n        public Job(string id) : base(id)\n        {\n            EnvironmentCharacteristic[this] = new EnvironmentMode();\n            RunCharacteristic[this] = new RunMode();\n            InfrastructureCharacteristic[this] = new InfrastructureMode();\n            AccuracyCharacteristic[this] = new AccuracyMode();\n            MetaCharacteristic[this] = new MetaMode();\n        }\n\n        public Job(CharacteristicObject other) : this(\"\", other)\n        {\n        }\n\n        public Job(params CharacteristicObject[] others) : this(\"\", others)\n        {\n        }\n\n        public Job(string id, CharacteristicObject other) : this(id)\n        {\n            Apply(other);\n        }\n\n        public Job(string id, params CharacteristicObject[] others) : this(id)\n        {\n            Apply(others);\n        }\n\n        public EnvironmentMode Environment => EnvironmentCharacteristic[this]!;\n        public RunMode Run => RunCharacteristic[this]!;\n        public InfrastructureMode Infrastructure => InfrastructureCharacteristic[this]!;\n        public AccuracyMode Accuracy => AccuracyCharacteristic[this]!;\n        public MetaMode Meta => MetaCharacteristic[this]!;\n\n        public string ResolvedId => HasValue(IdCharacteristic) ? Id : JobIdGenerator.GenerateRandomId(this);\n        public string FolderInfo => ResolvedId;\n\n        public string DisplayInfo\n        {\n            get\n            {\n                string props = ResolveId(this, \"\");\n                return props == IdCharacteristic.FallbackValue\n                    ? ResolvedId\n                    : ResolvedId + $\"({props})\";\n            }\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Jobs/JobComparer.cs",
    "content": "﻿using BenchmarkDotNet.Characteristics;\nusing BenchmarkDotNet.Order;\nusing System;\nusing System.Collections.Generic;\n\nnamespace BenchmarkDotNet.Jobs\n{\n    internal class JobComparer : IComparer<Job>, IEqualityComparer<Job>\n    {\n        private readonly IComparer<string> Comparer;\n        private static IComparer<string> NumericComparer =>\n#if NET10_0_OR_GREATER\n            StringComparer.Create(System.Globalization.CultureInfo.InvariantCulture, System.Globalization.CompareOptions.NumericOrdering);\n#else\n            new NumericStringComparer();\n#endif\n\n        public static readonly JobComparer Default = new(JobOrderPolicy.Numeric);\n        public static readonly JobComparer Ordinal = new(JobOrderPolicy.Ordinal);\n\n        private JobComparer(JobOrderPolicy jobOrderPolicy)\n        {\n            switch (jobOrderPolicy)\n            {\n                case JobOrderPolicy.Ordinal:\n                    Comparer = StringComparer.Ordinal;\n                    break;\n\n                default:\n                    Comparer = NumericComparer;\n                    break;\n            }\n        }\n\n        public int Compare(Job? x, Job? y)\n        {\n            if (ReferenceEquals(x, y))\n                return 0;\n\n            if (x == null)\n                return -1;\n\n            if (y == null)\n                return 1;\n\n            if (x.GetType() != y.GetType())\n                throw new InvalidOperationException($\"The type of xJob ({x.GetType()}) != type of yJob ({y.GetType()})\");\n\n            var presenter = CharacteristicPresenter.DefaultPresenter;\n\n            foreach (var characteristic in x.GetAllCharacteristics())\n            {\n                if (!x.HasValue(characteristic))\n                {\n                    if (y.HasValue(characteristic))\n                        return -1;\n                    continue;\n                }\n                if (!y.HasValue(characteristic))\n                {\n                    if (x.HasValue(characteristic))\n                        return 1;\n                    continue;\n                }\n\n                int compare = Comparer.Compare(\n                    presenter.ToPresentation(x, characteristic),\n                    presenter.ToPresentation(y, characteristic));\n                if (compare != 0)\n                    return compare;\n            }\n\n            return 0;\n        }\n\n        public bool Equals(Job? x, Job? y) => Compare(x, y) == 0;\n\n        public int GetHashCode(Job obj) => obj.Id.GetHashCode();\n\n#if !NET10_0_OR_GREATER\n        private class NumericStringComparer : IComparer<string>\n        {\n            public int Compare(string? x, string? y)\n            {\n                if (ReferenceEquals(x, y)) return 0;\n                if (x == null) return -1;\n                if (y == null) return 1;\n\n                ReadOnlySpan<char> spanX = x.AsSpan();\n                ReadOnlySpan<char> spanY = y.AsSpan();\n\n                int i = 0, j = 0;\n\n                while (i < spanX.Length && j < spanY.Length)\n                {\n                    char cx = spanX[i];\n                    char cy = spanY[j];\n\n                    if (!char.IsDigit(cx) || !char.IsDigit(cy))\n                    {\n                        int cmp = cx.CompareTo(cy);\n                        if (cmp != 0)\n                            return cmp;\n\n                        i++;\n                        j++;\n                        continue;\n                    }\n\n                    int ixStart = i;\n                    int iyStart = j;\n\n                    // Skip leading zeros\n                    while (ixStart < spanX.Length && spanX[ixStart] == '0') ixStart++;\n                    while (iyStart < spanY.Length && spanY[iyStart] == '0') iyStart++;\n\n                    int ix = ixStart;\n                    int iy = iyStart;\n\n                    // Skip digits\n                    while (ix < spanX.Length && char.IsDigit(spanX[ix])) ix++;\n                    while (iy < spanY.Length && char.IsDigit(spanY[iy])) iy++;\n\n                    int lenX = ix - ixStart;\n                    int lenY = iy - iyStart;\n\n                    // Compare by digits length\n                    if (lenX != lenY)\n                        return lenX.CompareTo(lenY);\n\n                    // Compare digits\n                    for (int k = 0; k < lenX; k++)\n                    {\n                        int cmp = spanX[ixStart + k].CompareTo(spanY[iyStart + k]);\n                        if (cmp != 0)\n                            return cmp;\n                    }\n\n                    // Compare by leading zeros\n                    int leadingZerosX = ixStart - i;\n                    int leadingZerosY = iyStart - j;\n                    if (leadingZerosX != leadingZerosY)\n                        return 0; // Leading zero differences are ignored (`CompareOptions.NumericOrdering` behavior of .NET)\n\n                    // Move to the next character after the digits\n                    i = ix;\n                    j = iy;\n                }\n\n                // Compare remaining chars\n                return (spanX.Length - i).CompareTo(spanY.Length - j);\n            }\n        }\n#endif\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Jobs/JobExtensions.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Linq;\nusing BenchmarkDotNet.Analysers;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Toolchains;\nusing BenchmarkDotNet.Toolchains.NativeAot;\nusing JetBrains.Annotations;\nusing Perfolizer.Horology;\nusing Perfolizer.Mathematics.OutlierDetection;\n\nnamespace BenchmarkDotNet.Jobs\n{\n    public static class JobExtensions\n    {\n        public static Job WithPlatform(this Job job, Platform platform) => job.WithCore(j => j.Environment.Platform = platform);\n\n        public static Job WithId(this Job job, string id) => new Job(id, job);\n\n        // Env\n        public static Job WithJit(this Job job, Jit jit) => job.WithCore(j => j.Environment.Jit = jit);\n\n        public static Job WithRuntime(this Job job, Runtime runtime) => job.WithCore(j => j.Environment.Runtime = runtime);\n\n        /// <summary>\n        /// ProcessorAffinity for the benchmark process.\n        /// See also: https://msdn.microsoft.com/library/system.diagnostics.process.processoraffinity.aspx\n        /// </summary>\n        public static Job WithAffinity(this Job job, IntPtr affinity) => job.WithCore(j => j.Environment.Affinity = affinity);\n\n        /// <summary>\n        /// Specifies whether the common language runtime runs server garbage collection.\n        /// <value>false: Does not run server garbage collection. This is the default.</value>\n        /// <value>true: Runs server garbage collection.</value>\n        /// </summary>\n        public static Job WithGcServer(this Job job, bool value) => job.WithCore(j => j.Environment.Gc.Server = value);\n\n        /// <summary>\n        /// Specifies whether the common language runtime runs garbage collection on a separate thread.\n        /// <value>false: Does not run garbage collection concurrently.</value>\n        /// <value>true: Runs garbage collection concurrently. This is the default.</value>\n        /// </summary>\n        public static Job WithGcConcurrent(this Job job, bool value) => job.WithCore(j => j.Environment.Gc.Concurrent = value);\n\n        /// <summary>\n        /// Specifies whether garbage collection supports multiple CPU groups.\n        /// <value>false: Garbage collection does not support multiple CPU groups. This is the default.</value>\n        /// <value>true: Garbage collection supports multiple CPU groups, if server garbage collection is enabled.</value>\n        /// </summary>\n        [PublicAPI]\n        public static Job WithGcCpuGroups(this Job job, bool value) => job.WithCore(j => j.Environment.Gc.CpuGroups = value);\n\n        /// <summary>\n        /// Specifies whether the BenchmarkDotNet's benchmark runner forces full garbage collection after each benchmark invocation\n        /// <value>false: Does not force garbage collection.</value>\n        /// <value>true: Forces full garbage collection after each benchmark invocation. This is the default.</value>\n        /// </summary>\n        public static Job WithGcForce(this Job job, bool value) => job.WithCore(j => j.Environment.Gc.Force = value);\n\n        /// <summary>\n        /// On 64-bit platforms, enables arrays that are greater than 2 gigabytes (GB) in total size.\n        /// <value>false: Arrays greater than 2 GB in total size are not enabled. This is the default.</value>\n        /// <value>true: Arrays greater than 2 GB in total size are enabled on 64-bit platforms.</value>\n        /// </summary>\n        public static Job WithGcAllowVeryLargeObjects(this Job job, bool value) => job.WithCore(j => j.Environment.Gc.AllowVeryLargeObjects = value);\n\n        /// <summary>\n        /// Specifies that benchmark can handle addresses larger than 2 gigabytes.\n        /// </summary>\n        public static Job WithLargeAddressAware(this Job job, bool value = true) => job.WithCore(j => j.Environment.LargeAddressAware = value);\n\n        /// <summary>\n        /// Put segments that should be deleted on a standby list for future use instead of releasing them back to the OS\n        /// <remarks>The default is false</remarks>\n        /// </summary>\n        [PublicAPI]\n        public static Job WithGcRetainVm(this Job job, bool value) => job.WithCore(j => j.Environment.Gc.RetainVm = value);\n\n        /// <summary>\n        ///  specify the # of Server GC threads/heaps, must be smaller than the # of logical CPUs the process is allowed to run on,\n        ///  ie, if you don't specifically affinitize your process it means the # of total logical CPUs on the machine;\n        ///  otherwise this is the # of logical CPUs you affinitized your process to.\n        /// </summary>\n        [PublicAPI]\n        public static Job WithHeapCount(this Job job, int heapCount) => job.WithCore(j => j.Environment.Gc.HeapCount = heapCount);\n\n        /// <summary>\n        /// specify true to disable hard affinity of Server GC threads to CPUs\n        /// </summary>\n        [PublicAPI]\n        public static Job WithNoAffinitize(this Job job, bool value) => job.WithCore(j => j.Environment.Gc.NoAffinitize = value);\n\n        /// <summary>\n        /// process mask, see <see href=\"https://support.microsoft.com/en-us/help/4014604/may-2017-description-of-the-quality-rollup-for-the-net-framework-4-6-4\">MSDN</see> for more.\n        /// </summary>\n        [PublicAPI]\n        public static Job WithHeapAffinitizeMask(this Job job, int heapAffinitizeMask) =>\n            job.WithCore(j => j.Environment.Gc.HeapAffinitizeMask = heapAffinitizeMask);\n\n        [PublicAPI]\n        public static Job WithGcMode(this Job job, GcMode gc) => job.WithCore(j => EnvironmentMode.GcCharacteristic[j] = gc);\n\n        /// <summary>\n        /// Available values: Throughput, ColdStart and Monitoring.\n        ///     Throughput: default strategy which allows to get good precision level.\n        ///     ColdStart: should be used only for measuring cold start of the application or testing purpose.\n        ///     Monitoring: no overhead evaluating, with several target iterations. Perfect for macrobenchmarks without a steady state with high variance.\n        /// </summary>\n        public static Job WithStrategy(this Job job, RunStrategy strategy) => job.WithCore(j => j.Run.RunStrategy = strategy);\n\n        /// <summary>\n        /// How many times we should launch process with target benchmark.\n        /// </summary>\n        public static Job WithLaunchCount(this Job job, int count) => job.WithCore(j => j.Run.LaunchCount = count);\n\n        /// <summary>\n        /// How many warmup iterations should be performed.\n        /// </summary>\n        public static Job WithWarmupCount(this Job job, int count) => job.WithCore(j => j.Run.WarmupCount = count);\n\n        /// <summary>\n        /// Minimum count of warmup iterations that should be performed\n        /// The default value is 6\n        /// </summary>\n        public static Job WithMinWarmupCount(this Job job, int count) => job.WithCore(j => j.Run.MinWarmupIterationCount = count);\n\n        /// <summary>\n        /// Maximum count of warmup iterations that should be performed\n        /// The default value is 50\n        /// </summary>\n        public static Job WithMaxWarmupCount(this Job job, int count) => job.WithCore(j => j.Run.MaxWarmupIterationCount = count);\n\n        /// <summary>\n        /// How many target iterations should be performed.\n        /// If specified, <see cref=\"RunMode.MinIterationCount\"/> will be ignored.\n        /// If specified, <see cref=\"RunMode.MaxIterationCount\"/> will be ignored.\n        /// </summary>\n        public static Job WithIterationCount(this Job job, int count) => job.WithCore(j => j.Run.IterationCount = count);\n\n        /// <summary>\n        /// Desired time of execution of an iteration. Used by Pilot stage to estimate the number of invocations per iteration.\n        /// The default value is 500 milliseconds.\n        /// </summary>\n        public static Job WithIterationTime(this Job job, TimeInterval time) => job.WithCore(j => j.Run.IterationTime = time);\n\n        /// <summary>\n        /// Invocation count in a single iteration.\n        /// If specified, <see cref=\"RunMode.IterationTime\"/> will be ignored.\n        /// If specified, it must be a multiple of <see cref=\"RunMode.UnrollFactor\"/>.\n        /// </summary>\n        public static Job WithInvocationCount(this Job job, long count) => job.WithCore(j => j.Run.InvocationCount = count);\n\n        /// <summary>\n        /// How many times the benchmark method will be invoked per one iteration of a generated loop.\n        /// The default value is 16.\n        /// </summary>\n        public static Job WithUnrollFactor(this Job job, int factor) => job.WithCore(j => j.Run.UnrollFactor = factor);\n\n        /// <summary>\n        /// Run the benchmark exactly once per iteration.\n        /// </summary>\n        public static Job RunOncePerIteration(this Job job) => job.WithInvocationCount(1).WithUnrollFactor(1);\n\n        /// <summary>\n        /// Minimum count of target iterations that should be performed.\n        /// The default value is 15.\n        /// <remarks>If you set this value to below 15, then <see cref=\"MultimodalDistributionAnalyzer\"/> is not going to work.</remarks>\n        /// </summary>\n        public static Job WithMinIterationCount(this Job job, int count) => job.WithCore(j => j.Run.MinIterationCount = count);\n\n        /// <summary>\n        /// Maximum count of target iterations that should be performed.\n        /// The default value is 100.\n        /// <remarks>If you set this value to below 15, then <see cref=\"MultimodalDistributionAnalyzer\"/>  is not going to work.</remarks>\n        /// </summary>\n        public static Job WithMaxIterationCount(this Job job, int count) => job.WithCore(j => j.Run.MaxIterationCount = count);\n\n        /// <summary>\n        /// Power plan for benchmarks.\n        /// The default value is HighPerformance.\n        /// <remarks>Only available for Windows.</remarks>\n        /// </summary>\n        public static Job WithPowerPlan(this Job job, PowerPlan powerPlan) => job.WithCore(j => j.Environment.PowerPlanMode = PowerManagementApplier.Map(powerPlan));\n\n        /// <summary>\n        /// Setting power plans by guid.\n        /// The default value is HighPerformance.\n        /// <remarks>Only available for Windows.</remarks>\n        /// </summary>\n        public static Job WithPowerPlan(this Job job, Guid powerPlanGuid) => job.WithCore(j => j.Environment.PowerPlanMode = powerPlanGuid);\n\n        /// <summary>\n        /// ensures that BenchmarkDotNet does not enforce any power plan\n        /// </summary>\n        public static Job DontEnforcePowerPlan(this Job job) => job.WithCore(j => j.Environment.PowerPlanMode = Guid.Empty);\n\n        /// <summary>\n        /// specifies whether Engine should allocate some random-sized memory between iterations\n        /// <remarks>it makes [GlobalCleanup] and [GlobalSetup] methods to be executed after every iteration</remarks>\n        /// </summary>\n        public static Job WithMemoryRandomization(this Job job, bool enable = true) => job.WithCore(j => j.Run.MemoryRandomization = enable);\n\n        // Infrastructure\n        public static Job WithToolchain(this Job job, IToolchain toolchain) => job.WithCore(j => j.Infrastructure.Toolchain = toolchain);\n\n        [PublicAPI] public static Job WithClock(this Job job, IClock clock) => job.WithCore(j => j.Infrastructure.Clock = clock);\n\n        [PublicAPI] public static Job WithEngineFactory(this Job job, IEngineFactory engineFactory) => job.WithCore(j => j.Infrastructure.EngineFactory = engineFactory);\n\n        public static Job WithCustomBuildConfiguration(this Job job, string buildConfiguration) =>\n            job.WithCore(j => j.Infrastructure.BuildConfiguration = buildConfiguration);\n\n        /// <summary>\n        /// Creates a new job based on the given job with specified environment variables.\n        /// It overrides the whole list of environment variables which were defined in the original job.\n        /// </summary>\n        /// <param name=\"job\">The original job</param>\n        /// <param name=\"environmentVariables\">The environment variables for the new job</param>\n        /// <exception cref=\"InvalidOperationException\">\n        /// Throws an exception if <paramref name=\"environmentVariables\"/> contains two variables with the same key.\n        /// </exception>\n        /// <returns>The new job with overriden environment variables</returns>\n        public static Job WithEnvironmentVariables(this Job job, params EnvironmentVariable[] environmentVariables)\n        {\n            var keys = new HashSet<string>();\n            foreach (var variable in environmentVariables)\n            {\n                if (keys.Contains(variable.Key))\n                    throw new InvalidOperationException($\"The '{variable.Key}' environment variables is defined twice\");\n                keys.Add(variable.Key);\n            }\n            return job.WithCore(j => j.Environment.EnvironmentVariables = environmentVariables);\n        }\n\n        /// <summary>\n        /// Creates a new job based on the given job with additional environment variable.\n        /// All existed environment variables of the original job will be copied to the new one.\n        /// If the original job already contains an environment variable with the same key, it will be overriden.\n        /// </summary>\n        /// <param name=\"job\">The original job</param>\n        /// <param name=\"environmentVariable\">The new environment variable which should be added for the new job</param>\n        /// <returns>The new job with additional environment variable</returns>\n        public static Job WithEnvironmentVariable(this Job job, EnvironmentVariable environmentVariable)\n            => job.WithCore(j => j.Environment.SetEnvironmentVariable(environmentVariable));\n\n        /// <summary>\n        /// Creates a new job based on the given job with additional environment variable.\n        /// All existed environment variables of the original job will be copied to the new one.\n        /// If the original job already contains an environment variable with the same key, it will be overriden.\n        /// </summary>\n        /// <param name=\"job\">The original job</param>\n        /// <param name=\"key\">The key of the new environment variable</param>\n        /// <param name=\"value\">The value of the new environment variable</param>\n        /// <returns>The new job with additional environment variable</returns>\n        public static Job WithEnvironmentVariable(this Job job, string key, string value)\n            => job.WithEnvironmentVariable(new EnvironmentVariable(key, value));\n\n        /// <summary>\n        /// Creates a new job based on the given job without any environment variables.\n        /// </summary>\n        /// <param name=\"job\">The original job</param>\n        /// <returns>The new job which doesn't have any environment variables</returns>\n        public static Job WithoutEnvironmentVariables(this Job job) => job.WithEnvironmentVariables([]);\n\n        public static Job WithArguments(this Job job, IReadOnlyList<Argument> arguments) => job.WithCore(j => j.Infrastructure.Arguments = arguments);\n\n        public static Job WithMsBuildArguments(this Job job, params string[] msBuildArguments)\n            => job.WithArguments([.. msBuildArguments.Select(a => new MsBuildArgument(a))]);\n\n        // Accuracy\n        /// <summary>\n        /// Maximum acceptable error for a benchmark (by default, BenchmarkDotNet continue iterations until the actual error is less than the specified error).\n        /// The default value is 0.02.\n        /// <remarks>If <see cref=\"AccuracyMode.MaxAbsoluteError\"/> is also provided, the smallest value is used as stop criteria.</remarks>\n        /// </summary>\n        public static Job WithMaxRelativeError(this Job job, double value) => job.WithCore(j => j.Accuracy.MaxRelativeError = value);\n\n        /// <summary>\n        /// Maximum acceptable error for a benchmark (by default, BenchmarkDotNet continue iterations until the actual error is less than the specified error).\n        /// Doesn't have a default value.\n        /// <remarks>If <see cref=\"AccuracyMode.MaxRelativeError\"/> is also provided, the smallest value is used as stop criteria.</remarks>\n        /// </summary>\n        public static Job WithMaxAbsoluteError(this Job job, TimeInterval interval) => job.WithCore(j => j.Accuracy.MaxAbsoluteError = interval);\n\n        /// <summary>\n        /// Minimum time of a single iteration. Unlike Run.IterationTime, this characteristic specifies only the lower limit. In case of need, BenchmarkDotNet can increase this value.\n        /// The default value is 500 milliseconds.\n        /// </summary>\n        public static Job WithMinIterationTime(this Job job, TimeInterval interval) => job.WithCore(j => j.Accuracy.MinIterationTime = interval);\n\n        /// <summary>\n        /// Minimum count of benchmark invocations per iteration\n        /// The default value is 4.\n        /// </summary>\n        public static Job WithMinInvokeCount(this Job job, int value) => job.WithCore(j => j.Accuracy.MinInvokeCount = value);\n\n        /// <summary>\n        /// Specifies if the overhead should be evaluated (Idle runs) and it's average value subtracted from every result.\n        /// False by default.\n        /// <remarks>WithEvaluateOverhead is deprecated.</remarks>\n        /// </summary>\n        [Obsolete(\"Overhead evaluation affects the accuracy of benchmark results. This will be removed soon.\")]\n        public static Job WithEvaluateOverhead(this Job job, bool value) => job.WithCore(j => j.Accuracy.EvaluateOverhead = value);\n\n        /// <summary>\n        /// Specifies which outliers should be removed from the distribution\n        /// </summary>\n        public static Job WithOutlierMode(this Job job, OutlierMode value) => job.WithCore(j => j.Accuracy.OutlierMode = value);\n\n        [PublicAPI]\n        public static Job WithAnalyzeLaunchVariance(this Job job, bool value) => job.WithCore(j => j.Accuracy.AnalyzeLaunchVariance = value);\n\n        // Meta\n        public static Job AsBaseline(this Job job) => job.WithCore(j => j.Meta.Baseline = true);\n        public static Job WithBaseline(this Job job, bool value) => job.WithCore(j => j.Meta.Baseline = value);\n\n        /// <summary>\n        /// mutator job should not be added to the config, but instead applied to other jobs in given config\n        /// </summary>\n        public static Job AsMutator(this Job job) => job.WithCore(j => j.Meta.IsMutator = true);\n\n        /// <summary>\n        /// use it if you want to specify custom default settings for default job used by console arguments parser\n        /// </summary>\n        public static Job AsDefault(this Job job, bool value = true) => job.WithCore(j => j.Meta.IsDefault = value);\n\n        internal static Job MakeSettingsUserFriendly(this Job job, Descriptor descriptor)\n        {\n            // users expect that if IterationSetup is configured, it should be run before every benchmark invocation https://github.com/dotnet/BenchmarkDotNet/issues/730\n            if ((descriptor.IterationSetupMethod != null || descriptor.IterationCleanupMethod != null)\n                && !job.HasValue(RunMode.InvocationCountCharacteristic)\n                && !job.HasValue(RunMode.UnrollFactorCharacteristic))\n            {\n                return job.RunOncePerIteration();\n            }\n\n            return job;\n        }\n\n        internal static bool IsNativeAOT(this Job job)\n            => job.Environment.GetRuntime() is NativeAotRuntime\n            // given job can have NativeAOT toolchain set, but Runtime == default\n            || (job.Infrastructure.TryGetToolchain(out var toolchain) && toolchain is NativeAotToolchain);\n\n        private static Job WithCore(this Job job, Action<Job> updateCallback)\n        {\n            bool hasId = job.HasValue(Job.IdCharacteristic);\n\n            var newJob = hasId ? new Job(job.Id, job) : new Job(job);\n            updateCallback(newJob);\n            return newJob;\n        }\n\n        internal static bool HasDynamicBuildCharacteristic(this Job job)\n            => job.HasValue(InfrastructureMode.BuildConfigurationCharacteristic)\n            || job.HasValue(InfrastructureMode.ArgumentsCharacteristic);\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Jobs/JobIdGenerator.cs",
    "content": "﻿using System;\nusing BenchmarkDotNet.Characteristics;\n\nnamespace BenchmarkDotNet.Jobs\n{\n    public static class JobIdGenerator\n    {\n        public static string GenerateRandomId(Job job)\n        {\n            string presentation = CharacteristicSetPresenter.Display.ToPresentation(job);\n            if (presentation == \"\")\n                return \"DefaultJob\";\n            int seed = GetStableHashCode(presentation);\n            var random = new Random(seed);\n            string id = \"\";\n            for (int i = 0; i < 6; i++)\n                id += (char)('A' + random.Next(26));\n            return \"Job-\" + id;\n        }\n\n        // Compute string hash value with DJB2 algorithm.\n        private static int GetStableHashCode(string value)\n        {\n            uint hash = 5381;\n            foreach (char c in value)\n            {\n                hash = ((hash << 5) + hash) + c; // hash * 32 + hash + c\n            }\n            return unchecked((int)hash);\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Jobs/JobMode`1.cs",
    "content": "﻿using BenchmarkDotNet.Characteristics;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Jobs\n{\n    public abstract class JobMode<T> : CharacteristicObject<T> where T : JobMode<T>, new()\n    {\n        public static readonly T Default = new T().Freeze();\n\n        protected JobMode() { }\n\n        protected JobMode(string id) : base(id) { }\n\n        [PublicAPI] public Job Job => (Job)OwnerOrSelf;\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Jobs/MetaMode.cs",
    "content": "﻿using BenchmarkDotNet.Characteristics;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Jobs\n{\n    public class MetaMode : JobMode<MetaMode>\n    {\n        [PublicAPI] public static readonly Characteristic<bool> BaselineCharacteristic = CreateHiddenCharacteristic<bool>(nameof(Baseline));\n        [PublicAPI] public static readonly Characteristic<bool> IsMutatorCharacteristic = CreateIgnoreOnApplyCharacteristic<bool>(nameof(IsMutator));\n        [PublicAPI] public static readonly Characteristic<bool> IsDefaultCharacteristic = CreateHiddenCharacteristic<bool>(nameof(IsDefault));\n\n        public bool Baseline\n        {\n            get => BaselineCharacteristic[this];\n            set => BaselineCharacteristic[this] = value;\n        }\n\n        /// <summary>\n        /// mutator job should not be added to the config, but instead applied to other jobs in given config\n        /// </summary>\n        public bool IsMutator\n        {\n            get => IsMutatorCharacteristic[this];\n            set => IsMutatorCharacteristic[this] = value;\n        }\n\n        /// <summary>\n        /// set to true if you want to specify custom default settings for default job used by console arguments parser\n        /// </summary>\n        public bool IsDefault\n        {\n            get => IsDefaultCharacteristic[this];\n            set => IsDefaultCharacteristic[this] = value;\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Jobs/RunMode.cs",
    "content": "﻿using System.Diagnostics.CodeAnalysis;\nusing BenchmarkDotNet.Analysers;\nusing BenchmarkDotNet.Characteristics;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Models;\nusing Perfolizer.Horology;\n\nnamespace BenchmarkDotNet.Jobs\n{\n    [SuppressMessage(\"ReSharper\", \"UnusedMember.Global\")]\n    public sealed class RunMode : JobMode<RunMode>\n    {\n        public static readonly Characteristic<RunStrategy> RunStrategyCharacteristic =\n            Characteristic.Create<RunMode, RunStrategy>(nameof(RunStrategy), RunStrategy.Throughput);\n\n        public static readonly Characteristic<int> LaunchCountCharacteristic = CreateCharacteristic<int>(nameof(LaunchCount));\n        public static readonly Characteristic<long> InvocationCountCharacteristic = CreateCharacteristic<long>(nameof(InvocationCount));\n        public static readonly Characteristic<int> UnrollFactorCharacteristic = CreateCharacteristic<int>(nameof(UnrollFactor));\n        public static readonly Characteristic<int> IterationCountCharacteristic = CreateCharacteristic<int>(nameof(IterationCount));\n        public static readonly Characteristic<int> MinIterationCountCharacteristic = CreateCharacteristic<int>(nameof(MinIterationCount));\n        public static readonly Characteristic<int> MaxIterationCountCharacteristic = CreateCharacteristic<int>(nameof(MaxIterationCount));\n        public static readonly Characteristic<TimeInterval> IterationTimeCharacteristic = CreateCharacteristic<TimeInterval>(nameof(IterationTime));\n        public static readonly Characteristic<int> WarmupCountCharacteristic = CreateCharacteristic<int>(nameof(WarmupCount));\n        public static readonly Characteristic<int> MinWarmupIterationCountCharacteristic = CreateCharacteristic<int>(nameof(MinWarmupIterationCount));\n        public static readonly Characteristic<int> MaxWarmupIterationCountCharacteristic = CreateCharacteristic<int>(nameof(MaxWarmupIterationCount));\n        public static readonly Characteristic<bool> MemoryRandomizationCharacteristic = CreateCharacteristic<bool>(nameof(MemoryRandomization));\n\n        public static readonly RunMode Dry = new RunMode(nameof(Dry))\n        {\n            LaunchCount = 1,\n            IterationCount = 1,\n            RunStrategy = RunStrategy.ColdStart, // WarmupStage is not invoked when using RunStrategy.ColdStart.\n            UnrollFactor = 1\n        }.Freeze();\n\n        public static readonly RunMode Short = new RunMode(nameof(Short))\n        {\n            LaunchCount = 1,\n            WarmupCount = 3,\n            IterationCount = 3\n        }.Freeze();\n\n        public static readonly RunMode Medium = new RunMode(nameof(Medium))\n        {\n            LaunchCount = 2,\n            WarmupCount = 10,\n            IterationCount = 15\n        }.Freeze();\n\n        public static readonly RunMode Long = new RunMode(nameof(Long))\n        {\n            LaunchCount = 3,\n            WarmupCount = 15,\n            IterationCount = 100\n        }.Freeze();\n\n        public static readonly RunMode VeryLong = new RunMode(nameof(VeryLong))\n        {\n            LaunchCount = 4,\n            WarmupCount = 30,\n            IterationCount = 500\n        }.Freeze();\n\n\n        public RunMode() : this(\"\") { }\n\n        private RunMode(string id) : base(id) { }\n\n        /// <summary>\n        /// Available values: Throughput and ColdStart.\n        ///     Throughput: default strategy which allows to get good precision level.\n        ///     ColdStart: should be used only for measuring cold start of the application or testing purpose.\n        ///     Monitoring: no overhead evaluating, with several target iterations. Perfect for macrobenchmarks without a steady state with high variance.\n        /// </summary>\n        public RunStrategy RunStrategy\n        {\n            get { return RunStrategyCharacteristic[this]; }\n            set { RunStrategyCharacteristic[this] = value; }\n        }\n\n        /// <summary>\n        /// How many times we should launch process with target benchmark.\n        /// </summary>\n        public int LaunchCount\n        {\n            get { return LaunchCountCharacteristic[this]; }\n            set { LaunchCountCharacteristic[this] = value; }\n        }\n\n        /// <summary>\n        /// How many warmup iterations should be performed.\n        /// </summary>\n        public int WarmupCount\n        {\n            get { return WarmupCountCharacteristic[this]; }\n            set { WarmupCountCharacteristic[this] = value; }\n        }\n\n        /// <summary>\n        /// How many target iterations should be performed\n        /// If specified, <see cref=\"MinIterationCount\"/> will be ignored.\n        /// If specified, <see cref=\"MaxIterationCount\"/> will be ignored.\n        /// </summary>\n        public int IterationCount\n        {\n            get { return IterationCountCharacteristic[this]; }\n            set { IterationCountCharacteristic[this] = value; }\n        }\n\n        /// <summary>\n        /// Desired time of execution of an iteration. Used by Pilot stage to estimate the number of invocations per iteration.\n        /// The default value is 500 milliseconds.\n        /// </summary>\n        public TimeInterval IterationTime\n        {\n            get { return IterationTimeCharacteristic[this]; }\n            set { IterationTimeCharacteristic[this] = value; }\n        }\n\n        /// <summary>\n        /// Invocation count in a single iteration.\n        /// If specified, <see cref=\"IterationTime\"/> will be ignored.\n        /// If specified, it must be a multiple of <see cref=\"UnrollFactor\"/>.\n        /// </summary>\n        public long InvocationCount\n        {\n            get { return InvocationCountCharacteristic[this]; }\n            set { InvocationCountCharacteristic[this] = value; }\n        }\n\n        /// <summary>\n        /// How many times the benchmark method will be invoked per one iteration of a generated loop.\n        /// </summary>\n        public int UnrollFactor\n        {\n            get { return UnrollFactorCharacteristic[this]; }\n            set { UnrollFactorCharacteristic[this] = value; }\n        }\n\n        /// <summary>\n        /// Minimum count of target iterations that should be performed\n        /// The default value is 15\n        /// <remarks>If you set this value to below 15, then <see cref=\"MultimodalDistributionAnalyzer\"/> is not going to work</remarks>\n        /// </summary>\n        public int MinIterationCount\n        {\n            get { return MinIterationCountCharacteristic[this]; }\n            set { MinIterationCountCharacteristic[this] = value; }\n        }\n\n        /// <summary>\n        /// Maximum count of target iterations that should be performed\n        /// The default value is 100\n        /// <remarks>If you set this value to below 15, then <see cref=\"MultimodalDistributionAnalyzer\"/>  is not going to work</remarks>\n        /// </summary>\n        public int MaxIterationCount\n        {\n            get { return MaxIterationCountCharacteristic[this]; }\n            set { MaxIterationCountCharacteristic[this] = value; }\n        }\n\n        /// <summary>\n        /// Minimum count of warmup iterations that should be performed\n        /// The default value is 6\n        /// </summary>\n        public int MinWarmupIterationCount\n        {\n            get { return MinWarmupIterationCountCharacteristic[this]; }\n            set { MinWarmupIterationCountCharacteristic[this] = value; }\n        }\n\n        /// <summary>\n        /// Maximum count of warmup iterations that should be performed\n        /// The default value is 50\n        /// </summary>\n        public int MaxWarmupIterationCount\n        {\n            get { return MaxWarmupIterationCountCharacteristic[this]; }\n            set { MaxWarmupIterationCountCharacteristic[this] = value; }\n        }\n\n        /// <summary>\n        /// specifies whether Engine should allocate some random-sized memory between iterations\n        /// <remarks>it makes [GlobalCleanup] and [GlobalSetup] methods to be executed after every iteration</remarks>\n        /// </summary>\n        public bool MemoryRandomization\n        {\n            get => MemoryRandomizationCharacteristic[this];\n            set => MemoryRandomizationCharacteristic[this] = value;\n        }\n\n        internal BdnExecution ToPerfonar() => new()\n        {\n            LaunchCount = HasValue(LaunchCountCharacteristic) ? LaunchCount : null,\n            WarmupCount = HasValue(WarmupCountCharacteristic) ? WarmupCount : null,\n            IterationCount = HasValue(IterationCountCharacteristic) ? IterationCount : null,\n            IterationTimeMs = HasValue(IterationTimeCharacteristic) ? IterationTime.ToMilliseconds().RoundToLong() : null,\n            InvocationCount = HasValue(InvocationCountCharacteristic) ? InvocationCount : null,\n            UnrollFactor = HasValue(UnrollFactorCharacteristic) ? UnrollFactor : null,\n            MinIterationCount = HasValue(MinIterationCountCharacteristic) ? MinIterationCount : null,\n            MaxIterationCount = HasValue(MaxIterationCountCharacteristic) ? MaxIterationCount : null,\n            MinWarmupIterationCount = HasValue(MinWarmupIterationCountCharacteristic) ? MinWarmupIterationCount : null,\n            MaxWarmupIterationCount = HasValue(MaxWarmupIterationCountCharacteristic) ? MaxWarmupIterationCount : null,\n            MemoryRandomization = HasValue(MemoryRandomizationCharacteristic) ? MemoryRandomization : null,\n            RunStrategy = HasValue(RunStrategyCharacteristic) ? RunStrategy : null,\n        };\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Loggers/AccumulationLogger.cs",
    "content": "﻿using System;\nusing System.Text;\n\nnamespace BenchmarkDotNet.Loggers\n{\n    public class AccumulationLogger : ILogger\n    {\n        private readonly StringBuilder builder = new StringBuilder();\n\n        public AccumulationLogger()\n        {\n            // All AccumulationLoggers should have unique Ids\n            Id = nameof(AccumulationLogger) + \".\" + Guid.NewGuid().ToString(\"N\");\n        }\n\n        public string Id { get; }\n        public int Priority => 0;\n\n        public virtual void Write(LogKind logKind, string text) => builder.Append(text);\n\n        public virtual void WriteLine() => builder.AppendLine();\n\n        public virtual void WriteLine(LogKind logKind, string text) => builder.AppendLine(text);\n\n        public void Flush() { }\n\n        public void ClearLog() => builder.Clear();\n\n        public string GetLog() => builder.ToString();\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Loggers/AsyncProcessOutputReader.cs",
    "content": "﻿using System;\nusing System.Collections.Concurrent;\nusing System.Collections.Immutable;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Threading;\n\nnamespace BenchmarkDotNet.Loggers\n{\n    internal class AsyncProcessOutputReader : IDisposable\n    {\n        private readonly Process process;\n        private readonly ILogger logger;\n        private readonly bool logOutput, readStandardError;\n\n        private static readonly TimeSpan FinishEventTimeout = TimeSpan.FromSeconds(1);\n        private readonly AutoResetEvent outputFinishEvent, errorFinishEvent;\n        private readonly ConcurrentQueue<string> output, error;\n\n        private long status;\n\n        internal AsyncProcessOutputReader(Process process, bool logOutput = false, ILogger? logger = null, bool readStandardError = true)\n        {\n            if (!process.StartInfo.RedirectStandardOutput)\n                throw new NotSupportedException(\"set RedirectStandardOutput to true first\");\n            if (readStandardError && !process.StartInfo.RedirectStandardError)\n                throw new NotSupportedException(\"set RedirectStandardError to true first\");\n            if (logOutput && logger == null)\n                throw new ArgumentException($\"{nameof(logger)} cannot be null when {nameof(logOutput)} is true\");\n\n            this.process = process;\n            output = new ConcurrentQueue<string>();\n            error = new ConcurrentQueue<string>();\n            outputFinishEvent = new AutoResetEvent(false);\n            errorFinishEvent = new AutoResetEvent(false);\n            status = (long)Status.Created;\n            this.logOutput = logOutput;\n            this.logger = logger ?? NullLogger.Instance;\n            this.readStandardError = readStandardError;\n        }\n\n        public void Dispose()\n        {\n            Interlocked.Exchange(ref status, (long)Status.Disposed);\n\n            Detach();\n\n            outputFinishEvent.Dispose();\n            errorFinishEvent.Dispose();\n        }\n\n        internal void BeginRead()\n        {\n            if (Interlocked.CompareExchange(ref status, (long)Status.Started, (long)Status.Created) != (long)Status.Created)\n                throw new InvalidOperationException(\"Reader can be started only once\");\n\n            Attach();\n\n            process.BeginOutputReadLine();\n\n            if (readStandardError)\n                process.BeginErrorReadLine();\n        }\n\n        internal void CancelRead()\n        {\n            if (Interlocked.CompareExchange(ref status, (long)Status.Stopped, (long)Status.Started) != (long)Status.Started)\n                throw new InvalidOperationException(\"Only a started reader can be stopped\");\n\n            process.CancelOutputRead();\n\n            if (readStandardError)\n                process.CancelErrorRead();\n\n            Detach();\n        }\n\n        internal void StopRead()\n        {\n            if (Interlocked.CompareExchange(ref status, (long)Status.Stopped, (long)Status.Started) != (long)Status.Started)\n                throw new InvalidOperationException(\"Only a started reader can be stopped\");\n\n            outputFinishEvent.WaitOne(FinishEventTimeout);\n            if (readStandardError)\n                errorFinishEvent.WaitOne(FinishEventTimeout);\n\n            Detach();\n        }\n\n        internal ImmutableArray<string> GetOutputLines() => ReturnIfStopped(() => output.ToImmutableArray());\n\n        internal ImmutableArray<string> GetErrorLines() => ReturnIfStopped(() => error.ToImmutableArray());\n\n        internal ImmutableArray<string> GetOutputAndErrorLines() => ReturnIfStopped(() => output.Concat(error).ToImmutableArray());\n\n        internal string GetOutputText() => ReturnIfStopped(() => string.Join(Environment.NewLine, output));\n\n        internal string GetErrorText() => ReturnIfStopped(() => string.Join(Environment.NewLine, error));\n\n        private void Attach()\n        {\n            process.OutputDataReceived += ProcessOnOutputDataReceived;\n\n            if (readStandardError)\n                process.ErrorDataReceived += ProcessOnErrorDataReceived;\n        }\n\n        private void Detach()\n        {\n            process.OutputDataReceived -= ProcessOnOutputDataReceived;\n\n            if (readStandardError)\n                process.ErrorDataReceived -= ProcessOnErrorDataReceived;\n        }\n\n        private void ProcessOnOutputDataReceived(object sender, DataReceivedEventArgs e)\n        {\n            if (e.Data != null)\n            {\n                if (!string.IsNullOrEmpty(e.Data))\n                {\n                    output.Enqueue(e.Data);\n\n                    if (logOutput)\n                    {\n                        logger.WriteLine(e.Data);\n                    }\n                }\n            }\n            else // 'e.Data == null' means EOF\n                outputFinishEvent.Set();\n        }\n\n        private void ProcessOnErrorDataReceived(object sender, DataReceivedEventArgs e)\n        {\n            if (e.Data != null)\n            {\n                if (!string.IsNullOrEmpty(e.Data))\n                {\n                    error.Enqueue(e.Data);\n\n                    if (logOutput)\n                    {\n                        logger.WriteLineError(e.Data);\n                    }\n                }\n            }\n            else // 'e.Data == null' means EOF\n                errorFinishEvent.Set();\n        }\n\n        private T ReturnIfStopped<T>(Func<T> getter)\n            => Interlocked.Read(ref status) == (long)Status.Stopped\n                ? getter.Invoke()\n                : throw new InvalidOperationException(\"The reader must be stopped first\");\n\n        private enum Status : long\n        {\n            Created,\n            Started,\n            Stopped,\n            Disposed\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Loggers/Broker.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.IO;\nusing System.IO.Pipes;\nusing System.Text;\nusing BenchmarkDotNet.Diagnosers;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Running;\n\nnamespace BenchmarkDotNet.Loggers\n{\n    internal class Broker : IDisposable\n    {\n        private readonly ILogger logger;\n        private readonly Process process;\n        private readonly CompositeInProcessDiagnoser compositeInProcessDiagnoser;\n        private readonly AnonymousPipeServerStream inputFromBenchmark, acknowledgments;\n\n        private enum Result\n        {\n            Success,\n            EndOfStream,\n            InvalidData,\n        }\n\n        public Broker(ILogger logger, Process process, IDiagnoser? diagnoser, CompositeInProcessDiagnoser compositeInProcessDiagnoser,\n            BenchmarkCase benchmarkCase, BenchmarkId benchmarkId, AnonymousPipeServerStream inputFromBenchmark, AnonymousPipeServerStream acknowledgments)\n        {\n            this.logger = logger;\n            this.process = process;\n            this.Diagnoser = diagnoser;\n            this.compositeInProcessDiagnoser = compositeInProcessDiagnoser;\n            this.inputFromBenchmark = inputFromBenchmark;\n            this.acknowledgments = acknowledgments;\n            DiagnoserActionParameters = new DiagnoserActionParameters(process, benchmarkCase, benchmarkId);\n\n            process.EnableRaisingEvents = true;\n            process.Exited += OnProcessExited;\n        }\n\n        internal IDiagnoser? Diagnoser { get; }\n\n        internal DiagnoserActionParameters DiagnoserActionParameters { get; }\n\n        internal List<string> Results { get; } = [];\n\n        internal List<string> PrefixedOutput { get; } = [];\n\n        public void Dispose()\n        {\n            process.Exited -= OnProcessExited;\n\n            // Dispose all the pipes to let reading from pipe finish with EOF and avoid a resource leak.\n            DisposeLocalCopyOfClientHandles();\n            inputFromBenchmark.Dispose();\n            acknowledgments.Dispose();\n        }\n\n        private void OnProcessExited(object? sender, EventArgs e)\n        {\n            DisposeLocalCopyOfClientHandles();\n        }\n\n        private void DisposeLocalCopyOfClientHandles()\n        {\n            inputFromBenchmark.DisposeLocalCopyOfClientHandle();\n            acknowledgments.DisposeLocalCopyOfClientHandle();\n        }\n\n        internal void ProcessData()\n        {\n            // When the process fails to start, there is no pipe to read from.\n            // If we try to read from such pipe, the read blocks and BDN hangs.\n            // We can't use async methods with cancellation tokens because Anonymous Pipes don't support async IO.\n\n            // Usually, this property is not set yet.\n            if (process.HasExited)\n                return;\n\n            var result = ProcessDataBlocking();\n            if (result != Result.Success)\n                logger.WriteLineError($\"ProcessData operation is interrupted by {result}.\");\n        }\n\n        private Result ProcessDataBlocking()\n        {\n            using StreamReader reader = new(inputFromBenchmark, AnonymousPipesHost.UTF8NoBOM, detectEncodingFromByteOrderMarks: false);\n            using StreamWriter writer = new(acknowledgments, AnonymousPipesHost.UTF8NoBOM, bufferSize: 1);\n            // Flush the data to the Stream after each write, otherwise the client will wait for input endlessly!\n            writer.AutoFlush = true;\n\n            while (true)\n            {\n                var line = reader.ReadLine();\n                if (line == null)\n                    return Result.EndOfStream;\n\n                // TODO: implement Silent mode here\n                logger.WriteLine(LogKind.Default, line);\n\n                // Handle normal log.\n                if (!line.StartsWith(\"//\"))\n                {\n                    Results.Add(line);\n                    continue;\n                }\n\n                // Keep in sync with WasmExecutor and InProcessHost.\n\n                // Handle line prefixed with \"// InProcessDiagnoser \"\n                if (line.StartsWith(CompositeInProcessDiagnoser.HeaderKey))\n                {\n                    // Something like \"// InProcessDiagnoser 0 1\"\n                    string[] lineItems = line.Split(' ');\n                    int diagnoserIndex = int.Parse(lineItems[2]);\n                    int resultsLinesCount = int.Parse(lineItems[3]);\n                    var resultsStringBuilder = new StringBuilder();\n                    for (int i = 0; i < resultsLinesCount;)\n                    {\n                        line = reader.ReadLine();\n                        if (line == null)\n                            return Result.EndOfStream;\n\n                        if (!line.StartsWith($\"{CompositeInProcessDiagnoser.ResultsKey} \"))\n                            return Result.InvalidData;\n\n                        // Strip the prepended \"// InProcessDiagnoserResults \".\n                        line = line.Substring(CompositeInProcessDiagnoser.ResultsKey.Length + 1);\n                        resultsStringBuilder.Append(line);\n                        if (++i < resultsLinesCount)\n                        {\n                            resultsStringBuilder.AppendLine();\n                        }\n                    }\n                    compositeInProcessDiagnoser.DeserializeResults(diagnoserIndex, DiagnoserActionParameters.BenchmarkCase, resultsStringBuilder.ToString());\n                    continue;\n                }\n\n                // Handle HostSignal data\n                if (Engine.Signals.TryGetSignal(line, out var signal))\n                {\n                    Diagnoser?.Handle(signal, DiagnoserActionParameters);\n\n                    writer.WriteLine(Engine.Signals.Acknowledgment);\n\n                    if (signal == HostSignal.BeforeAnythingElse)\n                    {\n                        // The client has connected, we no longer need to keep the local copy of client handle alive.\n                        // This allows server to detect that child process is done and hence avoid resource leak.\n                        // Full explanation: https://stackoverflow.com/a/39700027\n                        DisposeLocalCopyOfClientHandles();\n                    }\n                    else if (signal == HostSignal.AfterAll)\n                    {\n                        // we have received the last signal so we can stop reading from the pipe\n                        // if the process won't exit after this, its hung and needs to be killed\n                        return Result.Success;\n                    }\n\n                    continue;\n                }\n\n                // Other line that have \"//\" prefix.\n                PrefixedOutput.Add(line);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Loggers/CompositeLogger.cs",
    "content": "﻿using System.Collections.Immutable;\n\nnamespace BenchmarkDotNet.Loggers\n{\n    internal class CompositeLogger : ILogger\n    {\n        private readonly ImmutableHashSet<ILogger> loggers;\n\n        internal CompositeLogger(ImmutableHashSet<ILogger> loggers) => this.loggers = loggers;\n\n        public string Id => nameof(CompositeLogger);\n        public int Priority => 0;\n\n        public void Write(LogKind logKind, string text)\n        {\n            // BenchmarkRunner uses a single instance of CompositeLogger,\n            // it passes it as ILogger to various components, which may use it in parallel.\n            // We need to acquire the lock to avoid race conditions like #2125 and #2264\n            lock (this)\n            {\n                foreach (var logger in loggers)\n                {\n                    logger.Write(logKind, text);\n                }\n            }\n        }\n\n        public void WriteLine()\n        {\n            lock (this)\n            {\n                foreach (var logger in loggers)\n                {\n                    logger.WriteLine();\n                }\n            }\n        }\n\n        public void WriteLine(LogKind logKind, string text)\n        {\n            lock (this)\n            {\n                foreach (var logger in loggers)\n                {\n                    logger.WriteLine(logKind, text);\n                }\n            }\n        }\n\n        public void Flush()\n        {\n            lock (this)\n            {\n                foreach (var logger in loggers)\n                {\n                    logger.Flush();\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Loggers/ConsoleLogger.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing BenchmarkDotNet.Detectors;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Helpers;\nusing BenchmarkDotNet.Portability;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Loggers\n{\n    public sealed class ConsoleLogger : ILogger\n    {\n        private const ConsoleColor DefaultColor = ConsoleColor.Gray;\n\n        public static readonly ILogger Default = new ConsoleLogger();\n        public static readonly ILogger Ascii = new ConsoleLogger(false);\n        public static readonly ILogger Unicode = new ConsoleLogger(true);\n        private static readonly Lazy<bool> ConsoleSupportsColors = new(() =>\n        {\n            if (Environment.GetEnvironmentVariable(\"NO_COLOR\").IsNotBlank())\n                return false;\n\n            return !(OsDetector.IsAndroid() || OsDetector.IsIOS() || RuntimeInformation.IsWasm || OsDetector.IsTvOS());\n        });\n\n        private readonly bool unicodeSupport;\n        private readonly Dictionary<LogKind, ConsoleColor> colorScheme;\n\n        [PublicAPI]\n        public ConsoleLogger(bool unicodeSupport = false, Dictionary<LogKind, ConsoleColor>? colorScheme = null)\n        {\n            this.unicodeSupport = unicodeSupport;\n            this.colorScheme = colorScheme ?? CreateColorfulScheme();\n        }\n\n        public string Id => nameof(ConsoleLogger);\n\n        public int Priority => unicodeSupport ? 1 : 0;\n\n        public void Write(LogKind logKind, string text) => Write(logKind, Console.Write, text);\n\n        public void WriteLine() => Console.WriteLine();\n\n        public void WriteLine(LogKind logKind, string text) => Write(logKind, Console.WriteLine, text);\n\n        public void Flush() { }\n\n        private void Write(LogKind logKind, Action<string> write, string text)\n        {\n            if (!unicodeSupport)\n                text = text.ToAscii();\n\n            if (!ConsoleSupportsColors.Value)\n            {\n                write(text);\n                return;\n            }\n\n            var colorBefore = Console.ForegroundColor;\n\n            try\n            {\n                var color = GetColor(logKind);\n                if (color != Console.ForegroundColor && color != Console.BackgroundColor)\n                    Console.ForegroundColor = color;\n\n                write(text);\n            }\n            finally\n            {\n                Console.ForegroundColor = colorBefore;\n            }\n        }\n\n        private ConsoleColor GetColor(LogKind logKind) =>\n            colorScheme.ContainsKey(logKind) ? colorScheme[logKind] : DefaultColor;\n\n        private static Dictionary<LogKind, ConsoleColor> CreateColorfulScheme() =>\n            new Dictionary<LogKind, ConsoleColor>\n            {\n                { LogKind.Default, ConsoleColor.Gray },\n                { LogKind.Help, ConsoleColor.DarkGreen },\n                { LogKind.Header, ConsoleColor.Magenta },\n                { LogKind.Result, ConsoleColor.DarkCyan },\n                { LogKind.Statistic, ConsoleColor.Cyan },\n                { LogKind.Info, ConsoleColor.DarkYellow },\n                { LogKind.Error, ConsoleColor.Red },\n                { LogKind.Warning, ConsoleColor.Yellow },\n                { LogKind.Hint, ConsoleColor.DarkCyan }\n            };\n\n        [PublicAPI]\n        public static Dictionary<LogKind, ConsoleColor> CreateGrayScheme()\n        {\n            var colorScheme = new Dictionary<LogKind, ConsoleColor>();\n            foreach (var logKind in Enum.GetValues<LogKind>())\n                colorScheme[logKind] = ConsoleColor.Gray;\n            return colorScheme;\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Loggers/ILogger.cs",
    "content": "﻿namespace BenchmarkDotNet.Loggers\n{\n    public interface ILogger\n    {\n        string Id { get; }\n\n        /// <summary>\n        /// If there are several loggers with the same <see cref=\"Id\"/>,\n        /// only logger with the highest priority will be used.\n        /// </summary>\n        int Priority { get; }\n\n        void Write(LogKind logKind, string text);\n\n        void WriteLine();\n\n        void WriteLine(LogKind logKind, string text);\n\n        void Flush();\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Loggers/LinqPadLogger.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Reflection;\n\nnamespace BenchmarkDotNet.Loggers\n{\n    public sealed class LinqPadLogger : ILogger\n    {\n        private const string DefaultColor = \"\";\n\n        // The Util.WithStyle method from LINQPad\n        private readonly MethodInfo withStyle;\n\n        private readonly IReadOnlyDictionary<LogKind, string> colorScheme;\n\n        public static readonly Lazy<LinqPadLogger?> lazyInstance = new(() =>\n        {\n            // Detect if being run from LINQPad; see https://github.com/dotnet/BenchmarkDotNet/issues/445#issuecomment-300723741\n            MethodInfo? withStyle = null;\n            if (AppDomain.CurrentDomain.FriendlyName.StartsWith(\"LINQPad\", StringComparison.OrdinalIgnoreCase))\n            {\n                try\n                {\n                    // Use reflection to avoid taking a dependency on the LINQPad assembly\n                    var util = Type.GetType(\"LINQPad.Util, LINQPad, Version=1.0.0.0, Culture=neutral, PublicKeyToken=21353812cd2a2db5\", throwOnError: false) ??\n                               Type.GetType(\"LINQPad.Util, LINQPad.Runtime, Version=1.0.0.0, Culture=neutral, PublicKeyToken=21353812cd2a2db5\", throwOnError: false);\n\n                    withStyle = util?.GetMethod(\"WithStyle\", BindingFlags.Static | BindingFlags.Public);\n                }\n                catch (Exception)\n                {\n                }\n            }\n\n            if (withStyle != null)\n            {\n                var isDarkTheme = (bool)(withStyle.DeclaringType!.GetProperty(\"IsDarkThemeEnabled\", BindingFlags.Static | BindingFlags.Public)?.GetValue(null) ?? false);\n                var colorScheme = isDarkTheme ? CreateDarkScheme() : CreateLightScheme();\n                return new LinqPadLogger(withStyle, colorScheme);\n            }\n\n            return null;\n        });\n\n        public static bool IsAvailable => Instance != null;\n\n        public static ILogger? Instance => lazyInstance.Value;\n\n        private LinqPadLogger(MethodInfo withStyle, IReadOnlyDictionary<LogKind, string> colorScheme)\n        {\n            this.withStyle = withStyle;\n            this.colorScheme = colorScheme;\n        }\n\n        public string Id => nameof(LinqPadLogger);\n        public int Priority => 0;\n        public void Write(LogKind logKind, string text) => Write(logKind, Console.Write, text);\n\n        public void WriteLine() => Console.WriteLine();\n\n        public void WriteLine(LogKind logKind, string text) => Write(logKind, Console.WriteLine, text);\n\n        public void Flush() { }\n\n        private void Write(LogKind logKind, Action<object> write, string text) =>\n            write(WithStyle(text, \"color:\" + GetColor(logKind) + \";font-family:Consolas,'Lucida Console','Courier New',monospace\"));\n\n        private object WithStyle(object data, string htmlStyle) =>\n            withStyle.Invoke(null, [data, htmlStyle])!;\n\n        private string GetColor(LogKind logKind) =>\n            colorScheme.TryGetValue(logKind, out var color) ? color : DefaultColor;\n\n        // Converted from ConsoleLogger.CreateColorfulScheme using https://stackoverflow.com/a/28211539\n        private static IReadOnlyDictionary<LogKind, string> CreateDarkScheme() =>\n            new Dictionary<LogKind, string>\n            {\n                { LogKind.Default, \"#C0C0C0\" },\n                { LogKind.Help, \"#008000\" },\n                { LogKind.Header, \"#FF00FF\" },\n                { LogKind.Result, \"#008080\" },\n                { LogKind.Statistic, \"#00FFFF\" },\n                { LogKind.Info, \"#808000\" },\n                { LogKind.Error, \"#FF0000\" },\n                { LogKind.Warning, \"#FFFF00\" },\n                { LogKind.Hint, \"#008080\" }\n            };\n\n        private static IReadOnlyDictionary<LogKind, string> CreateLightScheme() =>\n            new Dictionary<LogKind, string>\n            {\n                { LogKind.Default, \"#404040\" },\n                { LogKind.Help, \"#008000\" },\n                { LogKind.Header, \"#800080\" },\n                { LogKind.Result, \"#004040\" },\n                { LogKind.Statistic, \"#008080\" },\n                { LogKind.Info, \"#808000\" },\n                { LogKind.Error, \"#FF0000\" },\n                { LogKind.Warning, \"#FFFF00\" },\n                { LogKind.Hint, \"#008080\" }\n            };\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Loggers/LogCapture.cs",
    "content": "﻿using System.Collections.Generic;\n\nnamespace BenchmarkDotNet.Loggers\n{\n    public class LogCapture : ILogger\n    {\n        public IReadOnlyList<OutputLine> CapturedOutput => capturedOutput;\n\n        private readonly List<OutputLine> capturedOutput = new List<OutputLine>(100);\n\n        public string Id => nameof(LogCapture);\n        public int Priority => 0;\n\n        public void Write(LogKind logKind, string text)\n        {\n            capturedOutput.Add(new OutputLine\n            {\n                Kind = logKind,\n                Text = text\n            });\n        }\n\n        public void WriteLine()\n        {\n            capturedOutput.Add(new OutputLine\n            {\n                Kind = LogKind.Default,\n                Text = System.Environment.NewLine\n            });\n        }\n\n        public void WriteLine(LogKind logKind, string text)\n        {\n            Write(logKind, text);\n            WriteLine();\n        }\n\n        public void Flush() { }\n\n        public void Clear() => capturedOutput.Clear();\n    }\n\n    public struct OutputLine\n    {\n        public LogKind Kind { get; set; }\n        public string Text { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Loggers/LogKind.cs",
    "content": "﻿namespace BenchmarkDotNet.Loggers\n{\n    public enum LogKind\n    {\n        Default, Help, Header, Result, Statistic, Info, Error, Hint, Warning\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Loggers/LoggerExtensions.cs",
    "content": "﻿using JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Loggers\n{\n    public static class LoggerExtensions\n    {\n        public static void WriteLine(this ILogger logger, string text) => logger.WriteLine(LogKind.Default, text);\n\n        public static void WriteLineHelp(this ILogger logger, string text) => logger.WriteLine(LogKind.Help, text);\n\n        public static void WriteLineHeader(this ILogger logger, string text) => logger.WriteLine(LogKind.Header, text);\n\n        public static void WriteLineResult(this ILogger logger, string text) => logger.WriteLine(LogKind.Result, text);\n\n        public static void WriteLineStatistic(this ILogger logger, string text) => logger.WriteLine(LogKind.Statistic, text);\n\n        public static void WriteLineInfo(this ILogger logger, string text) => logger.WriteLine(LogKind.Info, text);\n\n        public static void WriteLineError(this ILogger logger, string text) => logger.WriteLine(LogKind.Error, text);\n\n        public static void WriteLineWarning(this ILogger logger, string text) => logger.WriteLine(LogKind.Warning, text);\n\n        public static void WriteLineHint(this ILogger logger, string text) => logger.WriteLine(LogKind.Hint, text);\n\n        public static void Write(this ILogger logger, string text) => logger.Write(LogKind.Default, text);\n\n        [PublicAPI]\n        public static void WriteHelp(this ILogger logger, string text) => logger.Write(LogKind.Help, text);\n\n        public static void WriteHeader(this ILogger logger, string text) => logger.Write(LogKind.Header, text);\n\n        [PublicAPI]\n        public static void WriteResult(this ILogger logger, string text) => logger.Write(LogKind.Result, text);\n\n        public static void WriteStatistic(this ILogger logger, string text) => logger.Write(LogKind.Statistic, text);\n\n        public static void WriteInfo(this ILogger logger, string text) => logger.Write(LogKind.Info, text);\n\n        public static void WriteError(this ILogger logger, string text) => logger.Write(LogKind.Error, text);\n\n        public static void WriteWarning(this ILogger logger, string text) => logger.Write(LogKind.Warning, text);\n\n        [PublicAPI]\n        public static void WriteHint(this ILogger logger, string text) => logger.Write(LogKind.Hint, text);\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Loggers/LoggerWithPrefix.cs",
    "content": "﻿using System;\n\nnamespace BenchmarkDotNet.Loggers\n{\n    /// <summary>\n    /// Adds prefix for each line\n    /// </summary>\n    public class LoggerWithPrefix : ILogger\n    {\n        private ILogger Logger { get; }\n        private string Prefix { get; }\n        private bool isNewLine = true;\n\n        public LoggerWithPrefix(ILogger logger, string prefix)\n        {\n            Logger = logger;\n            Prefix = prefix;\n            Id = nameof(LoggerWithPrefix) + \".\" + Logger.Id + \".\" + Prefix;\n        }\n\n        public string Id { get; }\n        public int Priority => Logger.Priority;\n\n        public void Write(LogKind logKind, string text)\n        {\n            var lines = text.Split([Environment.NewLine], StringSplitOptions.None);\n            WriteSimple(logKind, lines[0]);\n\n            for (int i = 1; i < lines.Length; i++)\n            {\n                WriteLine();\n                WriteSimple(logKind, lines[i]);\n            }\n        }\n\n        private void WriteSimple(LogKind logKind, string text)\n        {\n            AddPrefixIfNeeded(logKind, text);\n            Logger.Write(text);\n        }\n\n        private void AddPrefixIfNeeded(LogKind logKind, string text)\n        {\n            if (isNewLine && !string.IsNullOrEmpty(text))\n            {\n                Logger.Write(logKind, Prefix);\n                isNewLine = false;\n            }\n        }\n\n        public void WriteLine(LogKind logKind, string text)\n        {\n            Write(logKind, text);\n            WriteLine();\n        }\n\n        public void WriteLine()\n        {\n            Logger.WriteLine();\n\n            isNewLine = true;\n        }\n\n        public void Flush() { }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Loggers/NullLogger.cs",
    "content": "﻿namespace BenchmarkDotNet.Loggers\n{\n    public class NullLogger : ILogger\n    {\n        public static readonly ILogger Instance = new NullLogger();\n\n        private NullLogger() { }\n\n        public string Id => nameof(NullLogger);\n        public int Priority => 0;\n        public void Write(LogKind logKind, string text) { }\n\n        public void WriteLine() { }\n\n        public void WriteLine(LogKind logKind, string text) { }\n\n        public void Flush() { }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Loggers/StreamLogger.cs",
    "content": "﻿using System.IO;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Loggers\n{\n    public class StreamLogger : TextLogger\n    {\n        public StreamLogger(StreamWriter writer) : base(writer) { }\n\n        [PublicAPI]\n        public StreamLogger(string filePath, bool append = false)\n            : this(new StreamWriter(filePath, append))\n        { }\n\n        public override string Id => nameof(StreamLogger);\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Loggers/TextLogger.cs",
    "content": "﻿using System;\nusing System.IO;\n\nnamespace BenchmarkDotNet.Loggers\n{\n    public class TextLogger : ILogger, IDisposable\n    {\n        private readonly TextWriter writer;\n\n        public TextLogger(TextWriter writer) => this.writer = writer;\n\n        public virtual string Id => nameof(TextLogger);\n        public int Priority => 0;\n\n        public void Write(LogKind logKind, string text) => writer.Write(text);\n\n        public void WriteLine() => writer.WriteLine();\n\n        public void WriteLine(LogKind logKind, string text) => writer.WriteLine(text);\n\n        public void Flush() => writer.Flush();\n\n        public void Dispose() => writer.Dispose();\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Mathematics/LegacyConfidenceInterval.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Globalization;\nusing System.Linq;\nusing System.Text;\nusing BenchmarkDotNet.Helpers;\nusing JetBrains.Annotations;\nusing Perfolizer.Mathematics.Common;\n\nnamespace BenchmarkDotNet.Mathematics;\n\npublic enum LegacyConfidenceLevel\n{\n    /// <summary>\n    /// 50.0% confidence interval\n    /// </summary>\n    [PublicAPI] L50,\n\n    /// <summary>\n    /// 70.0% confidence interval\n    /// </summary>\n    [PublicAPI] L70,\n\n    /// <summary>\n    /// 75.0% confidence interval\n    /// </summary>\n    [PublicAPI] L75,\n\n    /// <summary>\n    /// 80.0% confidence interval\n    /// </summary>\n    [PublicAPI] L80,\n\n    /// <summary>\n    /// 85.0% confidence interval\n    /// </summary>\n    [PublicAPI] L85,\n\n    /// <summary>\n    /// 90.0% confidence interval\n    /// </summary>\n    [PublicAPI] L90,\n\n    /// <summary>\n    /// 92.0% confidence interval\n    /// </summary>\n    [PublicAPI] L92,\n\n    /// <summary>\n    /// 95.0% confidence interval\n    /// </summary>\n    [PublicAPI] L95,\n\n    /// <summary>\n    /// 96.0% confidence interval\n    /// </summary>\n    [PublicAPI] L96,\n\n    /// <summary>\n    /// 97.0% confidence interval\n    /// </summary>\n    [PublicAPI] L97,\n\n    /// <summary>\n    /// 98.0% confidence interval\n    /// </summary>\n    [PublicAPI] L98,\n\n    /// <summary>\n    /// 99.0% confidence interval\n    /// </summary>\n    [PublicAPI] L99,\n\n    /// <summary>\n    /// 99.9% confidence interval\n    /// </summary>\n    [PublicAPI] L999\n}\n\npublic static class ConfidenceLevelExtensions\n{\n    private static readonly Dictionary<LegacyConfidenceLevel, (int value, int digits)> ConfidenceLevelDetails = CreateConfidenceLevelMapping();\n\n    /// <summary>\n    /// Calculates Z value (z-star) for confidence interval\n    /// </summary>\n    /// <param name=\"level\">ConfidenceLevel for a confidence interval</param>\n    /// <param name=\"n\">Sample size (n >= 3)</param>\n    public static double GetZValue(this LegacyConfidenceLevel level, int n)\n    {\n        return new ConfidenceIntervalEstimator(n, 0, 1).ZLevel(new ConfidenceLevel(level.ToPercent()));\n    }\n\n    public static string ToPercentStr(this LegacyConfidenceLevel level)\n    {\n        string s = level.ToString().Substring(1);\n        if (s.Length > 2)\n            s = s.Substring(0, 2) + \".\" + s.Substring(2);\n        return s + \"%\";\n    }\n\n    [PublicAPI] public static double ToPercent(this LegacyConfidenceLevel level)\n    {\n        (int value, int digits) = ConfidenceLevelDetails[level];\n\n        return value / Math.Pow(10, digits);\n    }\n\n    private static Dictionary<LegacyConfidenceLevel, (int value, int length)> CreateConfidenceLevelMapping()\n        => Enum.GetValues<LegacyConfidenceLevel>()\n            .ToDictionary(\n                confidenceLevel => confidenceLevel,\n                confidenceLevel =>\n                {\n                    string textRepresentation = confidenceLevel.ToString().Substring(1);\n\n                    return (int.Parse(textRepresentation), textRepresentation.Length);\n                });\n}\n\npublic struct LegacyConfidenceInterval\n{\n    [PublicAPI] public int N { get; }\n    [PublicAPI] public double Mean { get; }\n    [PublicAPI] public double StandardError { get; }\n\n    [PublicAPI] public LegacyConfidenceLevel Level { get; }\n    [PublicAPI] public double Margin { get; }\n\n    [PublicAPI] public double Lower { get; }\n    [PublicAPI] public double Upper { get; }\n\n    public LegacyConfidenceInterval(double mean, double standardError, int n, LegacyConfidenceLevel level = LegacyConfidenceLevel.L999)\n    {\n        N = n;\n        Mean = mean;\n        StandardError = standardError;\n        Level = level;\n        Margin = n <= 2 ? double.NaN : standardError * level.GetZValue(n);\n        Lower = mean - Margin;\n        Upper = mean + Margin;\n    }\n\n    public bool Contains(double value) => Lower - 1e-9 < value && value < Upper + 1e-9;\n\n    private string GetLevelHint(bool showLevel = true) => showLevel ? $\" (CI {Level.ToPercentStr()})\" : \"\";\n\n    public override string ToString() => ToString(DefaultCultureInfo.Instance);\n\n    public string ToString(CultureInfo cultureInfo, string format = \"0.##\", bool showLevel = true)\n    {\n        return ToString(x => x.ToString(format, cultureInfo), showLevel);\n    }\n\n    public string ToString(Func<double, string> formatter, bool showLevel = true)\n    {\n        var builder = new StringBuilder();\n        builder.Append('[');\n        builder.Append(formatter(Lower));\n        builder.Append(\"; \");\n        builder.Append(formatter(Upper));\n        builder.Append(\"]\");\n        builder.Append(GetLevelHint(showLevel));\n        return builder.ToString();\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Mathematics/MathHelper.cs",
    "content": "﻿using Perfolizer.Mathematics.Common;\nusing Perfolizer.Metrology;\nusing static System.Math;\n\nnamespace BenchmarkDotNet.Mathematics\n{\n    internal static class MathHelper\n    {\n        public static readonly Threshold DefaultThreshold = PercentValue.Of(2).ToThreshold();\n        public static readonly SignificanceLevel DefaultSignificanceLevel = SignificanceLevel.P1E5;\n        public static int Clamp(int value, int min, int max) => Min(Max(value, min), max);\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Mathematics/MeasurementsStatistics.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing BenchmarkDotNet.Reports;\nusing JetBrains.Annotations;\nusing Perfolizer.Mathematics.Common;\nusing Perfolizer.Mathematics.OutlierDetection;\n\nnamespace BenchmarkDotNet.Mathematics\n{\n    /// <summary>\n    /// the goal of this struct is to avoid any heap allocations, please keep it in mind\n    /// </summary>\n    internal readonly ref struct MeasurementsStatistics\n    {\n        /// <summary>\n        /// Standard error in nanoseconds.\n        /// </summary>\n        [PublicAPI]\n        public double StandardError { get; }\n\n        /// <summary>\n        /// Mean in nanoseconds.\n        /// </summary>\n        public double Mean { get; }\n\n        /// <summary>\n        /// 99.9% confidence interval in nanoseconds.\n        /// </summary>\n        public ConfidenceInterval LegacyConfidenceInterval { get; }\n\n        private MeasurementsStatistics(double standardError, double mean, ConfidenceInterval legacyConfidenceInterval)\n        {\n            StandardError = standardError;\n            Mean = mean;\n            LegacyConfidenceInterval = legacyConfidenceInterval;\n        }\n\n        public static MeasurementsStatistics Calculate(List<Measurement> measurements, OutlierMode outlierMode)\n        {\n            int n = measurements.Count;\n            if (n == 0)\n                throw new InvalidOperationException(\"StatSummary: Sequence contains no elements\");\n\n            double sum = Sum(measurements);\n            double mean = sum / n;\n\n            double variance = Variance(measurements, n, mean);\n            double standardDeviation = Math.Sqrt(variance);\n            double standardError = standardDeviation / Math.Sqrt(n);\n            var confidenceIntervalEstimator = new ConfidenceIntervalEstimator(n, mean, standardError);\n            var confidenceInterval = confidenceIntervalEstimator.ConfidenceInterval(ConfidenceLevel.L999);\n\n            if (outlierMode == OutlierMode.DontRemove) // most simple scenario is done without allocations! but this is not the default case\n                return new MeasurementsStatistics(standardError, mean, confidenceInterval);\n\n            measurements.Sort(); // sort in place\n\n            double q1, q3;\n\n            if (n == 1)\n                q1 = q3 = measurements[0].Nanoseconds;\n            else\n            {\n                q1 = GetQuartile(measurements, measurements.Count / 2);\n                q3 = GetQuartile(measurements, measurements.Count * 3 / 2);\n            }\n\n            double interquartileRange = q3 - q1;\n            double lowerFence = q1 - 1.5 * interquartileRange;\n            double upperFence = q3 + 1.5 * interquartileRange;\n\n            SumWithoutOutliers(outlierMode, measurements, lowerFence, upperFence, out sum, out n); // updates sum and N\n            mean = sum / n;\n\n            variance = VarianceWithoutOutliers(outlierMode, measurements, n, mean, lowerFence, upperFence);\n            standardDeviation = Math.Sqrt(variance);\n            standardError = standardDeviation / Math.Sqrt(n);\n            confidenceIntervalEstimator = new ConfidenceIntervalEstimator(n, mean, standardError);\n            confidenceInterval = confidenceIntervalEstimator.ConfidenceInterval(ConfidenceLevel.L999);\n\n            return new MeasurementsStatistics(standardError, mean, confidenceInterval);\n        }\n\n        private static double Sum(List<Measurement> measurements)\n        {\n            double sum = 0;\n            foreach (var m in measurements)\n                sum += m.Nanoseconds;\n            return sum;\n        }\n\n        private static void SumWithoutOutliers(OutlierMode outlierMode, List<Measurement> measurements,\n            double lowerFence, double upperFence, out double sum, out int n)\n        {\n            sum = 0;\n            n = 0;\n\n            foreach (var m in measurements)\n                if (!IsOutlier(outlierMode, m.Nanoseconds, lowerFence, upperFence))\n                {\n                    sum += m.Nanoseconds;\n                    ++n;\n                }\n        }\n\n        private static double Variance(List<Measurement> measurements, int n, double mean)\n        {\n            if (n == 1)\n                return 0;\n\n            double variance = 0;\n            foreach (var m in measurements)\n                variance += (m.Nanoseconds - mean) * (m.Nanoseconds - mean) / (n - 1);\n\n            return variance;\n        }\n\n        private static double VarianceWithoutOutliers(OutlierMode outlierMode, List<Measurement> measurements, int n, double mean, double lowerFence,\n            double upperFence)\n        {\n            if (n == 1)\n                return 0;\n\n            double variance = 0;\n            foreach (var m in measurements)\n                if (!IsOutlier(outlierMode, m.Nanoseconds, lowerFence, upperFence))\n                    variance += (m.Nanoseconds - mean) * (m.Nanoseconds - mean) / (n - 1);\n\n            return variance;\n        }\n\n        private static double GetQuartile(List<Measurement> measurements, int count)\n        {\n            if (count % 2 == 0)\n                return (measurements[count / 2 - 1].Nanoseconds + measurements[count / 2].Nanoseconds) / 2;\n\n            return measurements[count / 2].Nanoseconds;\n        }\n\n        private static bool IsOutlier(OutlierMode outlierMode, double value, double lowerFence, double upperFence)\n        {\n            switch (outlierMode)\n            {\n                case OutlierMode.DontRemove:\n                    return false;\n                case OutlierMode.RemoveUpper:\n                    return value > upperFence;\n                case OutlierMode.RemoveLower:\n                    return value < lowerFence;\n                case OutlierMode.RemoveAll:\n                    return value < lowerFence || value > upperFence;\n                default:\n                    throw new ArgumentOutOfRangeException(nameof(outlierMode), outlierMode, null);\n            }\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Mathematics/NumeralSystem.cs",
    "content": "﻿namespace BenchmarkDotNet.Mathematics\n{\n    public enum NumeralSystem\n    {\n        /// <summary>\n        /// Arabic numerals (1, 2, 3, 4, ...)\n        /// </summary>\n        Arabic,\n\n        /// <summary>\n        /// Roman numerals (I, II, III, IV, ...)\n        /// </summary>\n        Roman,\n\n        /// <summary>\n        /// Unary numeral system (*, **, ***, ****, ...)\n        /// </summary>\n        Stars\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Mathematics/NumeralSystemExtensions.cs",
    "content": "﻿using System;\n\nnamespace BenchmarkDotNet.Mathematics\n{\n    public static class NumeralSystemExtensions\n    {\n        public static string ToPresentation(this NumeralSystem system, int value)\n        {\n            switch (system)\n            {\n                case NumeralSystem.Arabic:\n                    return value.ToString();\n                case NumeralSystem.Roman:\n                    return ToRoman(value);\n                case NumeralSystem.Stars:\n                    return new string('*', value);\n                default:\n                    throw new ArgumentOutOfRangeException(nameof(system));\n            }\n        }\n\n        // Based on http://stackoverflow.com/questions/7040289/converting-integers-to-roman-numerals\n        private static string ToRoman(int number)\n        {\n            if (number < 0 || number > 3999) throw new ArgumentOutOfRangeException(nameof(number), \"insert value between 1 and 3999\");\n            if (number < 1) return string.Empty;\n            if (number >= 1000) return \"M\" + ToRoman(number - 1000);\n            if (number >= 900) return \"CM\" + ToRoman(number - 900);\n            if (number >= 500) return \"D\" + ToRoman(number - 500);\n            if (number >= 400) return \"CD\" + ToRoman(number - 400);\n            if (number >= 100) return \"C\" + ToRoman(number - 100);\n            if (number >= 90) return \"XC\" + ToRoman(number - 90);\n            if (number >= 50) return \"L\" + ToRoman(number - 50);\n            if (number >= 40) return \"XL\" + ToRoman(number - 40);\n            if (number >= 10) return \"X\" + ToRoman(number - 10);\n            if (number >= 9) return \"IX\" + ToRoman(number - 9);\n            if (number >= 5) return \"V\" + ToRoman(number - 5);\n            if (number >= 4) return \"IV\" + ToRoman(number - 4);\n            if (number >= 1) return \"I\" + ToRoman(number - 1);\n            throw new ArgumentOutOfRangeException(nameof(number), \"something bad happened\");\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Mathematics/PercentileValues.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Globalization;\nusing System.Text;\nusing BenchmarkDotNet.Helpers;\nusing JetBrains.Annotations;\nusing Perfolizer;\nusing Perfolizer.Mathematics.QuantileEstimators;\nusing Pragmastat;\n\nnamespace BenchmarkDotNet.Mathematics\n{\n    public class PercentileValues\n    {\n        [PublicAPI] public double Percentile(int percentile) => SimpleQuantileEstimator.Instance.Quantile(new Sample(SortedValues), percentile / 100.0);\n\n        private IReadOnlyList<double> SortedValues { get; }\n\n        public double P0 { get; }\n        public double P25 { get; }\n        public double P50 { get; }\n        public double P67 { get; }\n        public double P80 { get; }\n        public double P85 { get; }\n        public double P90 { get; }\n        public double P95 { get; }\n        public double P100 { get; }\n\n        internal PercentileValues(IReadOnlyList<double> sortedValues)\n        {\n            SortedValues = sortedValues;\n\n            // TODO: Collect all in one call?\n            P0 = Percentile(0);\n            P25 = Percentile(25);\n            P50 = Percentile(50);\n            P67 = Percentile(67);\n            P80 = Percentile(80);\n            P85 = Percentile(85);\n            P90 = Percentile(90);\n            P95 = Percentile(95);\n            P100 = Percentile(100);\n        }\n\n        public override string ToString() => ToString(DefaultCultureInfo.Instance);\n\n        public string ToString(Func<double, string> formatter)\n        {\n            var builder = new StringBuilder();\n            builder.Append(\"[P95: \");\n            builder.Append(formatter(P95));\n            builder.Append(\"]; [P0: \");\n            builder.Append(formatter(P0));\n            builder.Append(\"]; [P50: \");\n            builder.Append(formatter(P50));\n            builder.Append(\"]; [P100: \");\n            builder.Append(formatter(P100));\n            builder.Append(\"]\");\n            return builder.ToString();\n        }\n\n        public string ToString(CultureInfo? cultureInfo, string format = \"0.##\")\n        {\n            return ToString(x => x.ToString(format, cultureInfo));\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Mathematics/RankHelper.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing Perfolizer.Mathematics.Common;\nusing Perfolizer.Mathematics.SignificanceTesting;\nusing Perfolizer.Mathematics.SignificanceTesting.MannWhitney;\n\nnamespace BenchmarkDotNet.Mathematics\n{\n    internal static class RankHelper\n    {\n        public static int[] GetRanks(params Statistics[] stats)\n        {\n            var values = stats.Select((s, index) => new { Stats = s, Index = index }).OrderBy(pair => pair.Stats.Mean).ToArray();\n\n            int n = values.Length;\n            var ranks = new int[n];\n            if (n > 0)\n            {\n                int currentRank = 1;\n                ranks[values[0].Index] = currentRank;\n                for (int i = 1; i < n; i++)\n                {\n                    if (AreSame(values[i - 1].Stats, values[i].Stats))\n                        ranks[values[i].Index] = currentRank;\n                    else\n                        ranks[values[i].Index] = ++currentRank;\n                }\n            }\n            return ranks;\n        }\n\n        private static bool AreSame(Statistics x, Statistics y)\n        {\n            var test = new SimpleEquivalenceTest(MannWhitneyTest.Instance);\n            var comparisonResult = test.Perform(x.Sample, y.Sample, MathHelper.DefaultThreshold, MathHelper.DefaultSignificanceLevel);\n            return comparisonResult == ComparisonResult.Indistinguishable;\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Mathematics/RatioStatistics.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Text;\n\nnamespace BenchmarkDotNet.Mathematics\n{\n    /// <summary>\n    /// Statistics for *relation* of two data sets\n    /// </summary>\n    public class RatioStatistics\n    {\n        public double Mean { get; }\n        public double StandardDeviation { get; }\n\n        public RatioStatistics(Statistics x, Statistics y)\n        {\n            if (x.N < 1)\n                throw new ArgumentOutOfRangeException(nameof(x), \"Argument doesn't contain any values\");\n            if (y.N < 1)\n                throw new ArgumentOutOfRangeException(nameof(y), \"Argument doesn't contain any values\");\n\n            if (x == y)\n            {\n                Mean = 1.0;\n                StandardDeviation = 0.0;\n            }\n            else\n            {\n                var divided = Divide(x, y);\n                Mean = divided.Mean;\n                StandardDeviation = divided.StandardDeviation;\n            }\n        }\n\n        private static Statistics Divide(Statistics x, Statistics y)\n        {\n            double[]? z = new double[x.N * y.N];\n            int k = 0;\n            for (int i = 0; i < x.N; i++)\n                for (int j = 0; j < y.N; j++)\n                {\n                    if (Math.Abs(y.Sample.Values[j]) < 1e-9)\n                        throw new DivideByZeroException($\"y[{j}] is {y.Sample.Values[j]}\");\n                    z[k++] = x.Sample.Values[i] / y.Sample.Values[j];\n                }\n\n            return new Statistics(z);\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Mathematics/Statistics.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing BenchmarkDotNet.Extensions;\nusing JetBrains.Annotations;\nusing Perfolizer;\nusing Perfolizer.Horology;\nusing Perfolizer.Mathematics.Common;\nusing Perfolizer.Mathematics.OutlierDetection;\nusing Perfolizer.Mathematics.QuantileEstimators;\nusing Pragmastat;\n\nnamespace BenchmarkDotNet.Mathematics\n{\n    public class Statistics\n    {\n        internal Sample Sample { get; }\n        public IReadOnlyList<double> OriginalValues { get; }\n        public int N { get; }\n        public double Min { get; }\n        public double LowerFence { get; }\n        public double Q1 { get; }\n        public double Median { get; }\n        public double Mean { get; }\n        public double Q3 { get; }\n        public double UpperFence { get; }\n        public double Max { get; }\n        public double InterquartileRange { get; }\n        public double[] LowerOutliers { get; }\n        public double[] UpperOutliers { get; }\n        public double[] AllOutliers { get; }\n        public double StandardError { get; }\n        public double Variance { get; }\n        public double StandardDeviation { get; }\n        public double Skewness { get; }\n        public double Kurtosis { get; }\n        private ConfidenceIntervalEstimator ConfidenceIntervalEstimator { get; }\n        internal ConfidenceInterval PerfolizerConfidenceInterval { get; }\n        public LegacyConfidenceInterval ConfidenceInterval { get; }\n        public PercentileValues Percentiles { get; }\n\n        private readonly TukeyOutlierDetector outlierDetector;\n\n        public Statistics(params double[] values) :\n            this(values.ToList()) { }\n\n        public Statistics(IEnumerable<int> values) :\n            this(values.Select(value => (double)value)) { }\n\n        public Statistics(IEnumerable<double> values) : this(new Sample(values.ToArray(), TimeUnit.Nanosecond)) { }\n\n        public Statistics(Sample sample)\n        {\n            Sample = sample;\n            OriginalValues = sample.Values;\n            N = Sample.Size;\n\n            var quartiles = Quartiles.Create(Sample);\n            Min = quartiles.Min;\n            Q1 = quartiles.Q1;\n            Median = quartiles.Median;\n            Q3 = quartiles.Q3;\n            Max = quartiles.Max;\n            InterquartileRange = quartiles.InterquartileRange;\n\n            var moments = Moments.Create(Sample);\n            Mean = moments.Mean;\n            StandardDeviation = moments.StandardDeviation;\n            Variance = moments.Variance;\n            Skewness = moments.Skewness;\n            Kurtosis = moments.Kurtosis;\n\n            var tukey = TukeyOutlierDetector.Create(Sample);\n            LowerFence = tukey.LowerFence;\n            UpperFence = tukey.UpperFence;\n            AllOutliers = Sample.SortedValues.Where(tukey.IsOutlier).ToArray();\n            LowerOutliers = Sample.SortedValues.Where(tukey.IsLowerOutlier).ToArray();\n            UpperOutliers = Sample.SortedValues.Where(tukey.IsUpperOutlier).ToArray();\n            outlierDetector = tukey;\n\n            StandardError = StandardDeviation / Math.Sqrt(N);\n            ConfidenceIntervalEstimator = new ConfidenceIntervalEstimator(Sample.Size, Mean, StandardError);\n            PerfolizerConfidenceInterval = ConfidenceIntervalEstimator.ConfidenceInterval(ConfidenceLevel.L999);\n            ConfidenceInterval = new LegacyConfidenceInterval(PerfolizerConfidenceInterval.Estimation, StandardError, N, LegacyConfidenceLevel.L999);\n            Percentiles = new PercentileValues(Sample.SortedValues);\n        }\n\n        [PublicAPI] public ConfidenceInterval GetConfidenceInterval(ConfidenceLevel level) => ConfidenceIntervalEstimator.ConfidenceInterval(level);\n        [PublicAPI] public bool IsLowerOutlier(double value) => outlierDetector.IsLowerOutlier(value);\n        [PublicAPI] public bool IsUpperOutlier(double value) => outlierDetector.IsUpperOutlier(value);\n        [PublicAPI] public bool IsOutlier(double value) => outlierDetector.IsOutlier(value);\n        [PublicAPI] public double[] WithoutOutliers() => outlierDetector.WithoutAllOutliers(Sample.Values).ToArray();\n\n        [PublicAPI] public double CalcCentralMoment(int k) => Sample.SortedValues.Average(x => (x - Mean).Pow(k));\n\n        public bool IsActualOutlier(double value, OutlierMode outlierMode)\n        {\n            switch (outlierMode)\n            {\n                case OutlierMode.DontRemove:\n                    return false;\n                case OutlierMode.RemoveUpper:\n                    return IsUpperOutlier(value);\n                case OutlierMode.RemoveLower:\n                    return IsLowerOutlier(value);\n                case OutlierMode.RemoveAll:\n                    return IsOutlier(value);\n                default:\n                    throw new ArgumentOutOfRangeException(nameof(outlierMode), outlierMode, null);\n            }\n        }\n\n        [PublicAPI]\n        public double[] GetActualOutliers(OutlierMode outlierMode)\n        {\n            switch (outlierMode)\n            {\n                case OutlierMode.DontRemove:\n                    return [];\n                case OutlierMode.RemoveUpper:\n                    return UpperOutliers;\n                case OutlierMode.RemoveLower:\n                    return LowerOutliers;\n                case OutlierMode.RemoveAll:\n                    return AllOutliers;\n                default:\n                    throw new ArgumentOutOfRangeException(nameof(outlierMode), outlierMode, null);\n            }\n        }\n\n        public override string ToString() => Sample.ToString();\n\n        /// <summary>\n        /// Returns true, if this statistics can be inverted (see <see cref=\"Invert\"/>).\n        /// </summary>\n        public bool CanBeInverted() => Min > 1e-9;\n\n        /// <summary>\n        /// Statistics for [1/X]. If Min is less then or equal to 0, returns null.\n        /// </summary>\n        public Statistics? Invert() => CanBeInverted() ? new Statistics(Sample.SortedValues.Select(x => 1 / x)) : null;\n\n        /// <summary>\n        /// Mean for [X*Y].\n        /// </summary>\n        public static double MulMean(Statistics x, Statistics y) => x.Mean * y.Mean;\n\n        /// <summary>\n        /// Mean for [X/Y].\n        /// </summary>\n        public static double DivMean(Statistics? x, Statistics? y)\n        {\n            if (x == null || y == null)\n                return double.NaN;\n            var yInvert = y.Invert();\n            if (yInvert == null)\n                throw new DivideByZeroException();\n            return MulMean(x, yInvert);\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Models/BdnBenchmark.cs",
    "content": "using System.Text;\nusing BenchmarkDotNet.Extensions;\nusing Perfolizer.Models;\n\nnamespace BenchmarkDotNet.Models;\n\ninternal class BdnBenchmark : BenchmarkInfo\n{\n    public string Namespace { get; set; } = \"\";\n    public string Type { get; set; } = \"\";\n    public string Method { get; set; } = \"\";\n    public string Parameters { get; set; } = \"\";\n    public string? HardwareIntrinsics { get; set; } = \"\";\n\n    // TODO: Improve\n    public override string? GetDisplay()\n    {\n        if (Display != null) return Display;\n\n        var builder = new StringBuilder();\n        builder.Append($\"{Namespace}\");\n        if (Type.IsNotBlank())\n        {\n            if (builder.Length > 0)\n                builder.Append('.');\n            builder.Append(Type);\n        }\n        if (Method.IsNotBlank())\n        {\n            if (builder.Length > 0)\n                builder.Append('.');\n            builder.Append(Method);\n        }\n        return builder.ToString();\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Models/BdnEnvironment.cs",
    "content": "using BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Jobs;\nusing Perfolizer.Models;\n\nnamespace BenchmarkDotNet.Models;\n\ninternal class BdnEnvironment : EnvironmentInfo\n{\n    public RuntimeMoniker? Runtime { get; set; }\n    public Jit? Jit { get; set; }\n    public int? Affinity { get; set; }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Models/BdnExecution.cs",
    "content": "using BenchmarkDotNet.Analysers;\nusing BenchmarkDotNet.Engines;\nusing Perfolizer.Models;\n\nnamespace BenchmarkDotNet.Models;\n\ninternal class BdnExecution : ExecutionInfo\n{\n    /// <summary>\n    /// Available values: Throughput and ColdStart.\n    ///     Throughput: default strategy which allows to get good precision level.\n    ///     ColdStart: should be used only for measuring cold start of the application or testing purpose.\n    ///     Monitoring: no overhead evaluating, with several target iterations. Perfect for macrobenchmarks without a steady state with high variance.\n    /// </summary>\n    public RunStrategy? RunStrategy { get; set; }\n\n    /// <summary>\n    /// How many times we should launch process with target benchmark.\n    /// </summary>\n    public int? LaunchCount { get; set; }\n\n    /// <summary>\n    /// How many warmup iterations should be performed.\n    /// </summary>\n    public int? WarmupCount { get; set; }\n\n    /// <summary>\n    /// How many target iterations should be performed\n    /// If specified, <see cref=\"MinIterationCount\"/> will be ignored.\n    /// If specified, <see cref=\"MaxIterationCount\"/> will be ignored.\n    /// </summary>\n    public int? IterationCount { get; set; }\n\n    /// <summary>\n    /// Desired time of execution of an iteration. Used by Pilot stage to estimate the number of invocations per iteration.\n    /// The default value is 500 milliseconds.\n    /// </summary>\n    public long? IterationTimeMs { get; set; }\n\n    /// <summary>\n    /// Invocation count in a single iteration.\n    /// If specified, <see cref=\"IterationTimeMs\"/> will be ignored.\n    /// If specified, it must be a multiple of <see cref=\"UnrollFactor\"/>.\n    /// </summary>\n    public long? InvocationCount { get; set; }\n\n    /// <summary>\n    /// How many times the benchmark method will be invoked per one iteration of a generated loop.\n    /// </summary>\n    public int? UnrollFactor { get; set; }\n\n    /// <summary>\n    /// Minimum count of target iterations that should be performed\n    /// The default value is 15\n    /// <remarks>If you set this value to below 15, then <see cref=\"MultimodalDistributionAnalyzer\"/> is not going to work</remarks>\n    /// </summary>\n    public int? MinIterationCount { get; set; }\n\n    /// <summary>\n    /// Maximum count of target iterations that should be performed\n    /// The default value is 100\n    /// <remarks>If you set this value to below 15, then <see cref=\"MultimodalDistributionAnalyzer\"/>  is not going to work</remarks>\n    /// </summary>\n    public int? MaxIterationCount { get; set; }\n\n    /// <summary>\n    /// Minimum count of warmup iterations that should be performed\n    /// The default value is 6\n    /// </summary>\n    public int? MinWarmupIterationCount { get; set; }\n\n    /// <summary>\n    /// Maximum count of warmup iterations that should be performed\n    /// The default value is 50\n    /// </summary>\n    public int? MaxWarmupIterationCount { get; set; }\n\n    /// <summary>\n    /// specifies whether Engine should allocate some random-sized memory between iterations\n    /// <remarks>it makes [GlobalCleanup] and [GlobalSetup] methods to be executed after every iteration</remarks>\n    /// </summary>\n    public bool? MemoryRandomization { get; set; }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Models/BdnHostInfo.cs",
    "content": "using Perfolizer.Models;\n\nnamespace BenchmarkDotNet.Models;\n\ninternal class BdnHostInfo : HostInfo\n{\n    public string RuntimeVersion { get; set; } = \"\";\n    public bool HasAttachedDebugger { get; set; }\n    public bool HasRyuJit { get; set; }\n    public string Configuration { get; set; } = \"\";\n    public string DotNetSdkVersion { get; set; } = \"\";\n    public double ChronometerFrequency { get; set; }\n    public string HardwareTimerKind { get; set; } = \"\";\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Models/BdnLifecycle.cs",
    "content": "using System;\nusing BenchmarkDotNet.Engines;\nusing JetBrains.Annotations;\nusing Perfolizer.Models;\n\nnamespace BenchmarkDotNet.Models;\n\ninternal class BdnLifecycle : LifecycleInfo, IEquatable<BdnLifecycle>, IComparable<BdnLifecycle>\n{\n    public int LaunchIndex { get; set; }\n    public IterationStage IterationStage { get; set; } = IterationStage.Unknown;\n    public IterationMode IterationMode { get; set; } = IterationMode.Unknown;\n\n    public bool Equals(BdnLifecycle? other)\n    {\n        if (ReferenceEquals(null, other))\n            return false;\n        if (ReferenceEquals(this, other))\n            return true;\n        return LaunchIndex == other.LaunchIndex &&\n               IterationMode == other.IterationMode &&\n               IterationStage == other.IterationStage;\n    }\n\n    public override bool Equals(object? obj)\n    {\n        if (ReferenceEquals(null, obj))\n            return false;\n        if (ReferenceEquals(this, obj))\n            return true;\n        if (obj.GetType() != GetType())\n            return false;\n        return Equals((BdnLifecycle)obj);\n    }\n\n    public override int GetHashCode() => HashCode.Combine(LaunchIndex, IterationMode, IterationStage);\n\n    public static bool operator ==(BdnLifecycle? left, BdnLifecycle? right) => Equals(left, right);\n    public static bool operator !=(BdnLifecycle? left, BdnLifecycle? right) => !Equals(left, right);\n\n    public int CompareTo(BdnLifecycle? other)\n    {\n        if (ReferenceEquals(this, other))\n            return 0;\n        if (ReferenceEquals(null, other))\n            return 1;\n        int launchIndexComparison = LaunchIndex.CompareTo(other.LaunchIndex);\n        if (launchIndexComparison != 0)\n            return launchIndexComparison;\n        int iterationStageComparison = IterationStage.CompareTo(other.IterationStage);\n        if (iterationStageComparison != 0)\n            return iterationStageComparison;\n        return IterationMode.CompareTo(other.IterationMode);\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Models/BdnSchema.cs",
    "content": "using Perfolizer.Perfonar.Base;\n\nnamespace BenchmarkDotNet.Models;\n\ninternal class BdnSchema : PerfonarSchema\n{\n    public static readonly BdnSchema Instance = new();\n\n    private BdnSchema() : base(\"bdn\")\n    {\n        Add<BdnLifecycle>();\n        Add<BdnHostInfo>();\n        Add<BdnBenchmark>();\n        Add<BdnEnvironment>();\n        Add<BdnExecution>();\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Order/CategoryComparer.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\n\nnamespace BenchmarkDotNet.Order\n{\n    internal class CategoryComparer : IComparer<string[]>\n    {\n        private const string Separator = \"§\";\n        public static readonly CategoryComparer Instance = new();\n\n        public int Compare(string[]? x, string[]? y)\n        {\n            if (ReferenceEquals(x, y)) return 0;\n            if (x is null) return -1;\n            if (y is null) return 1;\n\n            return string.Compare(GetUniqueId(x), GetUniqueId(y), StringComparison.Ordinal);\n        }\n\n        private static string GetUniqueId(string[] categories)\n        {\n            var list = categories.ToList();\n            list.Sort();\n            return string.Join(Separator, categories);\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Order/DefaultOrderer.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Collections.Immutable;\nusing System.Diagnostics.CodeAnalysis;\nusing System.Linq;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Parameters;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Running;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Order\n{\n    [SuppressMessage(\"ReSharper\", \"ClassWithVirtualMembersNeverInherited.Global\")]\n    public class DefaultOrderer : IOrderer\n    {\n        public static readonly IOrderer Instance = new DefaultOrderer();\n\n        private readonly IComparer<string[]> categoryComparer = CategoryComparer.Instance;\n        private readonly IComparer<ParameterInstances> paramsComparer = ParameterComparer.Instance;\n        private readonly IComparer<Job> jobComparer;\n        private readonly IComparer<Descriptor> targetComparer;\n\n        public SummaryOrderPolicy SummaryOrderPolicy { get; }\n        public MethodOrderPolicy MethodOrderPolicy { get; }\n\n        public DefaultOrderer(\n            SummaryOrderPolicy summaryOrderPolicy = SummaryOrderPolicy.Default,\n            MethodOrderPolicy methodOrderPolicy = MethodOrderPolicy.Declared,\n            JobOrderPolicy jobOrderPolicy = JobOrderPolicy.Numeric)\n        {\n            SummaryOrderPolicy = summaryOrderPolicy;\n            MethodOrderPolicy = methodOrderPolicy;\n            jobComparer = jobOrderPolicy == JobOrderPolicy.Ordinal\n                ? JobComparer.Ordinal\n                : JobComparer.Default;\n            targetComparer = new DescriptorComparer(methodOrderPolicy);\n        }\n\n        [PublicAPI]\n        public virtual IEnumerable<BenchmarkCase> GetExecutionOrder(\n            ImmutableArray<BenchmarkCase> benchmarkCases,\n            IEnumerable<BenchmarkLogicalGroupRule>? order = null)\n        {\n            var benchmarkComparer = new BenchmarkComparer(categoryComparer, paramsComparer, jobComparer, targetComparer, order);\n            var list = benchmarkCases.ToList();\n            list.Sort(benchmarkComparer);\n            return list;\n        }\n\n        public virtual IEnumerable<BenchmarkCase> GetSummaryOrder(ImmutableArray<BenchmarkCase> benchmarksCases, Summary summary)\n        {\n            var benchmarkLogicalGroups = benchmarksCases.GroupBy(b => GetLogicalGroupKey(benchmarksCases, b));\n            foreach (var logicalGroup in GetLogicalGroupOrder(benchmarkLogicalGroups, benchmarksCases.FirstOrDefault()?.Config.GetLogicalGroupRules()))\n                foreach (var benchmark in GetSummaryOrderForGroup(logicalGroup.ToImmutableArray(), summary))\n                    yield return benchmark;\n        }\n\n        protected virtual IEnumerable<BenchmarkCase> GetSummaryOrderForGroup(ImmutableArray<BenchmarkCase> benchmarksCase, Summary summary)\n        {\n            switch (SummaryOrderPolicy)\n            {\n                case SummaryOrderPolicy.FastestToSlowest:\n                    return benchmarksCase.OrderBy(b => summary[b]?.ResultStatistics?.Mean ?? 0d);\n                case SummaryOrderPolicy.SlowestToFastest:\n                    return benchmarksCase.OrderByDescending(b => summary[b]?.ResultStatistics?.Mean ?? 0d);\n                case SummaryOrderPolicy.Method:\n                    return benchmarksCase.OrderBy(b => b.Descriptor.WorkloadMethodDisplayInfo);\n                case SummaryOrderPolicy.Declared:\n                    return benchmarksCase;\n                default:\n                    return GetExecutionOrder(benchmarksCase, benchmarksCase.FirstOrDefault()?.Config.GetLogicalGroupRules());\n            }\n        }\n\n        public string? GetHighlightGroupKey(BenchmarkCase benchmarkCase)\n        {\n            switch (SummaryOrderPolicy)\n            {\n                case SummaryOrderPolicy.Default:\n                    return benchmarkCase.Parameters.DisplayInfo;\n                case SummaryOrderPolicy.Method:\n                    return benchmarkCase.Descriptor.WorkloadMethodDisplayInfo;\n                default:\n                    return null;\n            }\n        }\n\n        public string GetLogicalGroupKey(ImmutableArray<BenchmarkCase> allBenchmarksCases, BenchmarkCase benchmarkCase)\n        {\n            var explicitRules = benchmarkCase.Config.GetLogicalGroupRules().ToList();\n            var implicitRules = new List<BenchmarkLogicalGroupRule>();\n            bool hasJobBaselines = allBenchmarksCases.Any(b => b.Job.Meta.Baseline);\n            bool hasDescriptorBaselines = allBenchmarksCases.Any(b => b.Descriptor.Baseline);\n            if (hasJobBaselines)\n            {\n                implicitRules.Add(BenchmarkLogicalGroupRule.ByParams);\n                implicitRules.Add(BenchmarkLogicalGroupRule.ByMethod);\n            }\n            if (hasDescriptorBaselines)\n            {\n                implicitRules.Add(BenchmarkLogicalGroupRule.ByParams);\n                implicitRules.Add(BenchmarkLogicalGroupRule.ByJob);\n            }\n            if (hasJobBaselines && hasDescriptorBaselines)\n            {\n                implicitRules.Remove(BenchmarkLogicalGroupRule.ByMethod);\n                implicitRules.Remove(BenchmarkLogicalGroupRule.ByJob);\n            }\n\n            var rules = new List<BenchmarkLogicalGroupRule>(explicitRules);\n            rules.AddRangeDistinct(implicitRules);\n\n            var keys = new List<string>();\n            foreach (var rule in rules)\n            {\n                switch (rule)\n                {\n                    case BenchmarkLogicalGroupRule.ByMethod:\n                        keys.Add(benchmarkCase.Descriptor.DisplayInfo);\n                        break;\n                    case BenchmarkLogicalGroupRule.ByJob:\n                        keys.Add(benchmarkCase.Job.DisplayInfo);\n                        break;\n                    case BenchmarkLogicalGroupRule.ByParams:\n                        keys.Add($\"DistinctParamSet{allBenchmarksCases.IndexOf(benchmarkCase, BenchmarkParamsEqualityComparer.Instance)}\");\n                        break;\n                    case BenchmarkLogicalGroupRule.ByCategory:\n                        keys.Add(string.Join(\",\", benchmarkCase.Descriptor.Categories));\n                        break;\n                    default:\n                        throw new ArgumentOutOfRangeException(nameof(rule), rule, $\"Not supported {nameof(BenchmarkLogicalGroupRule)}\");\n                }\n            }\n\n            string logicalGroupKey = string.Join(\"-\", keys.Where(key => key != string.Empty));\n            return logicalGroupKey == string.Empty ? \"*\" : logicalGroupKey;\n        }\n\n        public virtual IEnumerable<IGrouping<string, BenchmarkCase>> GetLogicalGroupOrder(\n            IEnumerable<IGrouping<string, BenchmarkCase>> logicalGroups,\n            IEnumerable<BenchmarkLogicalGroupRule>? order = null)\n        {\n            var benchmarkComparer = new BenchmarkComparer(categoryComparer, paramsComparer, jobComparer, targetComparer, order);\n            var logicalGroupComparer = new LogicalGroupComparer(benchmarkComparer);\n            var list = logicalGroups.ToList();\n            list.Sort(logicalGroupComparer);\n            return list;\n        }\n\n        public bool SeparateLogicalGroups => true;\n\n        private class BenchmarkComparer : IComparer<BenchmarkCase>\n        {\n            private static readonly BenchmarkLogicalGroupRule[] DefaultOrder =\n            [\n                BenchmarkLogicalGroupRule.ByCategory,\n                BenchmarkLogicalGroupRule.ByParams,\n                BenchmarkLogicalGroupRule.ByJob,\n                BenchmarkLogicalGroupRule.ByMethod\n            ];\n\n            private readonly IComparer<string[]> categoryComparer;\n            private readonly IComparer<ParameterInstances> paramsComparer;\n            private readonly IComparer<Job> jobComparer;\n            private readonly IComparer<Descriptor> targetComparer;\n            private readonly List<BenchmarkLogicalGroupRule> order;\n\n            public BenchmarkComparer(\n                IComparer<string[]> categoryComparer,\n                IComparer<ParameterInstances> paramsComparer,\n                IComparer<Job> jobComparer,\n                IComparer<Descriptor> targetComparer,\n                IEnumerable<BenchmarkLogicalGroupRule>? order)\n            {\n                this.categoryComparer = categoryComparer;\n                this.targetComparer = targetComparer;\n                this.jobComparer = jobComparer;\n                this.paramsComparer = paramsComparer;\n\n                this.order = [];\n                foreach (var rule in (order ?? []).Concat(DefaultOrder))\n                    if (!this.order.Contains(rule))\n                        this.order.Add(rule);\n            }\n\n            public int Compare(BenchmarkCase? x, BenchmarkCase? y)\n            {\n                if (ReferenceEquals(x, y)) return 0;\n                if (x is null) return -1;\n                if (y is null) return 1;\n\n                foreach (var rule in order)\n                {\n                    int compare = rule switch\n                    {\n                        BenchmarkLogicalGroupRule.ByMethod => targetComparer?.Compare(x.Descriptor, y.Descriptor) ?? 0,\n                        BenchmarkLogicalGroupRule.ByJob => jobComparer?.Compare(x.Job, y.Job) ?? 0,\n                        BenchmarkLogicalGroupRule.ByParams => paramsComparer?.Compare(x.Parameters, y.Parameters) ?? 0,\n                        BenchmarkLogicalGroupRule.ByCategory => categoryComparer?.Compare(x.Descriptor.Categories, y.Descriptor.Categories) ?? 0,\n                        _ => throw new ArgumentOutOfRangeException()\n                    };\n                    if (compare != 0)\n                        return compare;\n                }\n                return string.CompareOrdinal(x.DisplayInfo, y.DisplayInfo);\n            }\n        }\n\n        private sealed class BenchmarkParamsEqualityComparer : IEqualityComparer<BenchmarkCase>\n        {\n            internal static readonly BenchmarkParamsEqualityComparer Instance = new();\n\n            bool IEqualityComparer<BenchmarkCase>.Equals(BenchmarkCase? x, BenchmarkCase? y)\n            {\n                if (ReferenceEquals(x, y))\n                    return true;\n                if (x is null || y is null)\n                    return false;\n\n                return ParameterEqualityComparer.Instance.Equals(x.Parameters, y.Parameters);\n            }\n\n            int IEqualityComparer<BenchmarkCase>.GetHashCode(BenchmarkCase obj)\n                => ParameterEqualityComparer.Instance.GetHashCode(obj.Parameters);\n        }\n\n        private class LogicalGroupComparer : IComparer<IGrouping<string, BenchmarkCase>>\n        {\n            private readonly IComparer<BenchmarkCase> benchmarkComparer;\n\n            public LogicalGroupComparer(IComparer<BenchmarkCase> benchmarkComparer) => this.benchmarkComparer = benchmarkComparer;\n\n            public int Compare(IGrouping<string, BenchmarkCase>? x, IGrouping<string, BenchmarkCase>? y)\n            {\n                if (ReferenceEquals(x, y)) return 0;\n                if (x is null) return -1;\n                if (y is null) return 1;\n\n                return benchmarkComparer.Compare(x.First(), y.First());\n            }\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Order/IOrderer.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Collections.Immutable;\nusing System.Linq;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Running;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Order\n{\n    public interface IOrderer\n    {\n        [PublicAPI]\n        IEnumerable<BenchmarkCase> GetExecutionOrder(ImmutableArray<BenchmarkCase> benchmarksCase, IEnumerable<BenchmarkLogicalGroupRule>? order = null);\n\n        [PublicAPI]\n        IEnumerable<BenchmarkCase> GetSummaryOrder(ImmutableArray<BenchmarkCase> benchmarksCases, Summary summary);\n\n        [PublicAPI]\n        string? GetHighlightGroupKey(BenchmarkCase benchmarkCase);\n\n        [PublicAPI]\n        string? GetLogicalGroupKey(ImmutableArray<BenchmarkCase> allBenchmarksCases, BenchmarkCase benchmarkCase);\n\n        [PublicAPI]\n        IEnumerable<IGrouping<string, BenchmarkCase>> GetLogicalGroupOrder(IEnumerable<IGrouping<string, BenchmarkCase>> logicalGroups,\n            IEnumerable<BenchmarkLogicalGroupRule>? order = null);\n\n        [PublicAPI]\n        bool SeparateLogicalGroups { get; }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Order/JobOrderPolicy.cs",
    "content": "﻿namespace BenchmarkDotNet.Order;\n\npublic enum JobOrderPolicy\n{\n    /// <summary>\n    /// Compare job characteristics in numeric order.\n    /// </summary>\n    Numeric,\n\n    /// <summary>\n    /// Compare job characteristics in ordinal order.\n    /// </summary>\n    Ordinal,\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Order/MethodOrderPolicy.cs",
    "content": "﻿namespace BenchmarkDotNet.Order\n{\n    public enum MethodOrderPolicy\n    {\n        Alphabetical, Declared\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Order/SummaryOrderPolicy.cs",
    "content": "﻿namespace BenchmarkDotNet.Order\n{\n    public enum SummaryOrderPolicy\n    {\n        Default, FastestToSlowest, SlowestToFastest, Method, Declared\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Parameters/ParameterComparer.cs",
    "content": "﻿using System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Reflection;\nusing BenchmarkDotNet.Portability;\n\n#if NETSTANDARD2_0\nusing System.Collections.Concurrent;\nusing System.Linq;\n#endif\n\nnamespace BenchmarkDotNet.Parameters\n{\n    internal class ParameterComparer : IComparer<ParameterInstances>\n    {\n#if NETSTANDARD2_0\n        private static readonly ConcurrentDictionary<Type, MemberInfo[]> s_tupleMembersCache = new();\n\n        private static MemberInfo[] GetTupleMembers(Type type)\n            => s_tupleMembersCache.GetOrAdd(type, t =>\n            {\n                var members = type.FullName.StartsWith(\"System.Tuple`\")\n                    ? type.GetProperties(BindingFlags.Public | BindingFlags.Instance).Cast<MemberInfo>()\n                    : type.GetFields(BindingFlags.Public | BindingFlags.Instance).Cast<MemberInfo>();\n                return members\n                    .Where(p => p.Name.StartsWith(\"Item\"))\n                    .OrderBy(p => p.Name)\n                    .ToArray();\n            });\n#endif\n\n        public static readonly ParameterComparer Instance = new ParameterComparer();\n\n        public int Compare(ParameterInstances? x, ParameterInstances? y)\n        {\n            if (ReferenceEquals(x, y)) return 0;\n            if (x is null) return -1;\n            if (y is null) return 1;\n\n            for (int i = 0; i < Math.Min(x.Count, y.Count); i++)\n            {\n                var comparison = CompareValues(x[i]?.Value, y[i]?.Value);\n                if (comparison != 0)\n                {\n                    return comparison;\n                }\n            }\n\n            return string.CompareOrdinal(x.DisplayInfo, y.DisplayInfo);\n        }\n\n        private static int CompareValues<T1, T2>(T1 x, T2 y)\n        {\n            if (x == null || y == null || x.GetType() != y.GetType())\n            {\n                return string.CompareOrdinal(x?.ToString(), y?.ToString());\n            }\n\n            if (x is IStructuralComparable xStructuralComparable)\n            {\n                try\n                {\n                    return StructuralComparisons.StructuralComparer.Compare(x, y);\n                }\n                // https://github.com/dotnet/BenchmarkDotNet/issues/2346\n                // https://github.com/dotnet/runtime/issues/66472\n                // Unfortunately we can't rely on checking the exception message because it may change per current culture.\n                catch (ArgumentException)\n                {\n                    if (TryFallbackStructuralCompareTo(x, y, out int comparison))\n                    {\n                        return comparison;\n                    }\n                    // A complex user type did not handle a multi-dimensional array or tuple, just re-throw.\n                    throw;\n                }\n            }\n\n            if (x is IComparable xComparable)\n            {\n                // Tuples are already handled by IStructuralComparable case, if this throws, it's the user's own fault.\n                return xComparable.CompareTo(y);\n            }\n\n            if (x is IEnumerable xEnumerable) // General collection comparison support\n            {\n                return CompareEnumerables(xEnumerable, (IEnumerable) y);\n            }\n\n            // Anything else to differentiate between objects.\n            return string.CompareOrdinal(x?.ToString(), y?.ToString());\n        }\n\n        private static bool TryFallbackStructuralCompareTo(object x, object y, out int comparison)\n        {\n            // Check for multi-dimensional array and ITuple and re-try for each element recursively.\n            if (x is Array xArr)\n            {\n                Array yArr = (Array) y;\n                if (xArr.Rank != yArr.Rank)\n                {\n                    comparison = xArr.Rank.CompareTo(yArr.Rank);\n                    return true;\n                }\n\n                for (int dim = 0; dim < xArr.Rank; dim++)\n                {\n                    if (xArr.GetLength(dim) != yArr.GetLength(dim))\n                    {\n                        comparison = xArr.GetLength(dim).CompareTo(yArr.GetLength(dim));\n                        return true;\n                    }\n                }\n\n                // Common 2D and 3D arrays are specialized to avoid expensive boxing where possible.\n                if (!RuntimeInformation.IsAot && xArr.Rank is 2 or 3)\n                {\n                    string methodName = xArr.Rank == 2\n                        ? nameof(CompareTwoDArray)\n                        : nameof(CompareThreeDArray);\n                    comparison = (int) typeof(ParameterComparer)\n                        .GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Static)!\n                        .MakeGenericMethod(xArr.GetType().GetElementType()!, yArr.GetType().GetElementType()!)\n                        .Invoke(null, [xArr, yArr])!;\n                    return true;\n                }\n\n                // 1D arrays will only hit this code path if a nested type is a multi-dimensional array.\n                // 4D and larger fall back to enumerable.\n                comparison = CompareEnumerables(xArr, yArr);\n                return true;\n            }\n\n#if NETSTANDARD2_0\n            // ITuple does not exist in netstandard2.0, so we have to use reflection. ITuple does exist in net471 and newer, but the System.ValueTuple nuget package does not implement it.\n            string typeName = x.GetType().FullName;\n            if (typeName.StartsWith(\"System.Tuple`\"))\n            {\n                comparison = CompareTuples(x, y);\n                return true;\n            }\n            else if (typeName.StartsWith(\"System.ValueTuple`\"))\n            {\n                comparison = CompareValueTuples(x, y);\n                return true;\n            }\n#else\n            if (x is System.Runtime.CompilerServices.ITuple xTuple)\n            {\n                comparison = CompareTuples(xTuple, (System.Runtime.CompilerServices.ITuple) y);\n                return true;\n            }\n#endif\n\n            if (x is IEnumerable xEnumerable) // General collection equality support\n            {\n                comparison = CompareEnumerables(xEnumerable, (IEnumerable) y);\n                return true;\n            }\n\n            comparison = 0;\n            return false;\n        }\n\n        private static int CompareEnumerables(IEnumerable x, IEnumerable y)\n        {\n            var xEnumerator = x.GetEnumerator();\n            try\n            {\n                var yEnumerator = y.GetEnumerator();\n                try\n                {\n                    while (xEnumerator.MoveNext())\n                    {\n                        if (!yEnumerator.MoveNext())\n                        {\n                            return -1;\n                        }\n                        int comparison = CompareValues(xEnumerator.Current, yEnumerator.Current);\n                        if (comparison != 0)\n                        {\n                            return comparison;\n                        }\n                    }\n                    return yEnumerator.MoveNext() ? 1 : 0;\n                }\n                finally\n                {\n                    if (yEnumerator is IDisposable disposable)\n                    {\n                        disposable.Dispose();\n                    }\n                }\n            }\n            finally\n            {\n                if (xEnumerator is IDisposable disposable)\n                {\n                    disposable.Dispose();\n                }\n            }\n        }\n\n        private static int CompareTwoDArray<T1, T2>(T1[,] arrOne, T2[,] arrTwo)\n        {\n            // Assumes that arrOne & arrTwo are the same length and width.\n            for (int i = 0; i < arrOne.GetLength(0); i++)\n            {\n                for (int j = 0; j < arrOne.GetLength(1); j++)\n                {\n                    var comparison = CompareValues(arrOne[i, j], arrTwo[i, j]);\n                    if (comparison != 0)\n                    {\n                        return comparison;\n                    }\n                }\n            }\n\n            return 0;\n        }\n\n        private static int CompareThreeDArray<T1, T2>(T1[,,] arrOne, T2[,,] arrTwo)\n        {\n            // Assumes that arrOne & arrTwo are the same length, width, and height.\n            for (int i = 0; i < arrOne.GetLength(0); i++)\n            {\n                for (int j = 0; j < arrOne.GetLength(1); j++)\n                {\n                    for (int k = 0; k <arrOne.GetLength(2); k++)\n                    {\n                        var comparison = CompareValues(arrOne[i, j, k], arrTwo[i, j, k]);\n                        if (comparison != 0)\n                        {\n                            return comparison;\n                        }\n                    }\n                }\n            }\n\n            return 0;\n        }\n\n#if NETSTANDARD2_0\n        private static int CompareTuples(object x, object y)\n        {\n            foreach (PropertyInfo property in GetTupleMembers(x.GetType()))\n            {\n                var comparison = CompareValues(property.GetValue(x), property.GetValue(y));\n                if (comparison != 0)\n                {\n                    return comparison;\n                }\n            }\n\n            return 0;\n        }\n\n        private static int CompareValueTuples(object x, object y)\n        {\n            foreach (FieldInfo field in GetTupleMembers(x.GetType()))\n            {\n                var comparison = CompareValues(field.GetValue(x), field.GetValue(y));\n                if (comparison != 0)\n                {\n                    return comparison;\n                }\n            }\n\n            return 0;\n        }\n#else\n        private static int CompareTuples(System.Runtime.CompilerServices.ITuple x, System.Runtime.CompilerServices.ITuple y)\n        {\n            for (int i = 0; i < x.Length; i++)\n            {\n                var comparison = CompareValues(x[i], y[i]);\n                if (comparison != 0)\n                {\n                    return comparison;\n                }\n            }\n\n            return 0;\n        }\n#endif\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Parameters/ParameterDefinition.cs",
    "content": "﻿using System;\n\nnamespace BenchmarkDotNet.Parameters\n{\n    public class ParameterDefinition\n    {\n        public string Name { get; }\n        public bool IsStatic { get; }\n        public object?[] Values { get; }\n        public bool IsArgument { get; }\n        public Type ParameterType { get; }\n        public int PriorityInCategory { get; }\n\n        public ParameterDefinition(string name, bool isStatic, object?[] values, bool isArgument, Type parameterType, int priorityInCategory)\n        {\n            Name = name;\n            IsStatic = isStatic;\n            Values = values;\n            IsArgument = isArgument;\n            ParameterType = parameterType;\n            PriorityInCategory = priorityInCategory;\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Parameters/ParameterDefinitions.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Linq;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Reports;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Parameters\n{\n    public class ParameterDefinitions\n    {\n        [PublicAPI] public IReadOnlyList<ParameterDefinition> Items { get; }\n\n        public ParameterDefinitions(IReadOnlyList<ParameterDefinition> items) => Items = items;\n\n        public IReadOnlyList<ParameterInstances> Expand(SummaryStyle summaryStyle) => Expand([new ParameterInstances(new List<ParameterInstance>())], Items, summaryStyle);\n\n        private static IReadOnlyList<ParameterInstances> Expand(IReadOnlyList<ParameterInstances> instancesList, IReadOnlyList<ParameterDefinition> definitions, SummaryStyle summaryStyle)\n        {\n            if (definitions.IsNullOrEmpty())\n                return instancesList;\n            var nextDefinition = definitions.First();\n            var newInstancesList = new List<ParameterInstances>();\n            foreach (var instances in instancesList)\n            {\n                foreach (var value in nextDefinition.Values)\n                {\n                    var items = new List<ParameterInstance>();\n                    items.AddRange(instances.Items);\n                    items.Add(new ParameterInstance(nextDefinition, value, summaryStyle));\n                    newInstancesList.Add(new ParameterInstances(items));\n                }\n            }\n            return Expand(newInstancesList, definitions.Skip(1).ToArray(), summaryStyle);\n        }\n\n        public override string ToString() => Items.Any() ? string.Join(\",\", Items.Select(item => item.Name)) : \"<empty>\";\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Parameters/ParameterEqualityComparer.cs",
    "content": "﻿using System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Reflection;\nusing BenchmarkDotNet.Portability;\n\n#if NETSTANDARD2_0\nusing System.Collections.Concurrent;\nusing System.Linq;\n#endif\n\nnamespace BenchmarkDotNet.Parameters\n{\n    internal class ParameterEqualityComparer : IEqualityComparer<ParameterInstances>\n    {\n#if NETSTANDARD2_0\n        private static readonly ConcurrentDictionary<Type, MemberInfo[]> s_tupleMembersCache = new();\n\n        private static MemberInfo[] GetTupleMembers(Type type)\n            => s_tupleMembersCache.GetOrAdd(type, t =>\n            {\n                var members = type.FullName.StartsWith(\"System.Tuple`\")\n                    ? type.GetProperties(BindingFlags.Public | BindingFlags.Instance).Cast<MemberInfo>()\n                    : type.GetFields(BindingFlags.Public | BindingFlags.Instance).Cast<MemberInfo>();\n                return members\n                    .Where(p => p.Name.StartsWith(\"Item\"))\n                    .OrderBy(p => p.Name)\n                    .ToArray();\n            });\n#endif\n\n        public static readonly ParameterEqualityComparer Instance = new ParameterEqualityComparer();\n\n        public bool Equals(ParameterInstances? x, ParameterInstances? y)\n        {\n            if (ReferenceEquals(x, y))\n                return true;\n\n            if (x is null || y is null)\n                return false;\n\n            if (x.Count != y.Count) return false;\n\n            for (int i = 0; i < x.Count; i++)\n            {\n                if (!ValuesEqual(x[i]?.Value, y[i]?.Value))\n                {\n                    return false;\n                }\n            }\n\n            return true;\n        }\n\n        private static bool ValuesEqual<T1, T2>(T1 x, T2 y)\n        {\n            if (x == null && y == null)\n            {\n                return true;\n            }\n\n            if (x == null || y == null || x.GetType() != y.GetType())\n            {\n                // The objects are of different types or one is null, they cannot be equal\n                return false;\n            }\n\n            if (x is IStructuralEquatable xStructuralEquatable)\n            {\n                try\n                {\n                    return StructuralComparisons.StructuralEqualityComparer.Equals(xStructuralEquatable, y);\n                }\n                // https://github.com/dotnet/runtime/issues/66472\n                // Unfortunately we can't rely on checking the exception message because it may change per current culture.\n                catch (ArgumentException)\n                {\n                    if (TryFallbackStructuralEquals(x, y, out bool equals))\n                    {\n                        return equals;\n                    }\n                    // A complex user type did not handle a multi-dimensional array, just re-throw.\n                    throw;\n                }\n            }\n\n            if (x is IEnumerable xEnumerable) // General collection equality support\n            {\n                return EnumerablesEqual(xEnumerable, (IEnumerable) y);\n            }\n\n            return FallbackSimpleEquals(x, y);\n        }\n\n        private static bool FallbackSimpleEquals(object x, object y)\n        {\n            if (x.Equals(y))\n            {\n                return true;\n            }\n            // Anything else to differentiate between objects (match behavior of ParameterComparer).\n            return string.Equals(x.ToString(), y.ToString(), StringComparison.Ordinal);\n        }\n\n        private static bool TryFallbackStructuralEquals(object x, object y, out bool equals)\n        {\n            // Check for multi-dimensional array and ITuple and re-try for each element recursively.\n            if (x is Array xArr)\n            {\n                Array yArr = (Array) y;\n                if (xArr.Rank != yArr.Rank)\n                {\n                    equals = false;\n                    return true;\n                }\n\n                for (int dim = 0; dim < xArr.Rank; dim++)\n                {\n                    if (xArr.GetLength(dim) != yArr.GetLength(dim))\n                    {\n                        equals = false;\n                        return true;\n                    }\n                }\n\n                // Common 2D and 3D arrays are specialized to avoid expensive boxing where possible.\n                if (!RuntimeInformation.IsAot && xArr.Rank is 2 or 3)\n                {\n                    string methodName = xArr.Rank == 2\n                        ? nameof(TwoDArraysEqual)\n                        : nameof(ThreeDArraysEqual);\n                    equals = (bool) typeof(ParameterEqualityComparer)\n                        .GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Static)!\n                        .MakeGenericMethod(xArr.GetType().GetElementType()!, yArr.GetType().GetElementType()!)\n                        .Invoke(null, [xArr, yArr])!;\n                    return true;\n                }\n\n                // 1D arrays will only hit this code path if a nested type is a multi-dimensional array.\n                // 4D and larger fall back to enumerable.\n                equals = EnumerablesEqual(xArr, yArr);\n                return true;\n            }\n\n#if NETSTANDARD2_0\n            // ITuple does not exist in netstandard2.0, so we have to use reflection. ITuple does exist in net471 and newer, but the System.ValueTuple nuget package does not implement it.\n            string typeName = x.GetType().FullName;\n            if (typeName.StartsWith(\"System.Tuple`\"))\n            {\n                equals = TuplesEqual(x, y);\n                return true;\n            }\n            else if (typeName.StartsWith(\"System.ValueTuple`\"))\n            {\n                equals = ValueTuplesEqual(x, y);\n                return true;\n            }\n#else\n            if (x is System.Runtime.CompilerServices.ITuple xTuple)\n            {\n                equals = TuplesEqual(xTuple, (System.Runtime.CompilerServices.ITuple) y);\n                return true;\n            }\n#endif\n\n            if (x is IEnumerable xEnumerable) // General collection equality support\n            {\n                equals = EnumerablesEqual(xEnumerable, (IEnumerable) y);\n                return true;\n            }\n\n            equals = false;\n            return false;\n        }\n\n        private static bool EnumerablesEqual(IEnumerable x, IEnumerable y)\n        {\n            var xEnumerator = x.GetEnumerator();\n            try\n            {\n                var yEnumerator = y.GetEnumerator();\n                try\n                {\n                    while (xEnumerator.MoveNext())\n                    {\n                        if (!(yEnumerator.MoveNext() && ValuesEqual(xEnumerator.Current, yEnumerator.Current)))\n                        {\n                            return false;\n                        }\n                    }\n                    return !yEnumerator.MoveNext();\n                }\n                finally\n                {\n                    if (yEnumerator is IDisposable disposable)\n                    {\n                        disposable.Dispose();\n                    }\n                }\n            }\n            finally\n            {\n                if (xEnumerator is IDisposable disposable)\n                {\n                    disposable.Dispose();\n                }\n            }\n        }\n\n        private static bool TwoDArraysEqual<T1, T2>(T1[,] arrOne, T2[,] arrTwo)\n        {\n            // Assumes that arrOne & arrTwo are the same length and width.\n            for (int i = 0; i < arrOne.GetLength(0); i++)\n            {\n                for (int j = 0; j < arrOne.GetLength(1); j++)\n                {\n                    if (!ValuesEqual(arrOne[i, j], arrTwo[i, j]))\n                    {\n                        return false;\n                    }\n                }\n            }\n\n            return true;\n        }\n\n        private static bool ThreeDArraysEqual<T1, T2>(T1[,,] arrOne, T2[,,] arrTwo)\n        {\n            // Assumes that arrOne & arrTwo are the same length, width, and height.\n            for (int i = 0; i < arrOne.GetLength(0); i++)\n            {\n                for (int j = 0; j < arrOne.GetLength(1); j++)\n                {\n                    for (int k = 0; k <arrOne.GetLength(2); k++)\n                    {\n                        if (!ValuesEqual(arrOne[i, j, k], arrTwo[i, j, k]))\n                        {\n                            return false;\n                        }\n                    }\n                }\n            }\n\n            return true;\n        }\n\n#if NETSTANDARD2_0\n        private static bool TuplesEqual(object x, object y)\n        {\n            foreach (PropertyInfo property in GetTupleMembers(x.GetType()))\n            {\n                if (!ValuesEqual(property.GetValue(x), property.GetValue(y)))\n                {\n                    return false;\n                }\n            }\n\n            return true;\n        }\n\n        private static bool ValueTuplesEqual(object x, object y)\n        {\n            foreach (FieldInfo field in GetTupleMembers(x.GetType()))\n            {\n                if (!ValuesEqual(field.GetValue(x), field.GetValue(y)))\n                {\n                    return false;\n                }\n            }\n\n            return true;\n        }\n#else\n        private static bool TuplesEqual(System.Runtime.CompilerServices.ITuple x, System.Runtime.CompilerServices.ITuple y)\n        {\n            for (int i = 0; i < x.Length; i++)\n            {\n                if (!ValuesEqual(x[i], y[i]))\n                {\n                    return false;\n                }\n            }\n\n            return true;\n        }\n#endif\n\n        public int GetHashCode(ParameterInstances obj)\n        {\n            return obj?.ValueInfo.GetHashCode() ?? 0;\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Parameters/ParameterInstance.cs",
    "content": "﻿using System;\nusing System.Globalization;\nusing BenchmarkDotNet.Code;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Helpers;\nusing BenchmarkDotNet.Reports;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Parameters\n{\n    public class ParameterInstance : IDisposable\n    {\n        public const string NullParameterTextRepresentation = \"?\";\n\n        [PublicAPI] public ParameterDefinition Definition { get; }\n\n        private readonly object? value;\n        private readonly int maxParameterColumnWidthFromConfig;\n\n        public ParameterInstance(ParameterDefinition definition, object? value, SummaryStyle? summaryStyle)\n        {\n            Definition = definition;\n            this.value = value;\n            maxParameterColumnWidthFromConfig = summaryStyle?.MaxParameterColumnWidth ?? SummaryStyle.DefaultMaxParameterColumnWidth;\n        }\n\n        public void Dispose() => (Value as IDisposable)?.Dispose();\n\n        public string Name => Definition.Name;\n        public bool IsStatic => Definition.IsStatic;\n        public bool IsArgument => Definition.IsArgument;\n\n        public object? Value => value is IParam parameter ? parameter.Value : value;\n\n        public string ToSourceCode()\n            => value is IParam parameter\n                ? parameter.ToSourceCode()\n                : SourceCodeHelper.ToSourceCode(value);\n\n        private string ToDisplayText(CultureInfo cultureInfo, int maxParameterColumnWidth)\n        {\n            switch (value)\n            {\n                case null:\n                    return NullParameterTextRepresentation;\n                case IParam parameter:\n                    return Trim(parameter.DisplayText, maxParameterColumnWidth).EscapeSpecialCharacters(false);\n                case IFormattable formattable:\n                    return Trim(formattable.ToString(null, cultureInfo), maxParameterColumnWidth).EscapeSpecialCharacters(false);\n                // no trimming for types!\n                case Type type:\n                    return type.IsNullable() ? $\"{Nullable.GetUnderlyingType(type)!.GetDisplayName()}?\" : type.GetDisplayName();\n                default:\n                    return Trim(value.ToString()!, maxParameterColumnWidth).EscapeSpecialCharacters(false);\n            }\n        }\n\n        public string ToDisplayText(SummaryStyle summary)\n        {\n            return summary != null ? ToDisplayText(summary.CultureInfo, summary.MaxParameterColumnWidth) : ToDisplayText();\n        }\n\n        public string ToDisplayText() => ToDisplayText(CultureInfo.CurrentCulture, maxParameterColumnWidthFromConfig);\n\n        public override string ToString() => ToDisplayText();\n\n        private static string Trim(string value, int maxDisplayTextInnerLength)\n        {\n            if (value.Length <= maxDisplayTextInnerLength)\n                return value;\n\n            var postfix = $\" [{value.Length}]\";\n            const string dots = \"(...)\";\n\n            var takeFromStart = (maxDisplayTextInnerLength - postfix.Length - dots.Length) / 2;\n            var takeFromEnd = takeFromStart;\n\n            if (IsFirstCharInSurrogatePair(value[takeFromStart - 1]))\n            {\n                takeFromStart = Math.Max(0, takeFromStart - 1);\n            }\n\n            if (IsSecondCharInSurrogatePair(value[value.Length - takeFromEnd]))\n            {\n                takeFromEnd = Math.Max(0, takeFromEnd - 1);\n            }\n\n            var result = value.Substring(0, takeFromStart) + dots + value.Substring(value.Length - takeFromEnd, takeFromEnd) + postfix;\n\n            return result;\n        }\n\n        private static bool IsFirstCharInSurrogatePair(char c)\n        {\n            return BitConverter.IsLittleEndian ? char.IsHighSurrogate(c) : char.IsLowSurrogate(c);\n        }\n\n        private static bool IsSecondCharInSurrogatePair(char c)\n        {\n            return BitConverter.IsLittleEndian ? char.IsLowSurrogate(c) : char.IsHighSurrogate(c);\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Parameters/ParameterInstances.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing BenchmarkDotNet.Extensions;\n\nnamespace BenchmarkDotNet.Parameters\n{\n    public class ParameterInstances : IEquatable<ParameterInstances>, IDisposable\n    {\n        public static readonly ParameterInstances Empty = new([]);\n\n        public IReadOnlyList<ParameterInstance> Items { get; }\n        public int Count => Items.Count;\n        public ParameterInstance this[int index] => Items[index];\n        public object? this[string name] => Items.FirstOrDefault(item => item.Name == name)?.Value;\n\n        private string? printInfo = null;\n\n        public ParameterInstances(IReadOnlyList<ParameterInstance> items)\n        {\n            Items = items;\n        }\n\n        public void Dispose()\n        {\n            foreach (var parameterInstance in Items)\n            {\n                parameterInstance.Dispose();\n            }\n        }\n\n        public string FolderInfo => string.Join(\"_\", Items.Select(p => $\"{p.Name}-{p.ToDisplayText()}\")).AsValidFileName();\n\n        public string DisplayInfo =>  Items.Any() ? \"[\" + string.Join(\", \", Items.Select(p => $\"{p.Name}={p.ToDisplayText()}\")) + \"]\" : \"\";\n\n        public string ValueInfo => Items.Any() ? \"[\" + string.Join(\", \", Items.Select(p => $\"{p.Name}={p.Value?.ToString() ?? ParameterInstance.NullParameterTextRepresentation}\")) + \"]\" : \"\";\n\n        public string PrintInfo => printInfo ?? (printInfo = string.Join(\"&\", Items.Select(p => $\"{p.Name}={p.ToDisplayText()}\")));\n\n        public ParameterInstance GetArgument(string name) => Items.Single(parameter => parameter.IsArgument && parameter.Name == name);\n\n        public bool Equals(ParameterInstances? other)\n        {\n            if (ReferenceEquals(this, other))\n                return true;\n\n            if (other == null)\n                return false;\n\n            if (other.Count != Count)\n                return false;\n\n            if (Count != other.Count)\n                return false;\n\n            for (int i = 0; i < Count; i++)\n            {\n                var currentItem = Items[i];\n                var otherItem = other.Items[i];\n\n                if (ReferenceEquals(currentItem, otherItem))\n                    continue;\n\n                if (currentItem is null || otherItem is null)\n                    return false;\n\n                if (!currentItem.Equals(otherItem.Value))\n                    return false;\n            }\n\n            return true;\n        }\n\n        public override bool Equals(object? obj) \n            => obj is ParameterInstances other && Equals(other);\n\n        public override int GetHashCode() => FolderInfo.GetHashCode();\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Parameters/SmartParamBuilder.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Diagnostics.CodeAnalysis;\nusing System.Linq;\nusing System.Reflection;\nusing BenchmarkDotNet.Code;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Helpers;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Toolchains.InProcess.Emit.Implementation;\n\nnamespace BenchmarkDotNet.Parameters\n{\n    internal static class SmartParamBuilder\n    {\n        [SuppressMessage(\"ReSharper\", \"CoVariantArrayConversion\")]\n        internal static object[] CreateForParams(Type parameterType, MemberInfo source, object[] values)\n        {\n            // IEnumerable<object>\n            if (values.IsEmpty() || values.All(SourceCodeHelper.IsCompilationTimeConstant))\n                return values;\n\n            // IEnumerable<object[]>\n            if (values.All(value => value is object[] array && array.Length == 1 && SourceCodeHelper.IsCompilationTimeConstant(array[0])))\n                return values.Select(x => ((object[])x)[0]).ToArray();\n\n            return values.Select((value, index) => new SmartParameter(parameterType, source, value, index)).ToArray();\n        }\n\n        internal static ParameterInstances CreateForArguments(MethodInfo benchmark, ParameterDefinition[] parameterDefinitions, (MemberInfo source, object[] values) valuesInfo, int sourceIndex, SummaryStyle summaryStyle)\n        {\n            var unwrappedValue = valuesInfo.values[sourceIndex];\n\n            if (unwrappedValue is object[] array)\n            {\n                Type? firstParamType = benchmark.GetParameters().FirstOrDefault()?.ParameterType;\n                // the user provided object[] for a benchmark accepting a single argument\n                if (parameterDefinitions.Length == 1 && array.Length == 1\n                    && (array[0]?.GetType() == firstParamType || (firstParamType != null && firstParamType.IsStackOnlyWithImplicitCast(array[0])))) // the benchmark that accepts an object[] as argument\n                {\n                    return new ParameterInstances(\n                        [Create(parameterDefinitions, array[0], valuesInfo.source, sourceIndex, argumentIndex: 0, summaryStyle)]);\n                }\n\n                if (parameterDefinitions.Length > 1)\n                {\n                    if (parameterDefinitions.Length != array.Length)\n                        throw new InvalidOperationException($\"Benchmark {benchmark.Name} has invalid number of arguments provided by [ArgumentsSource({valuesInfo.source.Name})]! {array.Length} instead of {parameterDefinitions.Length}.\");\n\n                    return new ParameterInstances(\n                        array.Select((value, argumentIndex) => Create(parameterDefinitions, value, valuesInfo.source, sourceIndex, argumentIndex, summaryStyle)).ToArray());\n                }\n            }\n\n            if (parameterDefinitions.Length == 1)\n            {\n                return new ParameterInstances([Create(parameterDefinitions, unwrappedValue, valuesInfo.source, sourceIndex, argumentIndex: 0, summaryStyle)]);\n            }\n\n            throw new NotSupportedException($\"Benchmark {benchmark.Name} has invalid type of arguments provided by [ArgumentsSource({valuesInfo.source.Name})]. It should be IEnumerable<object[]> or IEnumerable<object>.\");\n        }\n\n        private static ParameterInstance Create(ParameterDefinition[] parameterDefinitions, object value, MemberInfo source, int sourceIndex, int argumentIndex, SummaryStyle summaryStyle)\n        {\n            if (SourceCodeHelper.IsCompilationTimeConstant(value))\n                return new ParameterInstance(parameterDefinitions[argumentIndex], value, summaryStyle);\n\n            return new ParameterInstance(parameterDefinitions[argumentIndex], new SmartArgument(parameterDefinitions, value, source, sourceIndex, argumentIndex), summaryStyle);\n        }\n    }\n\n    internal class SmartArgument : IParam\n    {\n        private readonly ParameterDefinition[] parameterDefinitions;\n        private readonly MemberInfo source;\n        private readonly int sourceIndex;\n        private readonly int argumentIndex;\n\n        public SmartArgument(ParameterDefinition[] parameterDefinitions, object value, MemberInfo source, int sourceIndex, int argumentIndex)\n        {\n            this.parameterDefinitions = parameterDefinitions;\n            Value = value;\n            this.source = source;\n            this.sourceIndex = sourceIndex;\n            this.argumentIndex = argumentIndex;\n        }\n\n        public object Value { get; }\n\n        public string DisplayText => Value is Array array ? ArrayParam.GetDisplayString(array) : Value?.ToString() ?? ParameterInstance.NullParameterTextRepresentation;\n\n        public string ToSourceCode()\n        {\n            Type paramType = parameterDefinitions[argumentIndex].ParameterType;\n            bool isParamRefLike = RunnableReflectionHelpers.IsRefLikeType(paramType);\n\n            string cast = isParamRefLike ? $\"({Value.GetType().GetCorrectCSharpTypeName()})\"\n                : $\"({paramType.GetCorrectCSharpTypeName()})\"; // it's an object so we need to cast it to the right type\n\n            string callPostfix = source is PropertyInfo ? string.Empty : \"()\";\n\n            MethodInfo? sourceAsMethodInfo = source as MethodInfo;\n            PropertyInfo? sourceAsPropertyInfo = source as PropertyInfo;\n\n            Type indexableType = typeof(IEnumerable<object[]>);\n\n            string indexPostfix;\n            if (sourceAsMethodInfo?.ReturnType == indexableType ||\n                sourceAsPropertyInfo?.GetMethod?.ReturnType == indexableType)\n            {\n                indexPostfix = $\"[{argumentIndex}]\";\n            }\n            else\n            {\n                indexPostfix = string.Empty; // IEnumerable<object>\n            }\n\n            string methodCall;\n            if (sourceAsMethodInfo?.IsStatic ?? sourceAsPropertyInfo?.GetMethod?.IsStatic ?? throw new Exception($\"{nameof(source)} was not {nameof(MethodInfo)} nor {nameof(PropertyInfo)}\"))\n            {\n                // If the source member is static, we need to place the fully qualified type name before it, in case the source member is from another type that this generated type does not inherit from.\n                methodCall = $\"{source.DeclaringType!.GetCorrectCSharpTypeName()}.{source.Name}\";\n            }\n            else\n            {\n                // If the source member is non-static, we mustn't include the type name, as this would be a compiler error when accessing a non-static source member in the base class of this generated type.\n                methodCall = $\"base.{source.Name}\";\n            }\n\n            // we do something like enumerable.ElementAt(sourceIndex)[argumentIndex];\n            return $\"{cast}BenchmarkDotNet.Parameters.ParameterExtractor.GetParameter({methodCall}{callPostfix}, {sourceIndex}){indexPostfix};\";\n        }\n    }\n\n    internal class SmartParameter : IParam\n    {\n        private readonly Type parameterType;\n        private readonly MemberInfo source;\n        private readonly MethodBase method;\n        private readonly int index;\n\n        public SmartParameter(Type parameterType, MemberInfo source, object value, int index)\n        {\n            this.parameterType = parameterType;\n            this.source = source;\n            method = source is PropertyInfo property ? property.GetMethod! : (MethodInfo)source;\n            Value = value;\n            this.index = index;\n        }\n\n        public object Value { get; }\n\n        public string DisplayText => Value is Array array ? ArrayParam.GetDisplayString(array) : Value?.ToString() ?? ParameterInstance.NullParameterTextRepresentation;\n\n        public string ToSourceCode()\n        {\n            string cast = $\"({parameterType.GetCorrectCSharpTypeName()})\"; // it's an object so we need to cast it to the right type\n\n            string callPrefix = method.IsStatic ? source.DeclaringType!.GetCorrectCSharpTypeName() : \"base\";\n\n            string callPostfix = source is PropertyInfo ? string.Empty : \"()\";\n\n            // we so something like enumerable.ElementAt(index);\n            return $\"{cast}BenchmarkDotNet.Parameters.ParameterExtractor.GetParameter({callPrefix}.{source.Name}{callPostfix}, {index});\";\n        }\n    }\n\n    public static class ParameterExtractor\n    {\n        [EditorBrowsable(EditorBrowsableState.Never)] // hide from intellisense, it's public so we can call it form the boilerplate code\n        public static T GetParameter<T>(IEnumerable<T> parameters, int index)\n        {\n            int count = 0;\n\n            foreach (T parameter in parameters)\n            {\n                if (count == index)\n                {\n                    return parameter;\n                }\n\n                if (parameter is IDisposable disposable)\n                {\n                    // parameters might contain locking finalizers which might cause the benchmarking process to hung at the end\n                    // to avoid that, we dispose the parameters that were created, but won't be used\n                    // (for every test case we have to enumerate the underlying source enumerator and stop when we reach index of given test case)\n                    // See https://github.com/dotnet/BenchmarkDotNet/issues/1383 and https://github.com/dotnet/runtime/issues/314 for more\n                    disposable.Dispose();\n                }\n\n                count++;\n            }\n\n            throw new InvalidOperationException(\"We should never get here!\");\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Portability/Antivirus.cs",
    "content": "﻿using JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Portability\n{\n    public class Antivirus\n    {\n        public Antivirus(string name, string path)\n        {\n            Name = name;\n            Path = path;\n        }\n\n        [PublicAPI] public string Name { get; }\n        [PublicAPI] public string Path { get; }\n\n        public override string ToString() => $\"{Name} ({Path})\";\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Portability/CodeGen.cs",
    "content": "﻿using System.Reflection;\nusing System.Runtime.CompilerServices;\n\nnamespace BenchmarkDotNet.Portability\n{\n    public static class CodeGenHelper\n    {\n        // AggressiveOptimization is not available in netstandard2.0, so just use the value casted to enum.\n        public const MethodImplOptions AggressiveOptimizationOption = (MethodImplOptions) 512;\n        public const MethodImplAttributes AggressiveOptimizationOptionForEmit = (MethodImplAttributes) 512;\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Portability/HyperV.cs",
    "content": "namespace BenchmarkDotNet.Portability\n{\n    public class HyperV : VirtualMachineHypervisor\n    {\n        public static HyperV Default { get; } = new HyperV();\n\n        private HyperV() { }\n\n        public override string Name => \"Hyper-V\";\n\n        public override bool IsVirtualMachine(string manufacturer, string model)\n        {\n            return ContainsVmIdentifier(manufacturer, \"microsoft\") && ContainsVmIdentifier(model, \"virtual\");\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Portability/JitInfo.cs",
    "content": "﻿using BenchmarkDotNet.Environments;\nusing System;\nusing System.Diagnostics;\nusing static BenchmarkDotNet.Portability.RuntimeInformation;\n\nnamespace BenchmarkDotNet.Portability;\n\n// Implementation is based on article https://medium.com/@meriffa/net-core-concepts-tiered-compilation-10f7da3a29c7\n// documentation https://learn.microsoft.com/en-us/dotnet/core/runtime-config/compilation\n// and source https://github.com/dotnet/runtime/blob/3fb6fbb3efaa7f2ae5e76bf235615d7f70005201/src/coreclr/vm/eeconfig.cpp\n// https://github.com/dotnet/runtime/blob/3fb6fbb3efaa7f2ae5e76bf235615d7f70005201/src/coreclr/jit/jitconfigvalues.h\ninternal static class JitInfo\n{\n    public const string EnvCallCountingDelayMs = \"TC_CallCountingDelayMs\";\n\n    private const string EnvMinOpts = \"JITMinOpts\";\n    private const string EnvTieredCompilation = \"TieredCompilation\";\n    private const string EnvQuickJit = \"TC_QuickJit\";\n    private const string EnvPGO = \"TieredPGO\";\n    private const string EnvCallCountThreshold = \"TC_CallCountThreshold\";\n    private const string EnvAggressiveTiering = \"TC_AggressiveTiering\";\n    private const string EnvOSR = \"TC_OnStackReplacement\";\n\n    private const string KnobTieredCompilation = \"System.Runtime.TieredCompilation\";\n    private const string KnobQuickJit = \"System.Runtime.TieredCompilation.QuickJit\";\n    private const string KnobPGO = \"System.Runtime.TieredPGO\";\n    private const string KnobCallCountThreshold = \"System.Runtime.TieredCompilation.CallCountThreshold\";\n    private const string KnobCallCountingDelayMs = \"System.Runtime.TieredCompilation.CallCountingDelayMs\";\n\n    // .Net 5 and older uses COMPlus_ prefix,\n    // .Net 6+ uses DOTNET_ prefix, but still supports legacy COMPlus_.\n    private static bool IsEnvVarEnabled(string name)\n        => Environment.GetEnvironmentVariable($\"COMPlus_{name}\") == \"1\"\n        || Environment.GetEnvironmentVariable($\"DOTNET_{name}\") == \"1\";\n\n    private static bool IsEnvVarDisabled(string name)\n        => Environment.GetEnvironmentVariable($\"COMPlus_{name}\") == \"0\"\n        || Environment.GetEnvironmentVariable($\"DOTNET_{name}\") == \"0\";\n\n    private static bool TryParseEnvVar(string name, out int value)\n        => int.TryParse(Environment.GetEnvironmentVariable($\"COMPlus_{name}\"), out value)\n        || int.TryParse(Environment.GetEnvironmentVariable($\"DOTNET_{name}\"), out value);\n\n    private static bool IsKnobEnabled(string name)\n        => AppContext.TryGetSwitch(name, out bool isEnabled) && isEnabled;\n\n    private static bool IsKnobDisabled(string name)\n        => AppContext.TryGetSwitch(name, out bool isEnabled) && !isEnabled;\n\n    private static bool TryParseKnob(string name, out int value)\n        => int.TryParse(AppContext.GetData(name) as string, out value);\n\n    private static bool IsEnabled(string envName, string knobName)\n        => IsEnvVarEnabled(envName) || IsKnobEnabled(knobName);\n\n    private static bool IsDisabled(string envName, string knobName)\n        => IsEnvVarDisabled(envName) || IsKnobDisabled(knobName);\n\n    /// <summary>\n    /// Is tiered JIT enabled?\n    /// </summary>\n    public static readonly bool IsTiered =\n        IsNetCore\n        // JITMinOpts disables tiered compilation (all methods are effectively tier0 instead of tier1).\n        && !IsEnvVarEnabled(EnvMinOpts)\n        && ((CoreRuntime.TryGetVersion(out var version) && version.Major >= 3)\n            // Enabled by default in netcoreapp3.0+, check if it's disabled.\n            ? !IsDisabled(EnvTieredCompilation, KnobTieredCompilation)\n            // Disabled by default in netcoreapp2.X, check if it's enabled.\n            : IsEnabled(EnvTieredCompilation, KnobTieredCompilation));\n\n    /// <summary>\n    /// The maximum numbers of jit tiers that a method may be promoted through. This is the maximum number of jit tiers - 1.\n    /// </summary>\n    public static readonly int MaxTierPromotions = GetMaxTierPromotions();\n\n    private static int GetMaxTierPromotions()\n    {\n        if (!IsTiered)\n        {\n            return 0;\n        }\n        // Tier1\n        int maxPromotions = 1;\n        if (GetIsDPGO())\n        {\n            // Tier0 instrumented\n            ++maxPromotions;\n        }\n        if (GetIsOSR())\n        {\n            // On-stack-replacement *shouldn't* interfere with promotion velocity, but there is a bug where OSR may cause a method to be tier0 instrumented twice.\n            // https://github.com/dotnet/runtime/issues/117787#issuecomment-3090771091\n            ++maxPromotions;\n        }\n        return maxPromotions;\n\n        static bool GetIsDPGO() =>\n            // Added experimentally in .Net 6.\n            Environment.Version.Major >= 6\n            // Disabled if QuickJit is disabled in .Net 7+.\n            && (Environment.Version.Major < 7 || !IsDisabled(EnvQuickJit, KnobQuickJit))\n            && (Environment.Version.Major >= 8\n                // Enabled by default in .Net 8, check if it's disabled.\n                ? !IsDisabled(EnvPGO, KnobPGO)\n                // Disabled by default in earlier versions, check if it's enabled.\n                : IsEnabled(EnvPGO, KnobPGO));\n\n        static bool GetIsOSR() =>\n            // Added experimentally in .Net 5.\n            Environment.Version.Major >= 5\n            && (Environment.Version.Major >= 7\n                // Enabled by default in .Net 7, check if it's disabled.\n                ? !IsEnvVarDisabled(EnvOSR)\n                // Disabled by default in earlier versions, check if it's enabled.\n                : IsEnvVarEnabled(EnvOSR));\n    }\n\n    /// <summary>\n    /// The number of times a method must be called before it will be eligible for the next JIT tier.\n    /// </summary>\n    public static readonly int TieredCallCountThreshold = GetTieredCallCountThreshold();\n\n    private static int GetTieredCallCountThreshold()\n    {\n        if (!IsTiered)\n        {\n            return 0;\n        }\n        // AggressiveTiering was added in .Net 5.\n        if (Environment.Version.Major >= 5 && IsEnvVarEnabled(EnvAggressiveTiering))\n        {\n            return 1;\n        }\n        if (TryParseEnvVar(EnvCallCountThreshold, out int callCountThreshold))\n        {\n            return callCountThreshold;\n        }\n        // CallCountThreshold was added as a knob in .Net 8.\n        if (Environment.Version.Major >= 8 && TryParseKnob(KnobCallCountThreshold, out callCountThreshold))\n        {\n            return callCountThreshold;\n        }\n        // Default 30 if it's not configured.\n        return 30;\n    }\n\n    /// <summary>\n    /// How long to wait to ensure tiered JIT call counting has begun.\n    /// </summary>\n    public static readonly TimeSpan TieredDelay = GetTieredDelay();\n\n    private static TimeSpan GetTieredDelay()\n    {\n        if (!IsTiered)\n        {\n            return TimeSpan.Zero;\n        }\n        // AggressiveTiering was added in .Net 5.\n        if (Environment.Version.Major >= 5 && IsEnvVarEnabled(EnvAggressiveTiering))\n        {\n            return TimeSpan.Zero;\n        }\n        if (TryParseEnvVar(EnvCallCountingDelayMs, out int callCountDelay))\n        {\n            return TimeSpan.FromMilliseconds(callCountDelay);\n        }\n        // CallCountingDelayMs was added as a knob in .Net 8.\n        if (Environment.Version.Major >= 8 && TryParseKnob(KnobCallCountingDelayMs, out callCountDelay))\n        {\n            return TimeSpan.FromMilliseconds(callCountDelay);\n        }\n        // Default 100 if it's not configured.\n        return TimeSpan.FromMilliseconds(100);\n    }\n\n    /// <summary>\n    /// How long to wait for the JIT to have completed tiered compilation in the background.\n    /// </summary>\n    public static readonly TimeSpan BackgroundCompilationDelay =\n        IsTiered\n            // It's impossible for us to know exactly how long to wait without hooking into JIT notifications (which we can't do in-process).\n            // 100ms should be enough most of the time, but we bump it up to 250ms for higher confidence.\n            // When https://github.com/dotnet/runtime/issues/101868 is resolved, if AggressiveTiering is enabled, we can skip the wait time and return TimeSpan.Zero.\n            ? TimeSpan.FromMilliseconds(250)\n            : TimeSpan.Zero;\n\n    public static readonly bool IsRyuJit = GetIsRyuJit();\n\n    private static bool GetIsRyuJit()\n    {\n        if (IsNetCore) // CoreCLR supports only RyuJIT.\n            return true;\n        if (IsMono || !IsFullFramework) // If it's not Core or Framework, it's not RyuJIT.\n            return false;\n        if (!Is64BitPlatform()) // Framework supports RyuJIT only in 64-bit process.\n            return false;\n\n        // https://stackoverflow.com/a/31534544\n        foreach (ProcessModule module in Process.GetCurrentProcess().Modules)\n        {\n            // clrjit.dll -> RyuJit\n            // compatjit.dll -> Legacy Jit\n            if (module.ModuleName == \"clrjit.dll\")\n            {\n                return true;\n            }\n        }\n        return false;\n    }\n\n    public static Jit GetCurrentJit() => IsRyuJit ? Jit.RyuJit : Jit.LegacyJit;\n\n    public static string GetInfo()\n    {\n        if (IsNativeAOT)\n            return \"NativeAOT\";\n        if (IsAot)\n            return \"AOT\";\n        if (IsMono || IsWasm)\n            return \"\"; // There is no helpful information about JIT on Mono\n        if (IsRyuJit)\n            return \"RyuJIT\";\n        if (IsFullFramework)\n            return \"LegacyJIT\";\n\n        return Unknown;\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Portability/Libc.cs",
    "content": "﻿using System.Runtime.InteropServices;\n\nnamespace BenchmarkDotNet.Portability\n{\n#pragma warning disable CS8981 // The type name 'libc' only contains lower-cased ascii characters. Such names may become reserved for the language.\n    internal static class libc\n#pragma warning restore CS8981\n    {\n        [DllImport(nameof(libc))]\n        internal static extern int getppid();\n\n        [DllImport(nameof(libc))]\n        internal static extern uint getuid();\n\n        [DllImport(nameof(libc), SetLastError = true)]\n        internal static extern int kill(int pid, int sig);\n\n        [DllImport(nameof(libc), SetLastError = true)]\n        internal static extern int chmod(string path, uint mode);\n\n        internal static class Signals\n        {\n            internal const int SIGINT = 2;\n        }\n\n        internal static class FilePermissions\n        {\n            internal const uint S_IXUSR = 0x40u;\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Portability/RuntimeInformation.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Diagnostics.CodeAnalysis;\nusing System.Linq;\nusing System.Management;\nusing System.Reflection;\nusing System.Runtime.InteropServices;\nusing System.Runtime.Versioning;\nusing System.Text.RegularExpressions;\nusing BenchmarkDotNet.Detectors;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Helpers;\nusing static System.Runtime.InteropServices.RuntimeInformation;\n\nnamespace BenchmarkDotNet.Portability\n{\n    internal static class RuntimeInformation\n    {\n        internal const string DebugConfigurationName = \"DEBUG\";\n        internal const string ReleaseConfigurationName = \"RELEASE\";\n        internal const string Unknown = \"?\";\n\n        // Many of these checks allocate and/or are expensive to compute. We store the results in static readonly fields to keep Engine non-allocating.\n        // Static readonly fields are used instead of properties to avoid an extra getter method call that might not be tier1 jitted.\n        // This class is internal, so we don't need to expose these as properties.\n\n        /// <summary>\n        /// returns true for both the old (implementation of .NET Framework) and new Mono (.NET 6+ flavour)\n        /// </summary>\n        public static readonly bool IsMono = Type.GetType(\"Mono.RuntimeStructs\") != null;\n\n        public static readonly bool IsOldMono = Type.GetType(\"Mono.Runtime\") != null;\n\n        public static readonly bool IsNewMono = IsMono && !IsOldMono;\n\n        public static readonly bool IsFullFramework =\n#if NET6_0_OR_GREATER\n            // This could be const, but we want to avoid unreachable code warnings.\n            false;\n#else\n            FrameworkDescription.StartsWith(\".NET Framework\", StringComparison.OrdinalIgnoreCase);\n#endif\n\n        [SupportedOSPlatformGuard(\"browser\")]\n#if NET6_0_OR_GREATER\n        public static readonly bool IsWasm = OperatingSystem.IsBrowser();\n#else\n        public static readonly bool IsWasm = IsOSPlatform(OSPlatform.Create(\"BROWSER\"));\n#endif\n\n#if NETSTANDARD2_0\n        public static readonly bool IsAot = IsAotMethod() || FrameworkDescription.StartsWith(\".NET Native\", StringComparison.OrdinalIgnoreCase);\n\n        private static bool IsAotMethod()\n        {\n            Type runtimeFeature = Type.GetType(\"System.Runtime.CompilerServices.RuntimeFeature\");\n            if (runtimeFeature != null)\n            {\n                MethodInfo? methodInfo = runtimeFeature.GetProperty(\"IsDynamicCodeCompiled\", BindingFlags.Public | BindingFlags.Static)?.GetMethod;\n\n                if (methodInfo != null)\n                {\n                    return !(bool)methodInfo.Invoke(null, null);\n                }\n            }\n\n            return false;\n        }\n#else\n        public static readonly bool IsAot = !System.Runtime.CompilerServices.RuntimeFeature.IsDynamicCodeCompiled;\n#endif\n\n        public static bool IsNetCore\n            => ((Environment.Version.Major >= 5) || FrameworkDescription.StartsWith(\".NET Core\", StringComparison.OrdinalIgnoreCase))\n                && !IsAot;\n\n        public static bool IsNativeAOT\n            => Environment.Version.Major >= 5\n               && IsAot\n               && !IsWasm && !IsMono; // Wasm and MonoAOTLLVM are also AOT\n\n        public static readonly bool IsRunningInContainer = string.Equals(Environment.GetEnvironmentVariable(\"DOTNET_RUNNING_IN_CONTAINER\"), \"true\");\n\n        internal static string GetArchitecture() => GetCurrentPlatform().ToString();\n\n        internal static string GetRuntimeVersion()\n        {\n            if (IsWasm)\n            {\n                // code copied from https://github.com/dotnet/runtime/blob/2c573b59aaaf3fd17e2ecab95ad3769f195d2dbc/src/libraries/System.Runtime.InteropServices.RuntimeInformation/src/System/Runtime/InteropServices/RuntimeInformation/RuntimeInformation.cs#L20-L30\n                string? versionString = typeof(object).Assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion;\n\n                // Strip the git hash if there is one\n                if (versionString != null)\n                {\n                    int plusIndex = versionString.IndexOf('+');\n                    if (plusIndex != -1)\n                    {\n                        versionString = versionString.Substring(0, plusIndex);\n                    }\n                }\n\n                string runtimeName = IsMono ? \"Mono\" : \"CoreCLR\";\n                return $\".NET Core ({runtimeName}) {versionString}\";\n            }\n            else if (IsOldMono)\n            {\n                var monoRuntimeType = Type.GetType(\"Mono.Runtime\");\n                var monoDisplayName = monoRuntimeType?.GetMethod(\"GetDisplayName\", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);\n                if (monoDisplayName != null)\n                {\n                    string? version = monoDisplayName.Invoke(null, null)?.ToString();\n                    if (version != null)\n                    {\n                        int bracket1 = version.IndexOf('('), bracket2 = version.IndexOf(')');\n                        if (bracket1 != -1 && bracket2 != -1)\n                        {\n                            string comment = version.Substring(bracket1 + 1, bracket2 - bracket1 - 1);\n                            var commentParts = comment.Split([' '], StringSplitOptions.RemoveEmptyEntries);\n                            if (commentParts.Length > 2)\n                                version = version.Substring(0, bracket1) + \"(\" + commentParts[0] + \" \" + commentParts[1] + \")\";\n                        }\n                    }\n\n                    return \"Mono \" + version;\n                }\n            }\n            else if (IsNewMono)\n            {\n                return $\"{GetNetCoreVersion()} using MonoVM\";\n            }\n            else if (IsFullFramework)\n            {\n                return FrameworkVersionHelper.GetFrameworkDescription();\n            }\n            else if (IsNetCore)\n            {\n                return GetNetCoreVersion();\n            }\n            else if (IsNativeAOT)\n            {\n                return FrameworkDescription;\n            }\n\n            return Unknown;\n        }\n\n        private static string GetNetCoreVersion()\n        {\n            if (OsDetector.IsAndroid())\n            {\n                return $\".NET {Environment.Version}\";\n            }\n\n            return CoreRuntime.TryGetVersion(out var version) && version.Major >= 5\n                ? $\".NET {version} ({GetDetailedVersion()})\"\n                : $\".NET Core {version?.ToString() ?? Unknown} ({GetDetailedVersion()})\";\n\n            string GetDetailedVersion()\n            {\n                string coreclrLocation = typeof(object).GetTypeInfo().Assembly.Location;\n                // Single-file publish has empty assembly location.\n                if (coreclrLocation.IsBlank())\n                    return CoreRuntime.GetVersionFromFrameworkDescription();\n                // .Net Core 2.X has confusing FrameworkDescription like 4.6.X.\n                if (version?.Major >= 3)\n                    return $\"{CoreRuntime.GetVersionFromFrameworkDescription()}, {FileVersionInfo.GetVersionInfo(coreclrLocation).FileVersion}\";\n                return FileVersionInfo.GetVersionInfo(coreclrLocation).FileVersion!;\n            }\n        }\n\n        internal static Runtime GetTargetOrCurrentRuntime(Assembly? assembly)\n        {\n            // Match order of checks in GetCurrentRuntime().\n            if (!IsMono && !IsWasm)\n            {\n                if (IsFullFramework)\n                    return ClrRuntime.GetTargetOrCurrentVersion(assembly);\n                // 99% of the time the core runtime is the same as the target framework, but the runtime could roll forward if it's not self-contained.\n                if (IsNetCore)\n                    return CoreRuntime.GetTargetOrCurrentVersion(assembly);\n            }\n            return GetCurrentRuntime();\n        }\n\n        internal static Runtime GetCurrentRuntime()\n        {\n            //do not change the order of conditions because it may cause incorrect determination of runtime\n            if (IsAot && IsMono)\n                return MonoAotLLVMRuntime.Default;\n            if (IsWasm)\n                return WasmRuntime.Default;\n            if (IsNewMono)\n                return MonoRuntime.GetCurrentVersion();\n            if (IsOldMono)\n                return MonoRuntime.Default;\n            if (IsFullFramework)\n                return ClrRuntime.GetCurrentVersion();\n            if (IsNetCore)\n                return CoreRuntime.GetCurrentVersion();\n            if (IsNativeAOT)\n                return NativeAotRuntime.GetCurrentVersion();\n\n            throw new NotSupportedException(\"Unknown .NET Runtime\");\n        }\n\n        public static Platform GetCurrentPlatform()\n        {\n            // these are not part of .NET Standard 2.0, so we use hardcoded values taken from\n            // https://github.com/dotnet/runtime/blob/080fcae7eaa8367abf7900e08ff2e52e3efea5bf/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Architecture.cs#L9\n            const Architecture Wasm = (Architecture)4;\n            const Architecture S390x = (Architecture)5;\n            const Architecture LoongArch64 = (Architecture)6;\n            const Architecture Armv6 = (Architecture)7;\n            const Architecture Ppc64le = (Architecture)8;\n            const Architecture RiscV64 = (Architecture)9;\n\n            switch (ProcessArchitecture)\n            {\n                case Architecture.Arm:\n                    return Platform.Arm;\n                case Architecture.Arm64:\n                    return Platform.Arm64;\n                case Architecture.X64:\n                    return Platform.X64;\n                case Architecture.X86:\n                    return Platform.X86;\n                case Wasm:\n                    return Platform.Wasm;\n                case S390x:\n                    return Platform.S390x;\n                case LoongArch64:\n                    return Platform.LoongArch64;\n                case Armv6:\n                    return Platform.Armv6;\n                case Ppc64le:\n                    return Platform.Ppc64le;\n                case RiscV64:\n                    return Platform.RiscV64;\n                default:\n                    throw new ArgumentOutOfRangeException();\n            }\n        }\n\n        public static bool Is64BitPlatform() => IntPtr.Size == 8;\n\n        internal static IntPtr GetCurrentAffinity() => Process.GetCurrentProcess().TryGetAffinity() ?? default;\n\n        internal static string GetConfiguration()\n        {\n            var isDebug = Assembly.GetEntryAssembly().IsDebug();\n            if (isDebug.HasValue == false)\n            {\n                return Unknown;\n            }\n            return isDebug.Value ? DebugConfigurationName : ReleaseConfigurationName;\n        }\n\n        internal static ICollection<Antivirus> GetAntivirusProducts()\n        {\n            var products = new List<Antivirus>();\n            if (OsDetector.IsWindows())\n            {\n                try\n                {\n                    using (var wmi = new ManagementObjectSearcher(@\"root\\SecurityCenter2\", \"SELECT * FROM AntiVirusProduct\"))\n                    using (var data = wmi.Get())\n                        foreach (var o in data)\n                        {\n                            var av = (ManagementObject)o;\n                            if (av != null)\n                            {\n                                string name = av[\"displayName\"].ToString()!;\n                                string path = av[\"pathToSignedProductExe\"].ToString()!;\n                                products.Add(new Antivirus(name, path));\n                            }\n                        }\n                }\n                catch\n                {\n                    // Never mind\n                }\n            }\n\n            return products;\n        }\n\n        internal static VirtualMachineHypervisor? GetVirtualMachineHypervisor()\n        {\n            VirtualMachineHypervisor[] hypervisors = [HyperV.Default, VirtualBox.Default, VMware.Default];\n\n            if (OsDetector.IsWindows())\n            {\n                try\n                {\n                    using (var searcher = new ManagementObjectSearcher(\"Select * from Win32_ComputerSystem\"))\n                    {\n                        using (var items = searcher.Get())\n                        {\n                            foreach (var item in items)\n                            {\n                                string manufacturer = item[\"Manufacturer\"]?.ToString()!;\n                                string model = item[\"Model\"]?.ToString()!;\n                                return hypervisors.FirstOrDefault(x => x.IsVirtualMachine(manufacturer, model));\n                            }\n                        }\n                    }\n                }\n                catch\n                {\n                    // Never mind\n                }\n            }\n\n            return null;\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Portability/StringExtensions.cs",
    "content": "﻿using System;\n\nnamespace BenchmarkDotNet.Portability\n{\n    internal static class StringExtensions\n    {\n        internal static bool EqualsWithIgnoreCase(this string left, string right) => left != null && left.Equals(right, StringComparison.InvariantCultureIgnoreCase);\n\n        internal static bool ContainsWithIgnoreCase(this string text, string word) => text != null && text.IndexOf(word, StringComparison.InvariantCultureIgnoreCase) >= 0;\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Portability/VMware.cs",
    "content": "namespace BenchmarkDotNet.Portability\n{\n    public class VMware : VirtualMachineHypervisor\n    {\n        public static VMware Default { get; } = new VMware();\n\n        private VMware() { }\n\n        public override string Name => \"VMware\";\n\n        public override bool IsVirtualMachine(string manufacturer, string model)\n        {\n            return ContainsVmIdentifier(model, \"vmware\");\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Portability/VirtualBox.cs",
    "content": "namespace BenchmarkDotNet.Portability\n{\n    public class VirtualBox : VirtualMachineHypervisor\n    {\n        public static VirtualBox Default { get; } = new VirtualBox();\n\n        private VirtualBox() { }\n\n        public override string Name => \"VirtualBox\";\n\n        public override bool IsVirtualMachine(string manufacturer, string model)\n        {\n            return ContainsVmIdentifier(model, \"virtualbox\");\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Portability/VirtualMachineHypervisor.cs",
    "content": "namespace BenchmarkDotNet.Portability\n{\n    public abstract class VirtualMachineHypervisor\n    {\n        public abstract string Name { get; }\n\n        public abstract bool IsVirtualMachine(string manufacturer, string model);\n\n        protected static bool ContainsVmIdentifier(string systemInformation, string vmIdentifier)\n        {\n            return systemInformation != null && systemInformation.ContainsWithIgnoreCase(vmIdentifier);\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Properties/AssemblyInfo.cs",
    "content": "﻿using System;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\nusing BenchmarkDotNet.Properties;\n\n[assembly: Guid(\"cbba82d3-e650-407f-a0f0-767891d4f04c\")]\n\n[assembly: CLSCompliant(true)]\n\n[assembly: InternalsVisibleTo(\"BenchmarkDotNet.Tests,PublicKey=\" + BenchmarkDotNetInfo.PublicKey)]\n[assembly: InternalsVisibleTo(\"BenchmarkDotNet.IntegrationTests,PublicKey=\" + BenchmarkDotNetInfo.PublicKey)]\n[assembly: InternalsVisibleTo(\"BenchmarkDotNet.Diagnostics.Windows,PublicKey=\" + BenchmarkDotNetInfo.PublicKey)]\n[assembly: InternalsVisibleTo(\"BenchmarkDotNet.Diagnostics.dotTrace,PublicKey=\" + BenchmarkDotNetInfo.PublicKey)]\n[assembly: InternalsVisibleTo(\"BenchmarkDotNet.Diagnostics.dotMemory,PublicKey=\" + BenchmarkDotNetInfo.PublicKey)]\n[assembly: InternalsVisibleTo(\"BenchmarkDotNet.Disassembler,PublicKey=\" + BenchmarkDotNetInfo.PublicKey)]\n[assembly: InternalsVisibleTo(\"BenchmarkDotNet.IntegrationTests.ManualRunning,PublicKey=\" + BenchmarkDotNetInfo.PublicKey)]\n[assembly: InternalsVisibleTo(\"BenchmarkDotNet.IntegrationTests.ManualRunning.MultipleFrameworks,PublicKey=\" + BenchmarkDotNetInfo.PublicKey)]\n[assembly: InternalsVisibleTo(\"BenchmarkDotNet.TestAdapter,PublicKey=\" + BenchmarkDotNetInfo.PublicKey)]\n"
  },
  {
    "path": "src/BenchmarkDotNet/Properties/BenchmarkDotNetInfo.cs",
    "content": "﻿using System;\nusing System.Reflection;\nusing BenchmarkDotNet.Extensions;\nusing Perfolizer.Models;\n\nnamespace BenchmarkDotNet.Properties\n{\n    public class BenchmarkDotNetInfo\n    {\n        public const string BenchmarkDotNetCaption = \"BenchmarkDotNet\";\n\n        private static readonly Lazy<BenchmarkDotNetInfo> LazyInstance = new(() =>\n        {\n            var assembly = typeof(BenchmarkDotNetInfo).GetTypeInfo().Assembly;\n            var assemblyVersion = assembly.GetName().Version!;\n            string informationVersion = assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>()!.InformationalVersion ?? \"\";\n            return new BenchmarkDotNetInfo(assemblyVersion, RemoveVersionMetadata(informationVersion));\n        });\n\n        public static BenchmarkDotNetInfo Instance { get; } = LazyInstance.Value;\n\n        public EngineInfo GetBdnEngineInfo() => new()\n        {\n            Name = BenchmarkDotNetCaption,\n            Version = BrandVersion\n        };\n\n        public Version AssemblyVersion { get; }\n        public string FullVersion { get; }\n\n        public bool IsDevelop { get; }\n        public bool IsNightly { get; }\n        public bool IsRelease { get; }\n\n        public string BrandTitle { get; }\n        public string BrandVersion { get; }\n\n        public BenchmarkDotNetInfo(Version assemblyVersion, string fullVersion)\n        {\n            AssemblyVersion = assemblyVersion;\n            FullVersion = fullVersion;\n\n            string versionPrefix = AssemblyVersion.Revision > 0\n                ? AssemblyVersion.ToString()\n                : AssemblyVersion.ToString(3);\n            if (!FullVersion.StartsWith(versionPrefix))\n                throw new ArgumentException($\"Inconsistent versions: '{assemblyVersion}' and '{fullVersion}'\");\n            string versionSuffix = FullVersion.Substring(versionPrefix.Length).TrimStart('-');\n\n            IsDevelop = versionSuffix.StartsWith(\"develop\");\n            IsNightly = AssemblyVersion.Revision > 0;\n            IsRelease = versionSuffix.IsEmpty() && AssemblyVersion.Revision <= 0;\n\n            string brandVersionSuffix = IsDevelop\n                ? \" (\" + DateTime.Now.ToString(\"yyyy-MM-dd\") + \")\"\n                : \"\";\n            BrandVersion = FullVersion + brandVersionSuffix;\n            BrandTitle = \"BenchmarkDotNet v\" + BrandVersion;\n        }\n\n        internal static string RemoveVersionMetadata(string version)\n        {\n            int index = version.IndexOf('+');\n            return index >= 0 ? version.Substring(0, index) : version;\n        }\n\n        internal const string PublicKey =\n            \"00240000048000009400000006020000002400005253413100040000010001002970bbdfca4d12\" +\n            \"9fc74b4845b239973f1b183684f0d7db5e1de7e085917e3656cf94884803cb800d85d5aae5838f\" +\n            \"b3f8fd1f2829e8208c4f087afcfe970bce44037ba30a66749cd5514b410ca8a35e9c7d6eb86975\" +\n            \"853c834c9ad25051537f9a05a0c540c5d84f2c7b32ab01619d84367fd424797ba3242f08b0e6ae\" +\n            \"75f66dad\";\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Reports/BaseliningStrategy.cs",
    "content": "using System.Collections.Immutable;\nusing System.Linq;\nusing BenchmarkDotNet.Running;\n\nnamespace BenchmarkDotNet.Reports\n{\n    internal class BaseliningStrategy\n    {\n        private static readonly BaseliningStrategy Disabled = new BaseliningStrategy(false, false);\n        private static readonly BaseliningStrategy DescriptorOnly = new BaseliningStrategy(true, false);\n        private static readonly BaseliningStrategy JobOnly = new BaseliningStrategy(false, true);\n        private static readonly BaseliningStrategy DescriptorAndJob = new BaseliningStrategy(true, true);\n\n        private readonly bool useDescriptors, useJobs;\n\n        public BaseliningStrategy(bool useDescriptors, bool useJobs)\n        {\n            this.useDescriptors = useDescriptors;\n            this.useJobs = useJobs;\n        }\n\n        public static BaseliningStrategy Create(ImmutableArray<BenchmarkCase> benchmarkCases)\n        {\n            bool hasDescriptorBaselines = benchmarkCases.Any(b => b.Descriptor.Baseline);\n            bool hasJobBaselines = benchmarkCases.Any(b => b.Job.Meta.Baseline);\n            if (hasDescriptorBaselines && hasJobBaselines)\n                return DescriptorAndJob;\n            if (hasDescriptorBaselines)\n                return DescriptorOnly;\n            if (hasJobBaselines)\n                return JobOnly;\n            return Disabled;\n        }\n\n        public bool IsBaseline(BenchmarkCase benchmark)\n        {\n            if (!useDescriptors && !useJobs)\n                return false;\n            bool result = true;\n            if (useDescriptors)\n                result &= benchmark.Descriptor.Baseline;\n            if (useJobs)\n                result &= benchmark.Job.Meta.Baseline;\n            return result;\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Reports/BenchmarkReport.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Collections.Immutable;\nusing System.Linq;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Exporters;\nusing BenchmarkDotNet.Models;\nusing BenchmarkDotNet.Mathematics;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Toolchains.Results;\nusing JetBrains.Annotations;\nusing Perfolizer.Horology;\nusing Perfolizer.Models;\n\nnamespace BenchmarkDotNet.Reports\n{\n    public sealed class BenchmarkReport\n    {\n        public BenchmarkCase BenchmarkCase { get; }\n        public IReadOnlyList<Measurement> AllMeasurements { get; }\n        public GcStats GcStats { get; }\n        [PublicAPI] public bool Success { get; }\n        [PublicAPI] public GenerateResult GenerateResult { get; }\n        [PublicAPI] public BuildResult BuildResult { get; }\n        [PublicAPI] public IReadOnlyDictionary<string, Metric> Metrics { get; }\n\n        public IReadOnlyList<ExecuteResult> ExecuteResults { get; }\n\n        public Statistics? ResultStatistics => resultStatistics ??=\n            GetResultRuns().Any()\n                ? new Statistics(GetResultRuns().Select(r => r.GetAverageTime().Nanoseconds))\n                : null;\n\n        private Statistics? resultStatistics = null;\n\n        public BenchmarkReport(\n            bool success,\n            BenchmarkCase benchmarkCase,\n            GenerateResult generateResult,\n            BuildResult buildResult,\n            IReadOnlyList<ExecuteResult>? executeResults,\n            IReadOnlyList<Metric>? metrics)\n        {\n            Success = success;\n            BenchmarkCase = benchmarkCase;\n            GenerateResult = generateResult;\n            BuildResult = buildResult;\n            ExecuteResults = executeResults ?? [];\n            AllMeasurements = ExecuteResults.SelectMany((results, index) => results.Measurements).ToArray();\n            GcStats = ExecuteResults.Count > 0 ? ExecuteResults[ExecuteResults.Count - 1].GcStats : default;\n            Metrics = metrics?.ToDictionary(metric => metric.Descriptor.Id) ?? [];\n        }\n\n        public override string ToString() => $\"{BenchmarkCase.DisplayInfo}, {AllMeasurements.Count} runs\";\n\n        public IReadOnlyList<Measurement> GetResultRuns() => AllMeasurements.Where(r => r.Is(IterationMode.Workload, IterationStage.Result)).ToList();\n\n        internal EntryInfo ToPerfonar()\n        {\n            var entry = new EntryInfo\n            {\n                Benchmark = new BdnBenchmark\n                {\n                    Display = BenchmarkCase.DisplayInfo,\n                    Namespace = BenchmarkCase.Descriptor.Type.Namespace ?? \"\",\n                    Type = FullNameProvider.GetTypeName(BenchmarkCase.Descriptor.Type),\n                    Method = BenchmarkCase.Descriptor.WorkloadMethod.Name,\n                    Parameters = BenchmarkCase.Parameters.PrintInfo,\n                    HardwareIntrinsics = this.GetHardwareIntrinsicsInfo()\n                },\n                Job = new JobInfo\n                {\n                    Environment = BenchmarkCase.Job.Environment.ToPerfonar(),\n                    Execution = BenchmarkCase.Job.Run.ToPerfonar()\n                }\n            };\n\n            var lifecycles = AllMeasurements.GroupBy(m => new BdnLifecycle\n            {\n                LaunchIndex = m.LaunchIndex,\n                IterationMode = m.IterationMode,\n                IterationStage = m.IterationStage\n            }).OrderBy(x => x.Key).ToList();\n            foreach (var lifecycleGroup in lifecycles)\n            {\n                var measurementsEntry = new EntryInfo\n                {\n                    Lifecycle = lifecycleGroup.Key\n                };\n\n                foreach (var measurement in lifecycleGroup.ToList())\n                {\n                    measurementsEntry.Add(new EntryInfo\n                    {\n                        IterationIndex = measurement.IterationIndex,\n                        InvocationCount = measurement.Operations,\n                        Value = measurement.Nanoseconds / measurement.Operations,\n                        Unit = TimeUnit.Nanosecond\n                    });\n                }\n                entry.Add(measurementsEntry);\n            }\n\n            return entry;\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Reports/BenchmarkReportExtensions.cs",
    "content": "﻿using System.Linq;\nusing BenchmarkDotNet.Environments;\n\nnamespace BenchmarkDotNet.Reports\n{\n    public static class BenchmarkReportExtensions\n    {\n        private const string DisplayedRuntimeInfoPrefix = \"// \" + BenchmarkEnvironmentInfo.RuntimeInfoPrefix;\n        private const string DisplayedGcInfoPrefix = \"// \" + BenchmarkEnvironmentInfo.GcInfoPrefix;\n        private const string DisplayedHardwareIntrinsicsPrefix = \"// \" + BenchmarkEnvironmentInfo.HardwareIntrinsicsPrefix;\n\n        public static string? GetRuntimeInfo(this BenchmarkReport report) => report.GetInfoFromOutput(DisplayedRuntimeInfoPrefix);\n\n        public static string? GetGcInfo(this BenchmarkReport report) => report.GetInfoFromOutput(DisplayedGcInfoPrefix);\n\n        public static string? GetHardwareIntrinsicsInfo(this BenchmarkReport report) => report.GetInfoFromOutput(DisplayedHardwareIntrinsicsPrefix);\n\n        private static string? GetInfoFromOutput(this BenchmarkReport report, string prefix)\n        {\n            return (\n                from executeResults in report.ExecuteResults\n                from extraOutputLine in executeResults.PrefixedLines.Where(line => line.StartsWith(prefix))\n                select extraOutputLine.Substring(prefix.Length)).FirstOrDefault();\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Reports/DisplayPrecisionManager.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing BenchmarkDotNet.Columns;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Mathematics;\n\nnamespace BenchmarkDotNet.Reports\n{\n    internal class DisplayPrecisionManager\n    {\n        private const int MinPrecision = 1;\n        private const int MaxPrecision = 4;\n\n        private readonly IDictionary<string, int> precision = new Dictionary<string, int>();\n        private readonly Summary summary;\n\n        public DisplayPrecisionManager(Summary summary) => this.summary = summary;\n\n        /// <summary>\n        /// Returns the best amount of decimal digits for the given column.\n        /// </summary>\n        public int GetPrecision(SummaryStyle summaryStyle, IStatisticColumn column, IStatisticColumn? parentColumn = null)\n        {\n            if (!precision.ContainsKey(column.Id))\n            {\n                var values = column.GetAllValues(summary, summaryStyle);\n                precision[column.Id] = parentColumn != null\n                    ? CalcPrecision(values, GetPrecision(summaryStyle, parentColumn))\n                    : CalcPrecision(values);\n            }\n\n            return precision[column.Id];\n        }\n\n        internal static int CalcPrecision(IList<double> values)\n        {\n            if (values.IsEmpty())\n                return MinPrecision;\n\n            bool allValuesAreZeros = values.All(v => Math.Abs(v) < 1e-9);\n            if (allValuesAreZeros)\n                return MinPrecision;\n\n            double minValue = values.Any() ? values.Min(v => Math.Abs(v)) : 0;\n            if (double.IsNaN(minValue) || double.IsInfinity(minValue))\n                return MinPrecision;\n            if (minValue < 1 - 1e-9)\n                return MaxPrecision;\n            return MathHelper.Clamp((int) Math.Truncate(-Math.Log10(minValue)) + 3, MinPrecision, MaxPrecision);\n        }\n\n        internal static int CalcPrecision(IList<double> values, int parentPrecision)\n        {\n            return MathHelper.Clamp(CalcPrecision(values), parentPrecision, parentPrecision + 1);\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Reports/Measurement.cs",
    "content": "﻿using System;\n#if DEBUG\nusing System.Diagnostics;\n#endif\nusing System.Globalization;\nusing System.Linq;\nusing System.Text;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Helpers;\nusing Perfolizer.Horology;\n\nnamespace BenchmarkDotNet.Reports\n{\n    /// <summary>\n    /// The basic captured statistics for a benchmark\n    /// </summary>\n    public struct Measurement : IComparable<Measurement>\n    {\n        // We always use the same CultureInfo to simplify string conversions (ToString and Parse)\n        private static readonly CultureInfo MainCultureInfo = DefaultCultureInfo.Instance;\n\n        private const string NsSymbol = \"ns\";\n        private const string OpSymbol = \"op\";\n\n        private static Measurement Error() => new Measurement(-1, IterationMode.Unknown, IterationStage.Unknown, 0, 0, 0);\n\n        private static readonly int IterationInfoNameMaxWidth\n            = Enum.GetNames<IterationMode>().Max(text => text.Length) + Enum.GetNames<IterationStage>().Max(text => text.Length);\n\n        public IterationMode IterationMode { get; }\n\n        public IterationStage IterationStage { get; }\n\n        public int LaunchIndex { get; }\n\n        public int IterationIndex { get; }\n\n        /// <summary>\n        /// Gets the number of operations performed.\n        /// </summary>\n        public long Operations { get; }\n\n        /// <summary>\n        /// Gets the total number of nanoseconds it took to perform all operations.\n        /// </summary>\n        public double Nanoseconds { get; }\n\n        /// <summary>\n        /// Creates an instance of <see cref=\"Measurement\"/> struct.\n        /// </summary>\n        /// <param name=\"launchIndex\"></param>\n        /// <param name=\"iterationMode\"></param>\n        /// <param name=\"iterationStage\"></param>\n        /// <param name=\"iterationIndex\"></param>\n        /// <param name=\"operations\">The number of operations performed.</param>\n        /// <param name=\"nanoseconds\">The total number of nanoseconds it took to perform all operations.</param>\n        public Measurement(int launchIndex, IterationMode iterationMode, IterationStage iterationStage, int iterationIndex, long operations, double nanoseconds)\n        {\n            Operations = operations;\n            Nanoseconds = nanoseconds;\n            LaunchIndex = launchIndex;\n            IterationMode = iterationMode;\n            IterationStage = iterationStage;\n            IterationIndex = iterationIndex;\n        }\n\n        private static IterationMode ParseIterationMode(string name) => Enum.TryParse(name, out IterationMode mode) ? mode : IterationMode.Unknown;\n\n        private static IterationStage ParseIterationStage(string name) => Enum.TryParse(name, out IterationStage stage) ? stage : IterationStage.Unknown;\n\n        /// <summary>\n        /// Gets the average duration of one operation.\n        /// </summary>\n        public TimeInterval GetAverageTime() => TimeInterval.FromNanoseconds(Nanoseconds / Operations);\n\n        public int CompareTo(Measurement other) => Nanoseconds.CompareTo(other.Nanoseconds);\n\n        public override string ToString()\n        {\n            var builder = new StringBuilder();\n\n            builder.Append((IterationMode.ToString() + IterationStage).PadRight(IterationInfoNameMaxWidth, ' '));\n            builder.Append(' ');\n\n            // Usually, a benchmarks takes more than 10 iterations (rarely more than 99)\n            // PadLeft(2, ' ') looks like a good trade-off between alignment and amount of characters\n            builder.Append(IterationIndex.ToString(MainCultureInfo).PadLeft(2, ' '));\n            builder.Append(\": \");\n\n            builder.Append(Operations.ToString(MainCultureInfo));\n            builder.Append(' ');\n            builder.Append(OpSymbol);\n            builder.Append(\", \");\n\n            builder.Append(Nanoseconds.ToString(\"0.00\", MainCultureInfo));\n            builder.Append(' ');\n            builder.Append(NsSymbol);\n            builder.Append(\", \");\n\n            builder.Append(GetAverageTime().ToDefaultString(\"0.0000\").ToAscii());\n            builder.Append(\"/op\");\n\n            return builder.ToString();\n        }\n\n        /// <summary>\n        /// Parses the benchmark statistics from the plain text line.\n        ///\n        /// E.g. given the input <paramref name=\"line\"/>:\n        ///\n        ///     WorkloadTarget 1: 10 op, 1005842518 ns\n        ///\n        /// Will extract the number of <see cref=\"Operations\"/> performed and the\n        /// total number of <see cref=\"Nanoseconds\"/> it took to perform them.\n        /// </summary>\n        /// <param name=\"line\">The line to parse.</param>\n        /// <param name=\"processIndex\">Process launch index, indexed from one.</param>\n        /// <returns>An instance of <see cref=\"Measurement\"/> if parsed successfully. <c>Null</c> in case of any trouble.</returns>\n        // ReSharper disable once UnusedParameter.Global\n        public static Measurement Parse(string line, int processIndex)\n        {\n            if (line.IsBlank() || line.StartsWith(GcStats.ResultsLinePrefix))\n                return Error();\n\n            try\n            {\n                var lineSplit = line.Split([':'], StringSplitOptions.RemoveEmptyEntries);\n\n                string iterationInfo = lineSplit[0];\n                var iterationInfoSplit = iterationInfo.Split([' '], StringSplitOptions.RemoveEmptyEntries);\n                int iterationStageIndex = 0;\n                for (int i = 1; i < iterationInfoSplit[0].Length; i++)\n                    if (char.IsUpper(iterationInfoSplit[0][i]))\n                    {\n                        iterationStageIndex = i;\n                        break;\n                    }\n\n                string iterationModeStr = iterationInfoSplit[0].Substring(0, iterationStageIndex);\n                string iterationStageStr = iterationInfoSplit[0].Substring(iterationStageIndex);\n\n                var iterationMode = ParseIterationMode(iterationModeStr);\n                var iterationStage = ParseIterationStage(iterationStageStr);\n                int.TryParse(iterationInfoSplit[1], out int iterationIndex);\n\n                string measurementsInfo = lineSplit[1];\n                var measurementsInfoSplit = measurementsInfo.Split([','], StringSplitOptions.RemoveEmptyEntries);\n                long op = 1L;\n                double ns = double.PositiveInfinity;\n                foreach (string item in measurementsInfoSplit)\n                {\n                    var measurementSplit = item.Split([' '], StringSplitOptions.RemoveEmptyEntries);\n                    string value = measurementSplit[0];\n                    string unit = measurementSplit[1];\n                    switch (unit)\n                    {\n                        case NsSymbol:\n                            ns = double.Parse(value, MainCultureInfo);\n                            break;\n                        case OpSymbol:\n                            op = long.Parse(value, MainCultureInfo);\n                            break;\n                    }\n                }\n                return new Measurement(processIndex, iterationMode, iterationStage, iterationIndex, op, ns);\n            }\n            catch (Exception)\n            {\n#if DEBUG // some benchmarks need to write to console and when we display this error it's confusing\n                Debug.WriteLine(\"Parse error in the following line:\");\n                Debug.WriteLine(line);\n#endif\n                return Error();\n            }\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Reports/MeasurementExtensions.cs",
    "content": "﻿using BenchmarkDotNet.Engines;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Reports\n{\n    public static class MeasurementExtensions\n    {\n        private const int NanosecondsInSecond = 1000 * 1000 * 1000;\n\n        /// <summary>\n        /// Gets the number of operations performed per second (ops/sec).\n        /// </summary>\n        public static double GetOpsPerSecond(this Measurement report) =>\n            report.Operations / (report.Nanoseconds / NanosecondsInSecond);\n\n        public static bool Is(this Measurement measurement, IterationMode mode, IterationStage stage)\n            => measurement.IterationMode == mode && measurement.IterationStage == stage;\n\n        [PublicAPI] public static bool IsOverhead(this Measurement measurement) => measurement.IterationMode == IterationMode.Overhead;\n        [PublicAPI] public static bool IsWorkload(this Measurement measurement) => measurement.IterationMode == IterationMode.Workload;\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Reports/Metric.cs",
    "content": "﻿using BenchmarkDotNet.Columns;\nusing JetBrains.Annotations;\nusing System;\nusing System.Collections.Generic;\n\nnamespace BenchmarkDotNet.Reports\n{\n    public class Metric\n    {\n        public double Value { get; }\n\n        public IMetricDescriptor Descriptor { get; }\n\n        public Metric(IMetricDescriptor descriptor, double value)\n        {\n            Descriptor = descriptor;\n            Value = value;\n        }\n    }\n\n    public interface IMetricDescriptor\n    {\n        [PublicAPI] string Id { get; }\n\n        [PublicAPI] string DisplayName { get; }\n\n        [PublicAPI] string Legend { get; }\n\n        [PublicAPI] string NumberFormat { get; }\n\n        [PublicAPI] UnitType UnitType { get; }\n\n        [PublicAPI] string Unit { get; }\n\n        [PublicAPI] bool TheGreaterTheBetter { get; }\n\n        [PublicAPI] int PriorityInCategory { get; }\n\n        [PublicAPI] bool GetIsAvailable(Metric metric);\n    }\n\n    public class MetricDescriptorEqualityComparer : EqualityComparer<IMetricDescriptor>\n    {\n        public static readonly EqualityComparer<IMetricDescriptor> Instance = new MetricDescriptorEqualityComparer();\n\n        public override bool Equals(IMetricDescriptor? x, IMetricDescriptor? y)\n        {\n            if (ReferenceEquals(x, y))\n                return true;\n\n            if (x is null || y is null)\n                return false;\n\n            return string.Equals(x.Id, y.Id, StringComparison.Ordinal);\n        }\n\n        public override int GetHashCode(IMetricDescriptor obj) => obj.Id.GetHashCode();\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Reports/Summary.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Collections.Immutable;\nusing System.Diagnostics.CodeAnalysis;\nusing System.Globalization;\nusing System.Linq;\nusing BenchmarkDotNet.Columns;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Helpers;\nusing BenchmarkDotNet.Order;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Validators;\nusing JetBrains.Annotations;\nusing Perfolizer.Horology;\nusing Perfolizer.Models;\nusing Perfolizer.Perfonar.Tables;\n\nnamespace BenchmarkDotNet.Reports\n{\n    public class Summary\n    {\n        [PublicAPI] public string Title { get; }\n        [PublicAPI] public string ResultsDirectoryPath { get; }\n        [PublicAPI] public string LogFilePath { get; }\n        [PublicAPI] public HostEnvironmentInfo HostEnvironmentInfo { get; }\n        [PublicAPI] public TimeSpan TotalTime { get; }\n        [PublicAPI] public SummaryStyle Style { get; }\n        [PublicAPI] public IOrderer Orderer { get; }\n        [PublicAPI] public SummaryTable Table { get; }\n        [PublicAPI] public string AllRuntimes { get; }\n        [PublicAPI] public ImmutableArray<ValidationError> ValidationErrors { get; }\n        [PublicAPI] public ImmutableArray<IColumnHidingRule> ColumnHidingRules { get; }\n\n        [PublicAPI] public ImmutableArray<BenchmarkCase> BenchmarksCases { get; }\n        [PublicAPI] public ImmutableArray<BenchmarkReport> Reports { get; }\n\n        internal DisplayPrecisionManager DisplayPrecisionManager { get; }\n\n        private ImmutableDictionary<BenchmarkCase, BenchmarkReport> ReportMap { get; }\n        private BaseliningStrategy BaseliningStrategy { get; }\n        private bool? isMultipleRuntimes;\n\n        public Summary(\n            string title,\n            ImmutableArray<BenchmarkReport> reports,\n            HostEnvironmentInfo hostEnvironmentInfo,\n            string resultsDirectoryPath,\n            string logFilePath,\n            TimeSpan totalTime,\n            CultureInfo cultureInfo,\n            ImmutableArray<ValidationError> validationErrors,\n            ImmutableArray<IColumnHidingRule> columnHidingRules,\n            SummaryStyle? summaryStyle = null)\n        {\n            Title = title;\n            ResultsDirectoryPath = resultsDirectoryPath;\n            LogFilePath = logFilePath;\n            HostEnvironmentInfo = hostEnvironmentInfo;\n            TotalTime = totalTime;\n            ValidationErrors = validationErrors;\n            ColumnHidingRules = columnHidingRules;\n\n            ReportMap = reports.ToImmutableDictionary(report => report.BenchmarkCase, report => report);\n\n            DisplayPrecisionManager = new DisplayPrecisionManager(this);\n            Orderer = GetConfiguredOrdererOrDefaultOne(reports.Select(report => report.BenchmarkCase.Config));\n            BenchmarksCases =\n                Orderer.GetSummaryOrder(reports.Select(report => report.BenchmarkCase).ToImmutableArray(), this).ToImmutableArray(); // we sort it first\n            Reports = BenchmarksCases.Select(b => ReportMap[b]).ToImmutableArray(); // we use sorted collection to re-create reports list\n            BaseliningStrategy = BaseliningStrategy.Create(BenchmarksCases);\n            Style = (summaryStyle ?? GetConfiguredSummaryStyleOrDefaultOne(BenchmarksCases)).WithCultureInfo(cultureInfo);\n            Table = GetTable(Style);\n            AllRuntimes = BuildAllRuntimes(HostEnvironmentInfo, Reports);\n        }\n\n        [PublicAPI] public bool HasReport(BenchmarkCase benchmarkCase) => ReportMap.ContainsKey(benchmarkCase);\n\n        /// <summary>\n        /// Returns a report for the given benchmark or null if there is no a corresponded report.\n        /// </summary>\n        public BenchmarkReport? this[BenchmarkCase benchmarkCase] => ReportMap.GetValueOrDefault(benchmarkCase);\n\n        public bool HasCriticalValidationErrors => ValidationErrors.Any(validationError => validationError.IsCritical);\n\n        public int GetNumberOfExecutedBenchmarks() => Reports.Count(report => report.ExecuteResults.Any(result => result.FoundExecutable));\n\n        public bool IsMultipleRuntimes\n            => isMultipleRuntimes ??= BenchmarksCases.Length > 1 ? BenchmarksCases.Select(benchmark => benchmark.GetRuntime()).Distinct().Count() > 1 : false;\n\n        internal static Summary ValidationFailed(string title, string resultsDirectoryPath, string logFilePath,\n            ImmutableArray<ValidationError>? validationErrors = null)\n            => new Summary(title, [], HostEnvironmentInfo.GetCurrent(), resultsDirectoryPath, logFilePath, TimeSpan.Zero,\n                DefaultCultureInfo.Instance, validationErrors ?? [], []);\n\n        internal static Summary Join(List<Summary> summaries, ClockSpan clockSpan)\n            => new Summary(\n                $\"BenchmarkRun-joined-{DateTime.Now:yyyy-MM-dd-HH-mm-ss}\",\n                summaries.SelectMany(summary => summary.Reports).ToImmutableArray(),\n                HostEnvironmentInfo.GetCurrent(),\n                summaries.First().ResultsDirectoryPath,\n                summaries.First().LogFilePath,\n                clockSpan.GetTimeSpan(),\n                summaries.First().GetCultureInfo(),\n                summaries.SelectMany(summary => summary.ValidationErrors).ToImmutableArray(),\n                summaries.SelectMany(summary => summary.ColumnHidingRules).ToImmutableArray());\n\n        internal static string BuildAllRuntimes(HostEnvironmentInfo hostEnvironmentInfo, IEnumerable<BenchmarkReport> reports)\n        {\n            var jobRuntimes = new Dictionary<string, string>(); // JobId -> Runtime\n            var orderedJobs = new List<string> { \"[Host]\" };\n\n            jobRuntimes[\"[Host]\"] = hostEnvironmentInfo.GetRuntimeInfo();\n\n            foreach (var benchmarkReport in reports)\n            {\n                string? runtime = benchmarkReport.GetRuntimeInfo();\n                if (runtime != null)\n                {\n                    string jobId = benchmarkReport.BenchmarkCase.Job.ResolvedId;\n\n                    if (!jobRuntimes.ContainsKey(jobId))\n                    {\n                        orderedJobs.Add(jobId);\n                        jobRuntimes[jobId] = runtime;\n                    }\n                }\n            }\n\n            int jobIdMaxWidth = orderedJobs.Max(j => j.ToString().Length);\n\n            var lines = orderedJobs.Select(jobId => $\"  {jobId.PadRight(jobIdMaxWidth)} : {jobRuntimes[jobId]}\");\n            return string.Join(Environment.NewLine, lines);\n        }\n\n        internal SummaryTable GetTable(SummaryStyle style) => new SummaryTable(this, style);\n\n        public string? GetLogicalGroupKey(BenchmarkCase benchmarkCase)\n            => Orderer.GetLogicalGroupKey(BenchmarksCases, benchmarkCase);\n\n        public bool IsBaseline(BenchmarkCase benchmarkCase)\n            => BaseliningStrategy.IsBaseline(benchmarkCase);\n\n        public BenchmarkCase? GetBaseline(string? logicalGroupKey)\n            => BenchmarksCases\n                .Where(b => GetLogicalGroupKey(b) == logicalGroupKey)\n                .FirstOrDefault(IsBaseline);\n\n        public IEnumerable<BenchmarkCase> GetNonBaselines(string? logicalGroupKey)\n            => BenchmarksCases\n                .Where(b => GetLogicalGroupKey(b) == logicalGroupKey)\n                .Where(b => !IsBaseline(b));\n\n        public bool HasBaselines() => BenchmarksCases.Any(IsBaseline);\n\n        private static IOrderer GetConfiguredOrdererOrDefaultOne(IEnumerable<ImmutableConfig> configs)\n            => configs\n                   .Where(config => config.Orderer != DefaultOrderer.Instance)\n                   .Select(config => config.Orderer)\n                   .Distinct()\n                   .FirstOrDefault()\n               ?? DefaultOrderer.Instance;\n\n        private static SummaryStyle GetConfiguredSummaryStyleOrDefaultOne(ImmutableArray<BenchmarkCase> benchmarkCases)\n            => benchmarkCases\n                   .Where(benchmark => benchmark.Config.SummaryStyle != SummaryStyle.Default)\n                   .Select(benchmark => benchmark.Config.SummaryStyle)\n                   .Distinct()\n                   .FirstOrDefault()\n               ?? SummaryStyle.Default;\n\n        internal PerfonarTableConfig GetDefaultTableConfig()\n        {\n            return new PerfonarTableConfig\n            {\n                ColumnDefinitions =\n                [\n                    new PerfonarColumnDefinition(\".engine\") { Cloud = \"primary\", IsSelfExplanatory = true, IsAtomic = true },\n                    new PerfonarColumnDefinition(\".host.os\") { Cloud = \"primary\", IsSelfExplanatory = true, IsAtomic = true },\n                    new PerfonarColumnDefinition(\".host.cpu\") { Cloud = \"primary\", IsSelfExplanatory = true, IsAtomic = true },\n                    new PerfonarColumnDefinition(\".benchmark\") { Cloud = \"secondary\" },\n                    new PerfonarColumnDefinition(\".job\") { Cloud = \"secondary\", Compressed = true },\n                    new PerfonarColumnDefinition(\"=center\"),\n                    new PerfonarColumnDefinition(\"=spread\")\n                ]\n            };\n        }\n\n        // TODO: GcStats\n        internal EntryInfo ToPerfonar()\n        {\n            var root = new EntryInfo\n            {\n                Engine = new EngineInfo\n                {\n                    Name = HostEnvironmentInfo.BenchmarkDotNetCaption,\n                    Version = HostEnvironmentInfo.BenchmarkDotNetVersion,\n                },\n                Host = HostEnvironmentInfo.ToPerfonar(),\n            };\n            foreach (var benchmarkReport in Reports)\n                root.Add(benchmarkReport.ToPerfonar());\n            return root;\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Reports/SummaryExtensions.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Globalization;\nusing System.Linq;\nusing BenchmarkDotNet.Columns;\nusing BenchmarkDotNet.Helpers;\nusing BenchmarkDotNet.Running;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Reports\n{\n    public static class SummaryExtensions\n    {\n        public static IColumn[] GetColumns(this Summary summary)\n            => summary\n                .BenchmarksCases\n                .SelectMany(benchmark => benchmark.Config.GetColumnProviders())\n                .Distinct()\n                .SelectMany(provider => provider.GetColumns(summary))\n                .Where(column => column.IsAvailable(summary))\n                .GroupBy(column => column.Id)\n                .Select(group => group.First())\n                .OrderBy(column => column.Category)\n                .ThenBy(column => column.PriorityInCategory)\n                .ToArray();\n\n        public static IEnumerable<BenchmarkCase> GetLogicalGroupForBenchmark(this Summary summary, BenchmarkCase benchmarkCase)\n        {\n            string? logicalGroupKey = summary.GetLogicalGroupKey(benchmarkCase);\n            return summary.BenchmarksCases.Where(b => summary.GetLogicalGroupKey(b) == logicalGroupKey);\n        }\n\n        [Pure]\n        public static CultureInfo GetCultureInfo(this Summary? summary) => summary?.Style?.CultureInfo ?? DefaultCultureInfo.Instance;\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Reports/SummaryStyle.cs",
    "content": "﻿using System;\nusing System.Globalization;\nusing BenchmarkDotNet.Columns;\nusing BenchmarkDotNet.Helpers;\nusing Perfolizer.Horology;\nusing Perfolizer.Metrology;\nusing static BenchmarkDotNet.Reports.SummaryTable.SummaryTableColumn;\n\n// ReSharper disable MemberCanBePrivate.Global\n\nnamespace BenchmarkDotNet.Reports\n{\n    public class SummaryStyle : IEquatable<SummaryStyle>\n    {\n        public static readonly SummaryStyle Default = new SummaryStyle(DefaultCultureInfo.Instance, printUnitsInHeader: false, printUnitsInContent: true,\n            printZeroValuesInContent: false, sizeUnit: null, timeUnit: null);\n\n        internal const int DefaultMaxParameterColumnWidth = 15 + 5; // 5 is for postfix \" [15]\"\n\n        public bool PrintUnitsInHeader { get; }\n        public bool PrintUnitsInContent { get; }\n        public bool PrintZeroValuesInContent { get; }\n        public int MaxParameterColumnWidth { get; }\n        public SizeUnit? SizeUnit { get; }\n        internal SizeUnit CodeSizeUnit { get; }\n        public TimeUnit? TimeUnit { get; }\n        public CultureInfo CultureInfo { get; }\n\n        public RatioStyle RatioStyle { get; }\n\n        public TextJustification TextColumnJustification { get; }\n        public TextJustification NumericColumnJustification { get; }\n\n        public SummaryStyle(CultureInfo? cultureInfo, bool printUnitsInHeader, SizeUnit? sizeUnit, TimeUnit? timeUnit, bool printUnitsInContent = true,\n            bool printZeroValuesInContent = false, int maxParameterColumnWidth = DefaultMaxParameterColumnWidth, RatioStyle ratioStyle = RatioStyle.Value,\n            TextJustification textColumnJustification = TextJustification.Left, TextJustification numericColumnJustification = TextJustification.Right)\n        {\n            if (maxParameterColumnWidth < DefaultMaxParameterColumnWidth)\n                throw new ArgumentOutOfRangeException(nameof(maxParameterColumnWidth), $\"{DefaultMaxParameterColumnWidth} is the minimum.\");\n\n            CultureInfo = cultureInfo ?? DefaultCultureInfo.Instance;\n            PrintUnitsInHeader = printUnitsInHeader;\n            PrintUnitsInContent = printUnitsInContent;\n            SizeUnit = sizeUnit;\n            TimeUnit = timeUnit;\n            MaxParameterColumnWidth = maxParameterColumnWidth;\n            RatioStyle = ratioStyle;\n            CodeSizeUnit = SizeUnit.B;\n            PrintZeroValuesInContent = printZeroValuesInContent;\n            TextColumnJustification = textColumnJustification;\n            NumericColumnJustification = numericColumnJustification;\n        }\n\n        public SummaryStyle WithTimeUnit(TimeUnit timeUnit)\n            => new SummaryStyle(CultureInfo, PrintUnitsInHeader, SizeUnit, timeUnit, PrintUnitsInContent, PrintZeroValuesInContent, MaxParameterColumnWidth,\n                RatioStyle, TextColumnJustification, NumericColumnJustification);\n\n        public SummaryStyle WithSizeUnit(SizeUnit sizeUnit)\n            => new SummaryStyle(CultureInfo, PrintUnitsInHeader, sizeUnit, TimeUnit, PrintUnitsInContent, PrintZeroValuesInContent, MaxParameterColumnWidth,\n                RatioStyle, TextColumnJustification, NumericColumnJustification);\n\n        public SummaryStyle WithZeroMetricValuesInContent()\n            => new SummaryStyle(CultureInfo, PrintUnitsInHeader, SizeUnit, TimeUnit, PrintUnitsInContent, printZeroValuesInContent: true,\n                MaxParameterColumnWidth, RatioStyle, TextColumnJustification, NumericColumnJustification);\n\n        public SummaryStyle WithMaxParameterColumnWidth(int maxParameterColumnWidth)\n            => new SummaryStyle(CultureInfo, PrintUnitsInHeader, SizeUnit, TimeUnit, PrintUnitsInContent, PrintZeroValuesInContent, maxParameterColumnWidth,\n                RatioStyle, TextColumnJustification, NumericColumnJustification);\n\n        public SummaryStyle WithCultureInfo(CultureInfo cultureInfo)\n            => new SummaryStyle(cultureInfo, PrintUnitsInHeader, SizeUnit, TimeUnit, PrintUnitsInContent, PrintZeroValuesInContent, MaxParameterColumnWidth,\n                RatioStyle, TextColumnJustification, NumericColumnJustification);\n\n        public SummaryStyle WithRatioStyle(RatioStyle ratioStyle)\n            => new SummaryStyle(CultureInfo, PrintUnitsInHeader, SizeUnit, TimeUnit, PrintUnitsInContent, PrintZeroValuesInContent, MaxParameterColumnWidth,\n                ratioStyle, TextColumnJustification, NumericColumnJustification);\n\n        public bool Equals(SummaryStyle? other)\n        {\n            if (other is null)\n                return false;\n            if (ReferenceEquals(this, other))\n                return true;\n            return Equals(CultureInfo, other.CultureInfo)\n                   && PrintUnitsInHeader == other.PrintUnitsInHeader\n                   && PrintUnitsInContent == other.PrintUnitsInContent\n                   && PrintZeroValuesInContent == other.PrintZeroValuesInContent\n                   && Equals(SizeUnit, other.SizeUnit)\n                   && Equals(CodeSizeUnit, other.CodeSizeUnit)\n                   && Equals(TimeUnit, other.TimeUnit)\n                   && MaxParameterColumnWidth == other.MaxParameterColumnWidth\n                   && RatioStyle == other.RatioStyle\n                   && TextColumnJustification == other.TextColumnJustification\n                   && NumericColumnJustification == other.NumericColumnJustification;\n        }\n\n        public override bool Equals(object? obj) => obj is SummaryStyle summary && Equals(summary);\n\n        public override int GetHashCode() =>\n            HashCode.Combine(\n                PrintUnitsInHeader,\n                PrintUnitsInContent,\n                PrintZeroValuesInContent,\n                SizeUnit,\n                CodeSizeUnit,\n                TimeUnit,\n                MaxParameterColumnWidth,\n                RatioStyle,\n                TextColumnJustification,\n                NumericColumnJustification);\n\n        public static bool operator ==(SummaryStyle? left, SummaryStyle? right) => Equals(left, right);\n\n        public static bool operator !=(SummaryStyle? left, SummaryStyle? right) => !Equals(left, right);\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Reports/SummaryTable.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing BenchmarkDotNet.Columns;\nusing BenchmarkDotNet.Extensions;\nusing JetBrains.Annotations;\nusing Perfolizer.Horology;\nusing Perfolizer.Metrology;\n\nnamespace BenchmarkDotNet.Reports\n{\n    public class SummaryTable\n    {\n        [PublicAPI] public Summary Summary { get; }\n\n        public SummaryTableColumn[] Columns { get; }\n        public int ColumnCount { get; }\n\n        public string[] FullHeader { get; }\n        public string[][] FullContent { get; }\n        public bool[] FullContentStartOfHighlightGroup { get; }\n        public bool[] FullContentStartOfLogicalGroup { get; }\n        public string[][] FullContentWithHeader { get; }\n        [PublicAPI] public bool[] IsDefault { get; }\n        public SummaryStyle EffectiveSummaryStyle { get; }\n        public bool SeparateLogicalGroups { get; }\n\n        internal SummaryTable(Summary summary, SummaryStyle? style = null)\n        {\n            Summary = summary;\n\n            if (summary.HasCriticalValidationErrors)\n            {\n                Columns = [];\n                ColumnCount = 0;\n                FullHeader = [];\n                FullContent = [];\n                FullContentStartOfHighlightGroup = [];\n                FullContentStartOfLogicalGroup = [];\n                FullContentWithHeader = [];\n                IsDefault = [];\n                EffectiveSummaryStyle = summary.Style;\n                return;\n            }\n\n            // Ensure we have all required data for styling\n            style = style ?? summary.Style;\n            if (style.TimeUnit == null)\n            {\n                style = style.WithTimeUnit(TimeUnit.GetBestTimeUnit(summary.Reports.Where(r => r.ResultStatistics != null).Select(r => r.ResultStatistics!.Mean)\n                    .ToArray()));\n            }\n\n            if (style.SizeUnit == null)\n            {\n                style = style.WithSizeUnit(SizeUnit.GetBestSizeUnit(summary.Reports\n                    .Where(r => r.GcStats.GetBytesAllocatedPerOperation(r.BenchmarkCase).HasValue)\n                    .Select(r => r.GcStats.GetBytesAllocatedPerOperation(r.BenchmarkCase)!.Value)\n                    .ToArray()));\n            }\n            EffectiveSummaryStyle = style!;\n\n            var columns = summary.GetColumns();\n            ColumnCount = columns.Length;\n            FullHeader = columns.Select(c => c.GetColumnTitle(style)).ToArray();\n\n            FullContent = summary.Reports.Select(r => columns.Select(c => c.GetValue(summary, r.BenchmarkCase, style)).ToArray()).ToArray();\n            IsDefault = columns.Select(c => summary.Reports.All(r => c.IsDefault(summary, r.BenchmarkCase))).ToArray();\n\n            var highlightGroupKeys = summary.BenchmarksCases.Select(b => b.Config.Orderer.GetHighlightGroupKey(b)).ToArray();\n            FullContentStartOfHighlightGroup = new bool[summary.Reports.Length];\n            if (highlightGroupKeys.Distinct().Count() > 1 && FullContentStartOfHighlightGroup.Length > 0)\n            {\n                FullContentStartOfHighlightGroup[0] = true;\n                for (int i = 1; i < summary.Reports.Length; i++)\n                    FullContentStartOfHighlightGroup[i] = highlightGroupKeys[i] != highlightGroupKeys[i - 1];\n            }\n\n            var logicalGroupKeys = summary.BenchmarksCases\n                .Select(b => b.Config.Orderer.GetLogicalGroupKey(summary.BenchmarksCases, b))\n                .ToArray();\n            FullContentStartOfLogicalGroup = new bool[summary.Reports.Length];\n            if (logicalGroupKeys.Distinct().Count() > 1 && FullContentStartOfLogicalGroup.Length > 0)\n            {\n                FullContentStartOfLogicalGroup[0] = true;\n                for (int i = 1; i < summary.Reports.Length; i++)\n                    FullContentStartOfLogicalGroup[i] = logicalGroupKeys[i] != logicalGroupKeys[i - 1];\n            }\n\n            SeparateLogicalGroups = summary.Orderer.SeparateLogicalGroups;\n\n            var full = new List<string[]> { FullHeader };\n            full.AddRange(FullContent);\n            FullContentWithHeader = full.ToArray();\n\n            Columns = new SummaryTableColumn[columns.Length];\n            for (int i = 0; i < columns.Length; i++)\n            {\n                var column = columns[i];\n                bool hide = summary.ColumnHidingRules.Any(rule => rule.NeedToHide(column));\n                Columns[i] = new SummaryTableColumn(this, i, column, hide);\n            }\n        }\n\n        public class SummaryTableColumn\n        {\n            [PublicAPI] public int Index { get; }\n            public string Header { get; }\n            public string[] Content { get; }\n            public bool NeedToShow { get; }\n            public int Width { get; }\n            public bool IsDefault { get; }\n            public TextJustification Justify { get; }\n            public IColumn OriginalColumn { get; }\n\n            internal bool IsCommon { get; }\n            internal bool WasHidden { get; }\n\n            public SummaryTableColumn(SummaryTable table, int index, IColumn column, bool hide = false)\n            {\n                Index = index;\n                Header = table.FullHeader[index];\n                Content = table.FullContent.Select(line => line[index]).ToArray();\n                Width = Math.Max(Header.Length, Content.Any() ? Content.Max(line => line.Length) : 0) + 1;\n                IsDefault = table.IsDefault[index];\n                OriginalColumn = column;\n\n                Justify = column.IsNumeric ? table.EffectiveSummaryStyle.NumericColumnJustification : table.EffectiveSummaryStyle.TextColumnJustification;\n\n                bool needToShow = column.AlwaysShow || Content.Distinct().Count() > 1;\n                NeedToShow = !hide && needToShow;\n                WasHidden = hide && needToShow;\n\n                bool isCommon = !NeedToShow && !IsDefault;\n                IsCommon = (!hide && isCommon) || (hide && Content.Distinct().Count() == 1);\n            }\n\n            public override string ToString() => Header;\n\n            public enum TextJustification\n            {\n                Left,\n                Right\n            }\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Reports/SummaryTableExtensions.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing System.Runtime.CompilerServices;\nusing System.Text;\nusing BenchmarkDotNet.Exporters;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Loggers;\n\nnamespace BenchmarkDotNet.Reports\n{\n    public static class SummaryTableExtensions\n    {\n        [ThreadStatic]\n        private static StringBuilder? sharedBuffer;\n\n        public static void PrintCommonColumns(this SummaryTable table, ILogger logger)\n        {\n            var commonColumns = table.Columns.Where(c => c.IsCommon).ToArray();\n            if (commonColumns.Any())\n            {\n                int paramsOnLine = 0;\n                foreach (var column in commonColumns)\n                {\n                    logger.WriteInfo($\"{column.Header}={column.Content[0]}  \");\n                    paramsOnLine++;\n                    if (paramsOnLine == 3)\n                    {\n                        logger.WriteLine();\n                        paramsOnLine = 0;\n                    }\n                }\n                if (paramsOnLine != 0)\n                    logger.WriteLine();\n            }\n        }\n\n        public static void PrintLine(this SummaryTable table, string[] line, ILogger logger, string leftDel, string rightDel)\n        {\n            for (int columnIndex = 0; columnIndex < table.ColumnCount; columnIndex++)\n            {\n                if (table.Columns[columnIndex].NeedToShow)\n                {\n                    logger.WriteStatistic(BuildStandardText(table, line, leftDel, rightDel, columnIndex));\n                }\n            }\n\n            logger.WriteLine();\n        }\n\n        public static void PrintLine(this SummaryTable table, string[] line, ILogger logger, string leftDel, string rightDel,\n            bool highlightRow, bool startOfGroup, MarkdownExporter.MarkdownHighlightStrategy startOfGroupHighlightStrategy, string boldMarkupFormat,\n            bool escapeHtml)\n        {\n            for (int columnIndex = 0; columnIndex < table.ColumnCount; columnIndex++)\n            {\n                if (!table.Columns[columnIndex].NeedToShow)\n                {\n                    continue;\n                }\n\n                string text = startOfGroup && startOfGroupHighlightStrategy == MarkdownExporter.MarkdownHighlightStrategy.Bold\n                    ? BuildBoldText(table, line, leftDel, rightDel, columnIndex, boldMarkupFormat)\n                    : BuildStandardText(table, line, leftDel, rightDel, columnIndex);\n                if (escapeHtml)\n                    text = text.HtmlEncode();\n\n                if (highlightRow) // write the row in an alternative color\n                {\n                    logger.WriteHeader(text);\n                }\n                else\n                {\n                    logger.WriteStatistic(text);\n                }\n            }\n\n            if (startOfGroup && startOfGroupHighlightStrategy == MarkdownExporter.MarkdownHighlightStrategy.Marker)\n                logger.Write(highlightRow ? LogKind.Header : LogKind.Statistic, \" ^\"); //\n\n            logger.WriteLine();\n        }\n\n        private static string BuildStandardText(SummaryTable table, string[] line, string leftDel, string rightDel, int columnIndex)\n        {\n            var buffer = GetClearBuffer();\n            var isBuildingHeader = table.FullHeader[columnIndex] == line[columnIndex];\n            var columnJustification = isBuildingHeader ? SummaryTable.SummaryTableColumn.TextJustification.Left : table.Columns[columnIndex].Justify;\n\n            buffer.Append(leftDel);\n            if (columnJustification == SummaryTable.SummaryTableColumn.TextJustification.Right)\n            {\n                AddPadding(table, line, leftDel, rightDel, columnIndex, buffer);\n            }\n\n            buffer.Append(line[columnIndex]);\n\n            if (columnJustification == SummaryTable.SummaryTableColumn.TextJustification.Left)\n            {\n                AddPadding(table, line, leftDel, rightDel, columnIndex, buffer);\n            }\n            var isLastColumn = columnIndex == table.ColumnCount - 1;\n            buffer.Append(isLastColumn ? rightDel.TrimEnd() : rightDel);\n\n            return buffer.ToString();\n        }\n\n        private static string BuildBoldText(SummaryTable table, string[] line, string leftDel, string rightDel, int columnIndex, string boldMarkupFormat)\n        {\n            var buffer = GetClearBuffer();\n            var isBuildingHeader = table.FullHeader[columnIndex] == line[columnIndex];\n            var columnJustification = isBuildingHeader ? SummaryTable.SummaryTableColumn.TextJustification.Left : table.Columns[columnIndex].Justify;\n\n            buffer.Append(leftDel);\n            if (columnJustification == SummaryTable.SummaryTableColumn.TextJustification.Right)\n            {\n                AddPadding(table, line, leftDel, rightDel, columnIndex, buffer);\n            }\n\n            buffer.AppendFormat(boldMarkupFormat, line[columnIndex]);\n\n            if (columnJustification == SummaryTable.SummaryTableColumn.TextJustification.Left)\n            {\n                AddPadding(table, line, leftDel, rightDel, columnIndex, buffer);\n            }\n            var isLastColumn = columnIndex == table.ColumnCount - 1;\n            buffer.Append(isLastColumn ? rightDel.TrimEnd() : rightDel);\n\n            return buffer.ToString();\n        }\n\n        private static StringBuilder GetClearBuffer()\n        {\n            if (sharedBuffer == null)\n            {\n                return sharedBuffer = new StringBuilder(28);\n            }\n\n            sharedBuffer.Clear();\n\n            return sharedBuffer;\n        }\n\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        private static void AddPadding(SummaryTable table, string[] line, string leftDel, string rightDel, int columnIndex, StringBuilder buffer)\n        {\n            const char space = ' ';\n            const int extraWidth = 2; // \" |\".Length is not included in the column's Width\n\n            int repeatCount = table.Columns[columnIndex].Width + extraWidth - leftDel.Length - line[columnIndex].Length - rightDel.Length;\n            if (repeatCount > 0)\n            {\n                buffer.Append(space, repeatCount);\n            }\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Running/BenchmarkBuildInfo.cs",
    "content": "﻿using BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Diagnosers;\n\nnamespace BenchmarkDotNet.Running\n{\n    public class BenchmarkBuildInfo\n    {\n        public BenchmarkBuildInfo(BenchmarkCase benchmarkCase, ImmutableConfig config, int id, CompositeInProcessDiagnoser compositeInProcessDiagnoser)\n        {\n            BenchmarkCase = benchmarkCase;\n            Config = config;\n            Id = new BenchmarkId(id, benchmarkCase);\n            CompositeInProcessDiagnoser = compositeInProcessDiagnoser;\n        }\n\n        public BenchmarkCase BenchmarkCase { get; }\n\n        public ImmutableConfig Config { get; }\n\n        public BenchmarkId Id { get; }\n\n        public CompositeInProcessDiagnoser CompositeInProcessDiagnoser { get; }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Running/BenchmarkCase.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Parameters;\nusing BenchmarkDotNet.Portability;\n\nnamespace BenchmarkDotNet.Running\n{\n    public class BenchmarkCase : IComparable<BenchmarkCase>, IDisposable\n    {\n        public Descriptor Descriptor { get; }\n        public Job Job { get; }\n        public ParameterInstances Parameters { get; }\n        public ImmutableConfig Config { get; }\n\n        public string FolderInfo => (Descriptor.FolderInfo + \"_\" + Job.FolderInfo + \"_\" + Parameters.FolderInfo).Trim('_');\n        public string DisplayInfo => (Descriptor.DisplayInfo + \": \" + Job.DisplayInfo + \" \" + Parameters.DisplayInfo).Trim(' ');\n\n        public override string ToString() => DisplayInfo;\n\n        internal BenchmarkCase(Descriptor descriptor, Job job, ParameterInstances parameters, ImmutableConfig config)\n        {\n            Descriptor = descriptor;\n            Job = job;\n            Parameters = parameters ?? ParameterInstances.Empty;\n            Config = config;\n        }\n\n        public Runtime GetRuntime() => Job.Environment.HasValue(EnvironmentMode.RuntimeCharacteristic)\n                ? Job.Environment.Runtime!\n                : RuntimeInformation.GetTargetOrCurrentRuntime(Descriptor.WorkloadMethod.DeclaringType!.Assembly);\n\n        public void Dispose() => Parameters.Dispose();\n\n        public int CompareTo(BenchmarkCase? other)\n        {\n            if (ReferenceEquals(this, other)) return 0;\n            if (other is null) return 1;\n\n            return string.Compare(FolderInfo, other.FolderInfo, StringComparison.Ordinal);\n        }\n\n        public bool HasParameters => Parameters != null && Parameters.Items.Any();\n\n        public bool HasArguments => Parameters != null && Parameters.Items.Any(parameter => parameter.IsArgument);\n\n        public static BenchmarkCase Create(Descriptor descriptor, Job job, ParameterInstances parameters, ImmutableConfig config)\n            => new BenchmarkCase(descriptor, job.MakeSettingsUserFriendly(descriptor), parameters, config);\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Running/BenchmarkConverter.cs",
    "content": "﻿using System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Collections.Immutable;\nusing System.Linq;\nusing System.Reflection;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Code;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Filters;\nusing BenchmarkDotNet.Parameters;\nusing BenchmarkDotNet.Reports;\n\nnamespace BenchmarkDotNet.Running\n{\n    public static class BenchmarkConverter\n    {\n        private const BindingFlags AllMethodsFlags = BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;\n\n        public static BenchmarkRunInfo TypeToBenchmarks(Type type, IConfig? config = null)\n        {\n            if (type.IsGenericTypeDefinition)\n                throw new InvalidBenchmarkDeclarationException($\"{type.Name} is generic type definition, use BenchmarkSwitcher for it\"); // for \"open generic types\" should be used BenchmarkSwitcher\n\n            // We should check all methods including private to notify users about private methods with the [Benchmark] attribute\n            var benchmarkMethods = GetOrderedBenchmarkMethods(type.GetMethods(AllMethodsFlags));\n\n            return MethodsToBenchmarksWithFullConfig(type, benchmarkMethods, config);\n        }\n\n        public static BenchmarkRunInfo MethodsToBenchmarks(Type containingType, MethodInfo[] benchmarkMethods, IConfig? config = null)\n            => MethodsToBenchmarksWithFullConfig(containingType, GetOrderedBenchmarkMethods(benchmarkMethods), config);\n\n        private static MethodInfo[] GetOrderedBenchmarkMethods(MethodInfo[] methods)\n            => methods\n                .Select(method => (method, attribute: method.ResolveAttribute<BenchmarkAttribute>()))\n                .Where(pair => pair.attribute is not null)\n                .OrderBy(pair => pair.attribute!.SourceCodeFile)\n                .ThenBy(pair => pair.attribute!.SourceCodeLineNumber)\n                .Select(pair => pair.method)\n                .ToArray();\n\n        private static BenchmarkRunInfo MethodsToBenchmarksWithFullConfig(Type type, MethodInfo[] benchmarkMethods, IConfig? config)\n        {\n            var allMethods = type.GetMethods(AllMethodsFlags); // benchmarkMethods can be filtered, without Setups, look #564\n            var configPerType = GetFullTypeConfig(type, config);\n\n            var globalSetupMethods = GetAttributedMethods<GlobalSetupAttribute>(allMethods, \"GlobalSetup\");\n            var globalCleanupMethods = GetAttributedMethods<GlobalCleanupAttribute>(allMethods, \"GlobalCleanup\");\n            var iterationSetupMethods = GetAttributedMethods<IterationSetupAttribute>(allMethods, \"IterationSetup\");\n            var iterationCleanupMethods = GetAttributedMethods<IterationCleanupAttribute>(allMethods, \"IterationCleanup\");\n\n            var targets = GetTargets(benchmarkMethods, type, globalSetupMethods, globalCleanupMethods, iterationSetupMethods, iterationCleanupMethods,\n                configPerType).ToArray();\n\n            var parameterDefinitions = GetParameterDefinitions(type);\n            var parameterInstancesList = parameterDefinitions.Expand(configPerType.SummaryStyle);\n\n            var benchmarks = new List<BenchmarkCase>();\n\n            bool containsBenchmarkDeclarations = false;\n\n            foreach (var target in targets)\n            {\n                var argumentsDefinitions = GetArgumentsDefinitions(target.WorkloadMethod, target.Type, configPerType.SummaryStyle).ToArray();\n\n                var parameterInstances =\n                    (from parameterInstance in parameterInstancesList\n                     from argumentDefinition in argumentsDefinitions\n                     select new ParameterInstances(parameterInstance.Items.Concat(argumentDefinition.Items).ToArray())).ToArray();\n\n                var configPerMethod = GetFullMethodConfig(target.WorkloadMethod, configPerType);\n\n                var benchmarksForTarget =\n                    from job in configPerMethod.GetJobs()\n                    from parameterInstance in parameterInstances\n                    select BenchmarkCase.Create(target, job, parameterInstance, configPerMethod);\n\n                if (benchmarksForTarget.Any() && !containsBenchmarkDeclarations) containsBenchmarkDeclarations = true;\n\n                benchmarks.AddRange(GetFilteredBenchmarks(benchmarksForTarget, configPerMethod.GetFilters()));\n            }\n\n            var orderedBenchmarks = configPerType.Orderer.GetExecutionOrder(benchmarks.ToImmutableArray()).ToArray();\n            var compositeInProcessDiagnoser = new Diagnosers.CompositeInProcessDiagnoser([.. configPerType.GetDiagnosers().OfType<Diagnosers.IInProcessDiagnoser>()]);\n\n            return new BenchmarkRunInfo(orderedBenchmarks, type, configPerType, containsBenchmarkDeclarations, compositeInProcessDiagnoser);\n        }\n\n        private static ImmutableConfig GetFullTypeConfig(Type type, IConfig? config)\n        {\n            config = config ?? DefaultConfig.Instance;\n\n            var typeAttributes = type.GetCustomAttributes(true).OfType<IConfigSource>();\n            var assemblyAttributes = type.Assembly.GetCustomAttributes().OfType<IConfigSource>();\n\n            foreach (var configFromAttribute in assemblyAttributes.Concat(typeAttributes))\n                config = ManualConfig.Union(config, configFromAttribute.Config);\n\n            return ImmutableConfigBuilder.Create(config);\n        }\n\n        private static ImmutableConfig GetFullMethodConfig(MethodInfo method, ImmutableConfig typeConfig)\n        {\n            var methodAttributes = method.GetCustomAttributes(true).OfType<IConfigSource>();\n\n            if (!methodAttributes.Any()) // the most common case\n                return typeConfig;\n\n            var config = ManualConfig.Create(typeConfig);\n            foreach (var configFromAttribute in methodAttributes)\n                config = ManualConfig.Union(config, configFromAttribute.Config);\n\n            return ImmutableConfigBuilder.Create(config);\n        }\n\n        private static IEnumerable<Descriptor> GetTargets(\n            MethodInfo[] targetMethods,\n            Type type,\n            Tuple<MethodInfo, TargetedAttribute>[] globalSetupMethods,\n            Tuple<MethodInfo, TargetedAttribute>[] globalCleanupMethods,\n            Tuple<MethodInfo, TargetedAttribute>[] iterationSetupMethods,\n            Tuple<MethodInfo, TargetedAttribute>[] iterationCleanupMethods,\n            IConfig config)\n        {\n            return targetMethods\n                .Select(methodInfo => CreateDescriptor(type,\n                                                   GetTargetedMatchingMethod(methodInfo, globalSetupMethods),\n                                                   methodInfo,\n                                                   GetTargetedMatchingMethod(methodInfo, globalCleanupMethods),\n                                                   GetTargetedMatchingMethod(methodInfo, iterationSetupMethods),\n                                                   GetTargetedMatchingMethod(methodInfo, iterationCleanupMethods),\n                                                   methodInfo.ResolveAttribute<BenchmarkAttribute>()!,\n                                                   targetMethods,\n                                                   config));\n        }\n\n        private static MethodInfo? GetTargetedMatchingMethod(MethodInfo benchmarkMethod, Tuple<MethodInfo, TargetedAttribute>[] methods)\n            => methods.Where(method => method.Item2.Match(benchmarkMethod)).Select(method => method.Item1).FirstOrDefault();\n\n        private static Tuple<MethodInfo, TargetedAttribute>[] GetAttributedMethods<T>(MethodInfo[] methods, string methodName) where T : TargetedAttribute\n        {\n            return methods.SelectMany(m => m.GetCustomAttributes<T>()\n                .Select(attr =>\n                {\n                    AssertMethodIsAccessible(methodName, m);\n                    AssertMethodHasCorrectSignature(methodName, m);\n                    AssertMethodIsNotGeneric(methodName, m);\n\n                    return new Tuple<MethodInfo, TargetedAttribute>(m, attr);\n                })).OrderByDescending(x => x.Item2.Targets?.Length ?? 0).ToArray();\n        }\n\n        private static Descriptor CreateDescriptor(\n            Type type,\n            MethodInfo? globalSetupMethod,\n            MethodInfo methodInfo,\n            MethodInfo? globalCleanupMethod,\n            MethodInfo? iterationSetupMethod,\n            MethodInfo? iterationCleanupMethod,\n            BenchmarkAttribute attr,\n            MethodInfo[] targetMethods,\n            IConfig config)\n        {\n            var categoryDiscoverer = config.CategoryDiscoverer ?? DefaultCategoryDiscoverer.Instance;\n            var target = new Descriptor(\n                type,\n                methodInfo,\n                globalSetupMethod,\n                globalCleanupMethod,\n                iterationSetupMethod,\n                iterationCleanupMethod,\n                attr.Description,\n                baseline: attr.Baseline,\n                categories: categoryDiscoverer.GetCategories(methodInfo),\n                operationsPerInvoke: attr.OperationsPerInvoke,\n                methodIndex: Array.IndexOf(targetMethods, methodInfo));\n            AssertMethodHasCorrectSignature(\"Benchmark\", methodInfo);\n            AssertMethodIsAccessible(\"Benchmark\", methodInfo);\n            AssertMethodIsNotGeneric(\"Benchmark\", methodInfo);\n            return target;\n        }\n\n        private static ParameterDefinitions GetParameterDefinitions(Type type)\n        {\n            IEnumerable<ParameterDefinition> GetDefinitions<TAttribute>(Func<TAttribute, Type, object?[]> getValidValues) where TAttribute : PriorityAttribute\n            {\n                const BindingFlags reflectionFlags = BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;\n\n                var allMembers = type.GetTypeMembersWithGivenAttribute<TAttribute>(reflectionFlags);\n                return allMembers.Select(member =>\n                    new ParameterDefinition(\n                        member.Name,\n                        member.IsStatic,\n                        getValidValues(member.Attribute, member.ParameterType),\n                        false,\n                        member.ParameterType,\n                        member.Attribute.Priority));\n            }\n\n            var paramsDefinitions = GetDefinitions<ParamsAttribute>((attribute, parameterType) => GetValidValues(attribute.Values, parameterType));\n\n            var paramsSourceDefinitions = GetDefinitions<ParamsSourceAttribute>((attribute, parameterType) =>\n            {\n                var targetType = attribute.Type ?? type;\n\n                var paramsValues = GetValidValuesForParamsSource(targetType, attribute.Name);\n                return SmartParamBuilder.CreateForParams(parameterType, paramsValues.source, paramsValues.values);\n            });\n\n            var paramsAllValuesDefinitions = GetDefinitions<ParamsAllValuesAttribute>((_, parameterType) => GetAllValidValues(parameterType));\n\n            var definitions = paramsDefinitions.Concat(paramsSourceDefinitions).Concat(paramsAllValuesDefinitions).ToArray();\n            return new ParameterDefinitions(definitions);\n        }\n\n        private static IEnumerable<ParameterInstances> GetArgumentsDefinitions(MethodInfo benchmark, Type benchmarkType, SummaryStyle summaryStyle)\n        {\n            var argumentsAttributes = benchmark.GetCustomAttributes<PriorityAttribute>();\n            int priority = argumentsAttributes.Select(attribute => attribute.Priority).Sum();\n\n            var parameterDefinitions = benchmark.GetParameters()\n                .Select(parameter => new ParameterDefinition(parameter.Name!, false, [], true, parameter.ParameterType, priority))\n                .ToArray();\n\n            if (parameterDefinitions.IsEmpty())\n            {\n                yield return new ParameterInstances([]);\n                yield break;\n            }\n\n            foreach (var argumentsAttribute in benchmark.GetCustomAttributes<ArgumentsAttribute>())\n            {\n                if (parameterDefinitions.Length != argumentsAttribute.Values.Length)\n                    throw new InvalidOperationException($\"Benchmark {benchmark.Name} has invalid number of defined arguments provided with [Arguments]! {argumentsAttribute.Values.Length} instead of {parameterDefinitions.Length}.\");\n\n                yield return new ParameterInstances(\n                    argumentsAttribute\n                        .Values\n                        .Select((value, index) =>\n                            {\n                                var definition = parameterDefinitions[index];\n                                var type = definition.ParameterType;\n                                return new ParameterInstance(definition, Map(value, type), summaryStyle);\n                            })\n                        .ToArray());\n            }\n\n            if (!benchmark.HasAttribute<ArgumentsSourceAttribute>())\n                yield break;\n\n            var argumentsSourceAttribute = benchmark.GetCustomAttribute<ArgumentsSourceAttribute>()!;\n            var targetType = argumentsSourceAttribute.Type ?? benchmarkType;\n\n            var valuesInfo = GetValidValuesForParamsSource(targetType, argumentsSourceAttribute.Name);\n            for (int sourceIndex = 0; sourceIndex < valuesInfo.values.Length; sourceIndex++)\n                yield return SmartParamBuilder.CreateForArguments(benchmark, parameterDefinitions, valuesInfo, sourceIndex, summaryStyle);\n        }\n\n        private static ImmutableArray<BenchmarkCase> GetFilteredBenchmarks(IEnumerable<BenchmarkCase> benchmarks, IEnumerable<IFilter> filters)\n            => benchmarks.Where(benchmark => filters.All(filter => filter.Predicate(benchmark))).ToImmutableArray();\n\n        private static void AssertMethodHasCorrectSignature(string methodType, MethodInfo methodInfo)\n        {\n            if (methodInfo.GetParameters().Any() && !methodInfo.HasAttribute<ArgumentsAttribute>() && !methodInfo.HasAttribute<ArgumentsSourceAttribute>())\n                throw new InvalidBenchmarkDeclarationException($\"{methodType} method {methodInfo.Name} has incorrect signature.\\nMethod shouldn't have any arguments.\");\n        }\n\n        private static void AssertMethodIsAccessible(string methodType, MethodInfo methodInfo)\n        {\n            if (!methodInfo.IsPublic)\n                throw new InvalidBenchmarkDeclarationException($\"{methodType} method {methodInfo.Name} has incorrect access modifiers.\\nMethod must be public.\");\n            /* Moved the code that verifies if DeclaringType of a given MethodInfo (a method) is publicly accessible to CompilationValidator */\n        }\n\n        private static void AssertMethodIsNotGeneric(string methodType, MethodInfo methodInfo)\n        {\n            if (methodInfo.IsGenericMethod)\n                throw new InvalidBenchmarkDeclarationException($\"{methodType} method {methodInfo.Name} is generic.\\nGeneric {methodType} methods are not supported.\");\n        }\n\n        private static object?[] GetValidValues(object?[] values, Type parameterType)\n            => values.Select(value => Map(value, parameterType)).ToArray();\n\n        private static object? Map(object? providedValue, Type type)\n        {\n            if (providedValue == null)\n                return null;\n\n            if (providedValue.GetType().IsArray)\n            {\n                return ArrayParam<IParam>.FromObject(providedValue);\n            }\n            // Usually providedValue contains all needed type information,\n            // but in case of F# enum types in attributes are erased.\n            // We can to restore them from types of arguments and fields.\n            // See also:\n            // https://github.com/dotnet/fsharp/issues/995\n            else if (providedValue.GetType().IsEnum || type.IsEnum)\n            {\n                return EnumParam.FromObject(providedValue, type);\n            }\n            return providedValue;\n        }\n\n        private static (MemberInfo source, object[] values) GetValidValuesForParamsSource(Type sourceType, string sourceName)\n        {\n            var paramsSourceMethod = sourceType.GetAllMethods().FirstOrDefault(method => method.Name == sourceName && method.IsPublic);\n\n            if (paramsSourceMethod != default)\n                return (paramsSourceMethod, ToArray(\n                    paramsSourceMethod.Invoke(paramsSourceMethod.IsStatic ? null : Activator.CreateInstance(sourceType), null)!,\n                    paramsSourceMethod,\n                    sourceType));\n\n            var paramsSourceProperty = sourceType.GetAllProperties().FirstOrDefault(property => property.Name == sourceName && property.GetMethod?.IsPublic == true);\n\n            if (paramsSourceProperty == null)\n                throw new InvalidBenchmarkDeclarationException($\"{sourceType.Name} has no public, accessible method/property called {sourceName}, unable to read values for [ParamsSource]\");\n\n            return (paramsSourceProperty, ToArray(\n                paramsSourceProperty.GetValue(paramsSourceProperty.GetMethod!.IsStatic ? null : Activator.CreateInstance(sourceType)!)!,\n                paramsSourceProperty,\n                sourceType));\n        }\n\n        private static object[] ToArray(object sourceValue, MemberInfo memberInfo, Type type)\n        {\n            if (!(sourceValue is IEnumerable collection))\n                throw new InvalidBenchmarkDeclarationException($\"{memberInfo.Name} of type {type.Name} does not implement IEnumerable, unable to read values for [ParamsSource]\");\n\n            return collection.Cast<object>().ToArray();\n        }\n\n        private static object?[] GetAllValidValues(Type parameterType)\n        {\n            if (parameterType == typeof(bool))\n                return [false, true];\n\n            if (parameterType.GetTypeInfo().IsEnum)\n            {\n                if (parameterType.GetTypeInfo().IsDefined(typeof(FlagsAttribute)))\n                    return [Activator.CreateInstance(parameterType)!];\n\n                return Enum.GetValues(parameterType).Cast<object>().ToArray();\n            }\n\n            var nullableUnderlyingType = Nullable.GetUnderlyingType(parameterType);\n            if (nullableUnderlyingType != null)\n                return new object?[] { null }.Concat(GetAllValidValues(nullableUnderlyingType)).ToArray();\n\n            return [Activator.CreateInstance(parameterType)!];\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Running/BenchmarkId.cs",
    "content": "﻿using System;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Exporters;\nusing BenchmarkDotNet.Extensions;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Running\n{\n    /// <summary>\n    /// represents an internal entity used to identify a benchmark within an executable with multiple benchmarks\n    /// </summary>\n    public struct BenchmarkId\n    {\n        public BenchmarkId(int value, BenchmarkCase benchmarkCase)\n        {\n            Value = value;\n            FullBenchmarkName = GetBenchmarkName(benchmarkCase);\n            JobId = benchmarkCase.Job.Id;\n        }\n\n        public int Value { get; }\n\n        private string JobId { get; }\n\n        private string FullBenchmarkName { get; }\n\n        [PublicAPI] public bool Equals(BenchmarkId other) => Value == other.Value;\n\n        public override bool Equals(object? obj) => throw new InvalidOperationException(\"boxing\");\n\n        public override int GetHashCode() => Value;\n\n        public string ToArguments(Diagnosers.RunMode diagnoserRunMode)\n            => $\"--benchmarkName {FullBenchmarkName.EscapeCommandLine()} --job {JobId.EscapeCommandLine()} --diagnoserRunMode {(int) diagnoserRunMode} --benchmarkId {Value}\";\n\n        public string ToArguments(string fromBenchmark, string toBenchmark, Diagnosers.RunMode diagnoserRunMode)\n            => $\"{AnonymousPipesHost.AnonymousPipesDescriptors} {fromBenchmark} {toBenchmark} {ToArguments(diagnoserRunMode)}\";\n\n        public override string ToString() => Value.ToString();\n\n        private static string GetBenchmarkName(BenchmarkCase benchmark)\n        {\n            var fullName = FullNameProvider.GetBenchmarkName(benchmark);\n\n            // FullBenchmarkName is passed to Process.Start as an argument and each OS limits the max argument length, so we have to limit it too\n            // Windows limit is 32767 chars, Unix is 128*1024 but we use 1024 as a common sense limit\n            if (fullName.Length < 1024)\n                return fullName;\n\n            string typeName = FullNameProvider.GetTypeName(benchmark.Descriptor.Type);\n            string methodName = benchmark.Descriptor.WorkloadMethod.Name;\n            string paramsHash = benchmark.HasParameters\n                ? \"paramsHash_\" + Hashing.HashString(FullNameProvider.GetMethodName(benchmark)).ToString()\n                : string.Empty;\n\n            return $\"{typeName}.{methodName}({paramsHash})\";\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Running/BenchmarkPartitioner.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing BenchmarkDotNet.Characteristics;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Toolchains;\n\nnamespace BenchmarkDotNet.Running\n{\n    public static class BenchmarkPartitioner\n    {\n        public static BuildPartition[] CreateForBuild(BenchmarkRunInfo[] supportedBenchmarks, IResolver resolver)\n            => supportedBenchmarks\n                .SelectMany(info => info.BenchmarksCases.Select(benchmark => (benchmark, benchmark.Config, info.CompositeInProcessDiagnoser)))\n                .GroupBy(tuple => tuple.benchmark, BenchmarkRuntimePropertiesComparer.Instance)\n                .Select(group => new BuildPartition([.. group.Select((item, index) => new BenchmarkBuildInfo(item.benchmark, item.Config, index, item.CompositeInProcessDiagnoser))], resolver))\n                .ToArray();\n\n        internal class BenchmarkRuntimePropertiesComparer : IEqualityComparer<BenchmarkCase>\n        {\n            internal static readonly IEqualityComparer<BenchmarkCase> Instance = new BenchmarkRuntimePropertiesComparer();\n\n            public bool Equals(BenchmarkCase? x, BenchmarkCase? y)\n            {\n                if (ReferenceEquals(x, y)) \n                    return true;\n\n                if (x is null || y is null) \n                    return false;\n\n                var jobX = x.Job;\n                var jobY = y.Job;\n\n                if (AreDifferent(x.GetRuntime(), y.GetRuntime())) // Mono vs .NET vs Core\n                    return false;\n                if (AreDifferent(x.GetToolchain(), y.GetToolchain())) // Mono vs .NET vs Core vs InProcess\n                    return false;\n                if (jobX.Environment.Jit != jobY.Environment.Jit) // Jit is set per exe in .config file\n                    return false;\n                if (jobX.Environment.Platform != jobY.Environment.Platform) // platform is set in .csproj\n                    return false;\n                if (jobX.Environment.LargeAddressAware != jobY.Environment.LargeAddressAware)\n                    return false;\n                if (AreDifferent(jobX.Infrastructure.BuildConfiguration, jobY.Infrastructure.BuildConfiguration)) // Debug vs Release\n                    return false;\n                if (AreDifferent(jobX.Infrastructure.Arguments, jobY.Infrastructure.Arguments)) // arguments can be anything (Mono runtime settings or MsBuild parameters)\n                    return false;\n                if (!jobX.Environment.Gc.Equals(jobY.Environment.Gc)) // GC settings are per .config/.csproj\n                    return false;\n\n                if (x.Descriptor.Type.Assembly.Location != y.Descriptor.Type.Assembly.Location) // some toolchains produce the exe in the same folder as .dll (to get some scenarios like native dependencies work)\n                    return false;\n\n                if (x.Descriptor.WorkloadMethod.GetCustomAttributes(false).OfType<STAThreadAttribute>().Count() !=\n                    y.Descriptor.WorkloadMethod.GetCustomAttributes(false).OfType<STAThreadAttribute>().Count()) // STA vs STA\n                    return false;\n\n                return true;\n            }\n\n            public int GetHashCode(BenchmarkCase obj)\n            {\n                var hashCode = new HashCode();\n                hashCode.Add(obj.GetToolchain());\n                hashCode.Add(obj.GetRuntime());\n                hashCode.Add(obj.Descriptor.Type.Assembly.Location);\n                hashCode.Add(obj.Descriptor.WorkloadMethod.GetCustomAttributes(false).OfType<STAThreadAttribute>().Any());\n                var job = obj.Job;\n                hashCode.Add(job.Environment.Jit);\n                hashCode.Add(job.Environment.Platform);\n                hashCode.Add(job.Environment.LargeAddressAware);\n                hashCode.Add(job.Environment.Gc);\n                hashCode.Add(job.Infrastructure.BuildConfiguration);\n                foreach (var arg in job.Infrastructure.Arguments ?? [])\n                    hashCode.Add(arg);\n                return hashCode.ToHashCode();\n            }\n\n            private static bool AreDifferent(object? x, object? y)\n                => !Equals(x, y);\n\n            private static bool AreDifferent(IReadOnlyList<Argument>? x, IReadOnlyList<Argument>? y)\n            {\n                if (ReferenceEquals(x, y)) \n                    return false;\n\n                if (x is null || y is null) \n                    return true;\n\n                return !x.SequenceEqual(y);\n            }\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Running/BenchmarkRunInfo.cs",
    "content": "﻿using System;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Diagnosers;\n\nnamespace BenchmarkDotNet.Running\n{\n    public class BenchmarkRunInfo(BenchmarkCase[] benchmarksCase, Type type, ImmutableConfig config, bool containsBenchmarkDeclarations, CompositeInProcessDiagnoser compositeInProcessDiagnoser) : IDisposable\n    {\n        public BenchmarkRunInfo(BenchmarkCase[] benchmarksCases, Type type, ImmutableConfig config, CompositeInProcessDiagnoser compositeInProcessDiagnoser)\n            : this(benchmarksCases, type, config, benchmarksCases.Length > 0, compositeInProcessDiagnoser) { }\n\n        public void Dispose()\n        {\n            foreach (var benchmarkCase in BenchmarksCases)\n            {\n                benchmarkCase.Dispose();\n            }\n        }\n\n        public BenchmarkCase[] BenchmarksCases { get; } = benchmarksCase;\n        public Type Type { get; } = type;\n        public ImmutableConfig Config { get; } = config;\n        public bool ContainsBenchmarkDeclarations { get; } = containsBenchmarkDeclarations;\n        public CompositeInProcessDiagnoser CompositeInProcessDiagnoser { get; } = compositeInProcessDiagnoser;\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Running/BenchmarkRunnerClean.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Collections.Immutable;\nusing System.IO;\nusing System.Linq;\nusing System.Text.RegularExpressions;\nusing BenchmarkDotNet.Analysers;\nusing BenchmarkDotNet.Characteristics;\nusing BenchmarkDotNet.Columns;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Detectors;\nusing BenchmarkDotNet.Diagnosers;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.EventProcessors;\nusing BenchmarkDotNet.Exporters;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Helpers;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Mathematics;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Toolchains;\nusing BenchmarkDotNet.Toolchains.DotNetCli;\nusing BenchmarkDotNet.Toolchains.Parameters;\nusing BenchmarkDotNet.Toolchains.Results;\nusing BenchmarkDotNet.Validators;\nusing Perfolizer.Horology;\nusing RunMode = BenchmarkDotNet.Jobs.RunMode;\n\nnamespace BenchmarkDotNet.Running\n{\n    internal static class BenchmarkRunnerClean\n    {\n        internal const string DateTimeFormat = \"yyyyMMdd-HHmmss\";\n\n        internal static readonly IResolver DefaultResolver = new CompositeResolver(EnvironmentResolver.Instance, InfrastructureResolver.Instance);\n\n        internal static Summary[] Run(BenchmarkRunInfo[] benchmarkRunInfos)\n        {\n            using var taskbarProgress = new TaskbarProgress(TaskbarProgressState.Indeterminate);\n\n            var resolver = DefaultResolver;\n            var artifactsToCleanup = new List<string>();\n\n            var rootArtifactsFolderPath = GetRootArtifactsFolderPath(benchmarkRunInfos);\n            var maxTitleLength = OsDetector.IsWindows()\n                ? 254 - rootArtifactsFolderPath.Length\n                : int.MaxValue;\n            var title = GetTitle(benchmarkRunInfos, maxTitleLength);\n            var resultsFolderPath = GetResultsFolderPath(rootArtifactsFolderPath, benchmarkRunInfos);\n            var logFilePath = Path.Combine(rootArtifactsFolderPath, title + \".log\");\n            var idToResume = GetIdToResume(rootArtifactsFolderPath, title, benchmarkRunInfos);\n\n            using (var streamLogger = new StreamLogger(GetLogFileStreamWriter(benchmarkRunInfos, logFilePath)))\n            {\n                var compositeLogger = CreateCompositeLogger(benchmarkRunInfos, streamLogger);\n                using var wakeLock = WakeLock.Request(WakeLock.GetWakeLockType(benchmarkRunInfos), \"BenchmarkDotNet Running Benchmarks\", streamLogger);\n                var eventProcessor = new CompositeEventProcessor(benchmarkRunInfos);\n\n                eventProcessor.OnStartValidationStage();\n\n                compositeLogger.WriteLineInfo(\"// Validating benchmarks:\");\n\n                var (supportedBenchmarks, validationErrors) = GetSupportedBenchmarks(benchmarkRunInfos, resolver);\n\n                validationErrors.AddRange(Validate(supportedBenchmarks));\n\n                foreach (var validationError in validationErrors)\n                    eventProcessor.OnValidationError(validationError);\n\n                PrintValidationErrors(compositeLogger, validationErrors);\n\n                eventProcessor.OnEndValidationStage(); // Ensure that OnEndValidationStage() is called when a critical validation error exists.\n\n                if (validationErrors.Any(validationError => validationError.IsCritical))\n                    return [Summary.ValidationFailed(title, resultsFolderPath, logFilePath, validationErrors.ToImmutableArray())];\n\n                int totalBenchmarkCount = supportedBenchmarks.Sum(benchmarkInfo => benchmarkInfo.BenchmarksCases.Length);\n                int benchmarksToRunCount = totalBenchmarkCount - (idToResume + 1); // ids are indexed from 0\n                compositeLogger.WriteLineHeader(\"// ***** BenchmarkRunner: Start   *****\");\n                compositeLogger.WriteLineHeader($\"// ***** Found {totalBenchmarkCount} benchmark(s) in total *****\");\n                var globalChronometer = Chronometer.Start();\n\n                var buildPartitions = BenchmarkPartitioner.CreateForBuild(supportedBenchmarks, resolver);\n                eventProcessor.OnStartBuildStage(buildPartitions);\n\n                var sequentialBuildPartitions = buildPartitions.Where(partition =>\n                        partition.Benchmarks.Any(x => x.Config.Options.IsSet(ConfigOptions.DisableParallelBuild))\n                        // .Net SDK 8+ supports ArtifactsPath for proper parallel builds.\n                        // Older SDKs may produce builds with incorrect bindings if more than 1 partition is built in parallel.\n                        || (partition.RepresentativeBenchmarkCase.GetToolchain().Generator is DotNetCliGenerator\n                            && partition.RepresentativeBenchmarkCase.GetRuntime().RuntimeMoniker.GetRuntimeVersion().Major < 8)\n                    )\n                    .ToArray();\n                var parallelBuildPartitions = buildPartitions.Except(sequentialBuildPartitions).ToArray();\n\n                var buildResults = new Dictionary<BuildPartition, BuildResult>();\n                if (parallelBuildPartitions.Length > 0)\n                {\n                    var results = BuildInParallel(compositeLogger, rootArtifactsFolderPath, parallelBuildPartitions, in globalChronometer, eventProcessor);\n                    foreach (var kvp in results)\n                    {\n                        buildResults.Add(kvp.Key, kvp.Value);\n                    }\n                }\n\n                if (sequentialBuildPartitions.Length > 0)\n                {\n                    var results = BuildSequential(compositeLogger, rootArtifactsFolderPath, sequentialBuildPartitions, in globalChronometer, eventProcessor);\n                    foreach (var kvp in results)\n                    {\n                        buildResults.Add(kvp.Key, kvp.Value);\n                    }\n                }\n\n                var allBuildsHaveFailed = buildResults.Values.All(buildResult => !buildResult.IsBuildSuccess);\n\n                eventProcessor.OnEndBuildStage();\n                eventProcessor.OnStartRunStage();\n\n                try\n                {\n                    var results = new List<Summary>();\n\n                    var benchmarkToBuildResult = buildResults\n                        .SelectMany(buildResult => buildResult.Key.Benchmarks.Select(buildInfo => (buildInfo.BenchmarkCase, buildInfo.Id, buildResult.Value)))\n                        .ToDictionary(info => info.BenchmarkCase, info => (info.Id, info.Value));\n\n                    // used to estimate finish time, in contrary to globalChronometer it does not include build time\n                    var runsChronometer = Chronometer.Start();\n\n                    foreach (var benchmarkRunInfo in supportedBenchmarks) // we run them in the old order now using the new build artifacts\n                    {\n                        if (idToResume >= 0)\n                        {\n                            var benchmarkWithHighestIdForGivenType = benchmarkRunInfo.BenchmarksCases.Last();\n                            if (benchmarkToBuildResult[benchmarkWithHighestIdForGivenType].Id.Value <= idToResume)\n                            {\n                                compositeLogger.WriteLineInfo($\"Skipping {benchmarkRunInfo.BenchmarksCases.Length} benchmark(s) defined by {benchmarkRunInfo.Type.GetCorrectCSharpTypeName(prefixWithGlobal: false)}.\");\n                                continue;\n                            }\n                        }\n\n                        eventProcessor.OnStartRunBenchmarksInType(benchmarkRunInfo.Type, benchmarkRunInfo.BenchmarksCases);\n                        var summary = Run(benchmarkRunInfo, benchmarkToBuildResult, resolver, compositeLogger, eventProcessor, artifactsToCleanup,\n                            resultsFolderPath, logFilePath, totalBenchmarkCount, in runsChronometer, ref benchmarksToRunCount,\n                            taskbarProgress);\n                        eventProcessor.OnEndRunBenchmarksInType(benchmarkRunInfo.Type, summary);\n\n                        if (!benchmarkRunInfo.Config.Options.IsSet(ConfigOptions.JoinSummary))\n                            PrintSummary(compositeLogger, benchmarkRunInfo.Config, summary);\n\n                        LogTotalTime(compositeLogger, summary.TotalTime, summary.GetNumberOfExecutedBenchmarks(), message: \"Run time\");\n                        compositeLogger.WriteLine();\n\n                        results.Add(summary);\n\n                        if ((benchmarkRunInfo.Config.Options.IsSet(ConfigOptions.StopOnFirstError) && summary.Reports.Any(report => !report.Success)) || allBuildsHaveFailed)\n                            break;\n                    }\n\n                    if (supportedBenchmarks.Any(b => b.Config.Options.IsSet(ConfigOptions.JoinSummary)))\n                    {\n                        var joinedSummary = Summary.Join(results, runsChronometer.GetElapsed());\n\n                        PrintSummary(compositeLogger, supportedBenchmarks.First(b => b.Config.Options.IsSet(ConfigOptions.JoinSummary)).Config, joinedSummary);\n\n                        results.Clear();\n                        results.Add(joinedSummary);\n                    }\n\n                    var totalTime = globalChronometer.GetElapsed().GetTimeSpan();\n                    int totalNumberOfExecutedBenchmarks = results.Sum(summary => summary.GetNumberOfExecutedBenchmarks());\n                    LogTotalTime(compositeLogger, totalTime, totalNumberOfExecutedBenchmarks, \"Global total time\");\n\n                    return results.ToArray();\n                }\n                finally\n                {\n                    // some benchmarks might be using parameters that have locking finalizers\n                    // so we need to dispose them after we are done running the benchmarks\n                    // see https://github.com/dotnet/BenchmarkDotNet/issues/1383 and https://github.com/dotnet/runtime/issues/314 for more\n                    foreach (var benchmarkInfo in benchmarkRunInfos)\n                    {\n                        benchmarkInfo.Dispose();\n                    }\n\n                    compositeLogger.WriteLineHeader(\"// * Artifacts cleanup *\");\n                    Cleanup(compositeLogger, new HashSet<string>(artifactsToCleanup.Distinct()));\n                    compositeLogger.WriteLineInfo(\"Artifacts cleanup is finished\");\n                    compositeLogger.Flush();\n\n                    eventProcessor.OnEndRunStage();\n                }\n            }\n        }\n\n        private static Summary Run(BenchmarkRunInfo benchmarkRunInfo,\n                                   Dictionary<BenchmarkCase, (BenchmarkId benchmarkId, BuildResult buildResult)> buildResults,\n                                   IResolver resolver,\n                                   ILogger logger,\n                                   EventProcessor eventProcessor,\n                                   List<string> artifactsToCleanup,\n                                   string resultsFolderPath,\n                                   string logFilePath,\n                                   int totalBenchmarkCount,\n                                   in StartedClock runsChronometer,\n                                   ref int benchmarksToRunCount,\n                                   TaskbarProgress taskbarProgress)\n        {\n            var runStart = runsChronometer.GetElapsed();\n\n            var benchmarks = benchmarkRunInfo.BenchmarksCases;\n            var allBuildsHaveFailed = benchmarks.All(benchmark => !buildResults[benchmark].buildResult.IsBuildSuccess);\n            var config = benchmarkRunInfo.Config;\n            var cultureInfo = config.CultureInfo ?? DefaultCultureInfo.Instance;\n            var reports = new List<BenchmarkReport>();\n            string title = GetTitle([benchmarkRunInfo]);\n            using var consoleTitler = new ConsoleTitler($\"{benchmarksToRunCount}/{totalBenchmarkCount} Remaining\");\n\n            logger.WriteLineInfo($\"// Found {benchmarks.Length} benchmarks:\");\n            foreach (var benchmark in benchmarks)\n                logger.WriteLineInfo($\"//   {benchmark.DisplayInfo}\");\n            logger.WriteLine();\n\n            using (var powerManagementApplier = new PowerManagementApplier(logger))\n            {\n                bool stop = false;\n\n                for (int i = 0; i < benchmarks.Length && !stop; i++)\n                {\n                    var benchmark = benchmarks[i];\n\n                    powerManagementApplier.ApplyPerformancePlan(benchmark.Job.Environment.PowerPlanMode\n                        ?? benchmark.Job.ResolveValue(EnvironmentMode.PowerPlanModeCharacteristic, EnvironmentResolver.Instance).GetValueOrDefault());\n\n                    var info = buildResults[benchmark];\n                    var buildResult = info.buildResult;\n\n                    if (buildResult.IsBuildSuccess)\n                    {\n                        if (!config.Options.IsSet(ConfigOptions.KeepBenchmarkFiles))\n                            artifactsToCleanup.AddRange(buildResult.ArtifactsToCleanup);\n\n                        eventProcessor.OnStartRunBenchmark(benchmark);\n                        var report = RunCore(benchmark, info.benchmarkId, logger, resolver, buildResult, benchmarkRunInfo.CompositeInProcessDiagnoser);\n                        eventProcessor.OnEndRunBenchmark(benchmark, report);\n\n                        if (report.AllMeasurements.Any(m => m.Operations == 0))\n                            throw new InvalidOperationException(\"An iteration with 'Operations == 0' detected\");\n                        reports.Add(report);\n                        if (report.GetResultRuns().Any())\n                        {\n                            var statistics = report.GetResultRuns().GetStatistics();\n                            var formatter = statistics.CreateNanosecondFormatter(cultureInfo);\n                            logger.WriteLineStatistic(statistics.ToString(cultureInfo, formatter));\n                        }\n\n                        if (!report.Success && config.Options.IsSet(ConfigOptions.StopOnFirstError))\n                        {\n                            stop = true;\n                        }\n                    }\n                    else\n                    {\n                        reports.Add(new BenchmarkReport(false, benchmark, buildResult, buildResult, default, default));\n\n                        if (buildResult.GenerateException != null)\n                            logger.WriteLineError($\"// Generate Exception: {buildResult.GenerateException}\");\n                        else if (!buildResult.IsBuildSuccess && buildResult.TryToExplainFailureReason(out string? reason))\n                            logger.WriteLineError($\"// Build Error: {reason}\");\n                        else if (buildResult.ErrorMessage != null)\n                            logger.WriteLineError($\"// Build Error: {buildResult.ErrorMessage}\");\n\n                        if (!benchmark.Job.GetToolchain().IsInProcess)\n                        {\n                            logger.WriteLine();\n                            logger.WriteLineError($\"// BenchmarkDotNet has failed to build the auto-generated boilerplate code.\");\n\n                            if (config.Options.IsSet(ConfigOptions.KeepBenchmarkFiles))\n                            {\n                                logger.WriteLineError($\"// It can be found in {buildResult.ArtifactsPaths.BuildArtifactsDirectoryPath}\");\n                            }\n                            else\n                            {\n                                artifactsToCleanup.AddRange(buildResult.ArtifactsToCleanup);\n                                logger.WriteLineError($\"// Re-run benchmark with --keepFiles option to confirm auto-generated project files.\");\n                            }\n\n                            logger.WriteLineError($\"// Please follow the troubleshooting guide: https://benchmarkdotnet.org/articles/guides/troubleshooting.html\");\n                        }\n\n                        if (config.Options.IsSet(ConfigOptions.StopOnFirstError) || allBuildsHaveFailed)\n                        {\n                            stop = true;\n                        }\n                    }\n\n                    logger.WriteLine();\n\n                    benchmarksToRunCount -= stop ? benchmarks.Length - i : 1;\n\n                    LogProgress(logger, in runsChronometer, totalBenchmarkCount, benchmarksToRunCount, consoleTitler, taskbarProgress);\n                }\n            }\n\n            var runEnd = runsChronometer.GetElapsed();\n\n            return new Summary(title,\n                reports.ToImmutableArray(),\n                HostEnvironmentInfo.GetCurrent(),\n                resultsFolderPath,\n                logFilePath,\n                runEnd.GetTimeSpan() - runStart.GetTimeSpan(),\n                cultureInfo,\n                Validate(benchmarkRunInfo), // validate them once again, but don't print the output\n                config.GetColumnHidingRules().ToImmutableArray());\n        }\n\n        private static void PrintSummary(ILogger logger, ImmutableConfig config, Summary summary)\n        {\n            var cultureInfo = config.CultureInfo ?? DefaultCultureInfo.Instance;\n\n            logger.WriteLineHeader(\"// ***** BenchmarkRunner: Finish  *****\");\n            logger.WriteLine();\n\n            logger.WriteLineHeader(\"// * Export *\");\n            string currentDirectory = Directory.GetCurrentDirectory();\n            foreach (string file in config.GetCompositeExporter().ExportToFiles(summary, logger))\n            {\n                logger.WriteLineInfo($\"  {file.GetBaseName(currentDirectory)}\");\n            }\n\n            logger.WriteLine();\n\n            logger.WriteLineHeader(\"// * Detailed results *\");\n\n            BenchmarkReportExporter.Default.ExportToLog(summary, logger);\n\n            logger.WriteLineHeader(\"// * Summary *\");\n            MarkdownExporter.Console.ExportToLog(summary, logger);\n\n            // TODO: make exporter\n            ConclusionHelper.Print(logger, config.GetCompositeAnalyser().Analyse(summary).Distinct().ToList());\n\n            if (config.ConfigAnalysisConclusion.Any())\n            {\n                logger.WriteLineHeader(\"// * Config Issues *\");\n                ConclusionHelper.Print(logger, config.ConfigAnalysisConclusion);\n            }\n\n            // TODO: move to conclusions\n            var columnWithLegends = summary.Table.Columns.Where(c => c.NeedToShow && c.OriginalColumn.Legend.IsNotBlank()).Select(c => c.OriginalColumn).ToArray();\n\n            bool needToShowTimeLegend = summary.Table.Columns.Any(c => c.NeedToShow && c.OriginalColumn.UnitType == UnitType.Time);\n            var effectiveTimeUnit = needToShowTimeLegend ? summary.Table.EffectiveSummaryStyle.TimeUnit : null;\n\n            if (columnWithLegends.Any() || effectiveTimeUnit != null)\n            {\n                logger.WriteLine();\n                logger.WriteLineHeader(\"// * Legends *\");\n                int maxNameWidth = 0;\n                if (columnWithLegends.Any())\n                    maxNameWidth = Math.Max(maxNameWidth, columnWithLegends.Select(c => c.ColumnName.Length).Max());\n                if (effectiveTimeUnit != null)\n                    maxNameWidth = Math.Max(maxNameWidth, effectiveTimeUnit.Abbreviation.ToString(cultureInfo).Length + 2);\n\n                foreach (var column in columnWithLegends)\n                    logger.WriteLineHint($\"  {column.ColumnName.PadRight(maxNameWidth, ' ')} : {column.Legend}\");\n\n                if (effectiveTimeUnit != null)\n                    logger.WriteLineHint($\"  {(\"1 \" + effectiveTimeUnit.Abbreviation).PadRight(maxNameWidth, ' ')} :\" +\n                                         $\" 1 {effectiveTimeUnit.FullName} ({TimeUnit.Convert(1, effectiveTimeUnit, TimeUnit.Second).ToString(\"0.#########\", summary.GetCultureInfo())} sec)\");\n            }\n\n            if (config.GetDiagnosers().Any())\n            {\n                logger.WriteLine();\n                config.GetCompositeDiagnoser().DisplayResults(logger);\n            }\n\n            logger.WriteLine();\n            logger.WriteLineHeader(\"// ***** BenchmarkRunner: End *****\");\n        }\n\n        private static ImmutableArray<ValidationError> Validate(params BenchmarkRunInfo[] benchmarks)\n        {\n            var validationErrors = new List<ValidationError>();\n\n            foreach (var benchmarkRunInfo in benchmarks)\n                validationErrors.AddRange(benchmarkRunInfo.Config.GetCompositeValidator().Validate(new ValidationParameters(benchmarkRunInfo.BenchmarksCases, benchmarkRunInfo.Config)));\n\n            return validationErrors.ToImmutableArray();\n        }\n\n        private static Dictionary<BuildPartition, BuildResult> BuildInParallel(ILogger logger, string rootArtifactsFolderPath, BuildPartition[] buildPartitions, in StartedClock globalChronometer, EventProcessor eventProcessor)\n        {\n            logger.WriteLineHeader($\"// ***** Building {buildPartitions.Length} exe(s) in Parallel: Start   *****\");\n\n            var buildLogger = buildPartitions.Length == 1 ? logger : NullLogger.Instance; // when we have just one partition we can print to std out\n\n            var beforeParallelBuild = globalChronometer.GetElapsed();\n\n            var buildResults = buildPartitions\n                .AsParallel()\n                .Select(buildPartition => (Partition: buildPartition, Result: Build(buildPartition, rootArtifactsFolderPath, buildLogger)))\n                .AsSequential() // Ensure that build completion events are processed sequentially\n                .Select(build =>\n                {\n                    // If the generation was successful, but the build was not, we will try building sequentially\n                    // so don't send the OnBuildComplete event yet.\n                    if (buildPartitions.Length <= 1 || !build.Result.IsGenerateSuccess || build.Result.IsBuildSuccess)\n                        eventProcessor.OnBuildComplete(build.Partition, build.Result);\n\n                    return build;\n                })\n                .ToDictionary(build => build.Partition, build => build.Result);\n\n            var afterParallelBuild = globalChronometer.GetElapsed();\n\n            logger.WriteLineHeader($\"// ***** Done, took {GetFormattedDifference(beforeParallelBuild, afterParallelBuild)}   *****\");\n\n            if (buildPartitions.Length <= 1 || !buildResults.Values.Any(result => result.IsGenerateSuccess && !result.IsBuildSuccess))\n                return buildResults;\n\n            logger.WriteLineHeader(\"// ***** Failed to build in Parallel, switching to sequential build   *****\");\n\n            foreach (var buildPartition in buildPartitions)\n            {\n                if (buildResults[buildPartition].IsGenerateSuccess && !buildResults[buildPartition].IsBuildSuccess)\n                {\n                    if (!buildResults[buildPartition].TryToExplainFailureReason(out _))\n                        buildResults[buildPartition] = Build(buildPartition, rootArtifactsFolderPath, buildLogger);\n\n                    eventProcessor.OnBuildComplete(buildPartition, buildResults[buildPartition]);\n                }\n            }\n\n            var afterSequentialBuild = globalChronometer.GetElapsed();\n\n            logger.WriteLineHeader($\"// ***** Done, took {GetFormattedDifference(afterParallelBuild, afterSequentialBuild)}   *****\");\n\n            return buildResults;\n        }\n\n        private static Dictionary<BuildPartition, BuildResult> BuildSequential(ILogger logger, string rootArtifactsFolderPath, BuildPartition[] buildPartitions, in StartedClock globalChronometer, EventProcessor eventProcessor)\n        {\n            logger.WriteLineHeader($\"// ***** Building {buildPartitions.Length} exe(s) in Sequential: Start   *****\");\n\n            var beforeBuild = globalChronometer.GetElapsed();\n\n            var buildResults = new Dictionary<BuildPartition, BuildResult>();\n            foreach (var buildPartition in buildPartitions)\n            {\n                buildResults[buildPartition] = Build(buildPartition, rootArtifactsFolderPath, logger);\n                eventProcessor.OnBuildComplete(buildPartition, buildResults[buildPartition]);\n            }\n\n            var afterBuild = globalChronometer.GetElapsed();\n\n            logger.WriteLineHeader($\"// ***** Done, took {GetFormattedDifference(beforeBuild, afterBuild)}   *****\");\n\n            return buildResults;\n        }\n\n        private static string GetFormattedDifference(ClockSpan before, ClockSpan after)\n                => (after.GetTimeSpan() - before.GetTimeSpan()).ToFormattedTotalTime(DefaultCultureInfo.Instance);\n\n        private static BuildResult Build(BuildPartition buildPartition, string rootArtifactsFolderPath, ILogger buildLogger)\n        {\n            var toolchain = buildPartition.RepresentativeBenchmarkCase.GetToolchain(); // it's guaranteed that all the benchmarks in single partition have same toolchain\n\n            var generateResult = toolchain.Generator.GenerateProject(buildPartition, buildLogger, rootArtifactsFolderPath);\n\n            try\n            {\n                if (!generateResult.IsGenerateSuccess)\n                {\n                    return generateResult.GenerateException != null\n                        ? BuildResult.Failure(generateResult, generateResult.GenerateException)\n                        : BuildResult.Failure(generateResult, errorMessage: \"\");\n                }\n\n                return toolchain.Builder.Build(generateResult, buildPartition, buildLogger);\n            }\n            catch (Exception e)\n            {\n                return BuildResult.Failure(generateResult, e);\n            }\n        }\n\n        private static BenchmarkReport RunCore(BenchmarkCase benchmarkCase, BenchmarkId benchmarkId, ILogger logger, IResolver resolver, BuildResult buildResult,\n            CompositeInProcessDiagnoser compositeInProcessDiagnoser)\n        {\n            var toolchain = benchmarkCase.GetToolchain();\n\n            logger.WriteLineHeader(\"// **************************\");\n            logger.WriteLineHeader(\"// Benchmark: \" + benchmarkCase.DisplayInfo);\n\n            var (success, executeResults, metrics) = Execute(logger, benchmarkCase, benchmarkId, toolchain, buildResult, resolver, compositeInProcessDiagnoser);\n\n            return new BenchmarkReport(success, benchmarkCase, buildResult, buildResult, executeResults, metrics);\n        }\n\n        private static (bool success, List<ExecuteResult> executeResults, List<Metric> metrics) Execute(\n            ILogger logger, BenchmarkCase benchmarkCase, BenchmarkId benchmarkId, IToolchain toolchain, BuildResult buildResult, IResolver resolver,\n            CompositeInProcessDiagnoser compositeInProcessDiagnoser)\n        {\n            var executeResults = new List<ExecuteResult>();\n            var metrics = new List<Metric>();\n\n            logger.WriteLineInfo(\"// *** Execute ***\");\n            bool analyzeRunToRunVariance = benchmarkCase.Job.ResolveValue(AccuracyMode.AnalyzeLaunchVarianceCharacteristic, resolver);\n            bool autoLaunchCount = !benchmarkCase.Job.HasValue(RunMode.LaunchCountCharacteristic);\n            int defaultValue = analyzeRunToRunVariance ? 2 : 1;\n            int launchCount = Math.Max(\n                1,\n                autoLaunchCount ? defaultValue : benchmarkCase.Job.Run.LaunchCount);\n\n            var noOverheadCompositeDiagnoser = benchmarkCase.Config.GetCompositeDiagnoser(benchmarkCase, runmode => runmode is Diagnosers.RunMode.NoOverhead or Diagnosers.RunMode.ExtraIteration);\n\n            for (int launchIndex = 1; launchIndex <= launchCount; launchIndex++)\n            {\n                string printedLaunchCount = analyzeRunToRunVariance && autoLaunchCount && launchIndex <= 2\n                    ? \"\"\n                    : \" / \" + launchCount;\n                logger.WriteLineInfo($\"// Launch: {launchIndex}{printedLaunchCount}\");\n\n                // use diagnoser only for the last run (we need single result, not many)\n                bool useDiagnoser = launchIndex == launchCount && noOverheadCompositeDiagnoser != null;\n\n                var executeResult = RunExecute(\n                    logger,\n                    benchmarkCase,\n                    benchmarkId,\n                    toolchain,\n                    buildResult,\n                    resolver,\n                    useDiagnoser ? noOverheadCompositeDiagnoser : null,\n                    compositeInProcessDiagnoser,\n                    launchIndex,\n                    useDiagnoser ? Diagnosers.RunMode.NoOverhead : Diagnosers.RunMode.None);\n\n                executeResults.Add(executeResult);\n\n                if (!executeResult.IsSuccess)\n                {\n                    return (false, executeResults, metrics);\n                }\n\n                var measurements = executeResult.Measurements;\n\n                if (useDiagnoser)\n                {\n                    metrics.AddRange(noOverheadCompositeDiagnoser!.ProcessResults(new DiagnoserResults(benchmarkCase, executeResult, buildResult)));\n                }\n\n                if (autoLaunchCount && launchIndex == 2 && analyzeRunToRunVariance)\n                {\n                    // TODO: improve this logic\n                    double overheadApprox = new Statistics(measurements.Where(m => m.Is(IterationMode.Overhead, IterationStage.Actual)).Select(m => m.Nanoseconds)).Median;\n                    double workloadApprox = new Statistics(measurements.Where(m => m.Is(IterationMode.Workload, IterationStage.Actual)).Select(m => m.Nanoseconds)).Median;\n                    double percent = overheadApprox / workloadApprox * 100;\n                    launchCount = (int)Math.Round(Math.Max(2, 2 + (percent - 1) / 3)); // an empirical formula\n                }\n            }\n            logger.WriteLine();\n\n            // Do a \"Diagnostic\" run, but DISCARD the results, so that the overhead of Diagnostics doesn't skew the overall results\n            var extraRunCompositeDiagnoser = benchmarkCase.Config.GetCompositeDiagnoser(benchmarkCase, runmode => runmode is Diagnosers.RunMode.ExtraRun);\n            if (extraRunCompositeDiagnoser != null)\n            {\n                logger.WriteLineInfo(\"// Run, Diagnostic\");\n\n                var executeResult = RunExecute(\n                    logger,\n                    benchmarkCase,\n                    benchmarkId,\n                    toolchain,\n                    buildResult,\n                    resolver,\n                    extraRunCompositeDiagnoser,\n                    compositeInProcessDiagnoser,\n                    ++launchCount,\n                    Diagnosers.RunMode.ExtraRun);\n\n                if (executeResult.IsSuccess)\n                {\n                    metrics.AddRange(extraRunCompositeDiagnoser.ProcessResults(new DiagnoserResults(benchmarkCase, executeResult, buildResult)));\n                }\n\n                logger.WriteLine();\n            }\n\n            var separateLogicCompositeDiagnoser = benchmarkCase.Config.GetCompositeDiagnoser(benchmarkCase, runmode => runmode is Diagnosers.RunMode.SeparateLogic);\n            if (separateLogicCompositeDiagnoser != null)\n            {\n                logger.WriteLineInfo(\"// Run, Diagnostic [SeparateLogic]\");\n\n                separateLogicCompositeDiagnoser.Handle(HostSignal.SeparateLogic, new DiagnoserActionParameters(null, benchmarkCase, benchmarkId));\n\n                if (compositeInProcessDiagnoser.InProcessDiagnosers.Any(d => d.GetRunMode(benchmarkCase) == Diagnosers.RunMode.SeparateLogic))\n                {\n                    var executeResult = RunExecute(\n                        logger,\n                        benchmarkCase,\n                        benchmarkId,\n                        toolchain,\n                        buildResult,\n                        resolver,\n                        separateLogicCompositeDiagnoser,\n                        compositeInProcessDiagnoser,\n                        ++launchCount,\n                        Diagnosers.RunMode.SeparateLogic);\n\n                    if (executeResult.IsSuccess)\n                    {\n                        metrics.AddRange(separateLogicCompositeDiagnoser.ProcessResults(new DiagnoserResults(benchmarkCase, executeResult, buildResult)));\n                    }\n\n                    logger.WriteLine();\n                }\n            }\n\n            return (true, executeResults, metrics);\n        }\n\n        private static ExecuteResult RunExecute(ILogger logger, BenchmarkCase benchmarkCase, BenchmarkId benchmarkId, IToolchain toolchain,\n            BuildResult buildResult, IResolver resolver, IDiagnoser? diagnoser, CompositeInProcessDiagnoser compositeInProcessDiagnoser, int launchIndex, Diagnosers.RunMode diagnoserRunMode)\n        {\n            var executeResult = toolchain.Executor.Execute(\n                new ExecuteParameters(\n                    buildResult,\n                    benchmarkCase,\n                    benchmarkId,\n                    logger,\n                    resolver,\n                    launchIndex,\n                    compositeInProcessDiagnoser,\n                    diagnoser,\n                    diagnoserRunMode));\n\n            if (!executeResult.IsSuccess)\n            {\n                executeResult.LogIssues(logger, buildResult);\n            }\n\n            if (executeResult.ProcessId.HasValue)\n            {\n                if (executeResult.ExitCode is int exitCode)\n                {\n                    logger.WriteLineInfo($\"// Benchmark Process {executeResult.ProcessId} has exited with code {exitCode}.\");\n                }\n                else\n                {\n                    logger.WriteLineInfo($\"// Benchmark Process {executeResult.ProcessId} failed to exit.\");\n                }\n            }\n\n            return executeResult;\n        }\n\n        private static void LogTotalTime(ILogger logger, TimeSpan time, int executedBenchmarksCount, string message = \"Total time\")\n            => logger.WriteLineStatistic($\"{message}: {time.ToFormattedTotalTime(DefaultCultureInfo.Instance)}, executed benchmarks: {executedBenchmarksCount}\");\n\n        private static (BenchmarkRunInfo[], List<ValidationError>) GetSupportedBenchmarks(BenchmarkRunInfo[] benchmarkRunInfos, IResolver resolver)\n        {\n            List<ValidationError> validationErrors = new();\n            List<BenchmarkRunInfo> runInfos = new(benchmarkRunInfos.Length);\n\n            if (benchmarkRunInfos.Length == 0)\n            {\n                validationErrors.Add(new ValidationError(true, $\"No benchmarks were found.\"));\n                return (Array.Empty<BenchmarkRunInfo>(), validationErrors);\n            }\n\n            foreach (var benchmarkRunInfo in benchmarkRunInfos)\n            {\n                if (!benchmarkRunInfo.ContainsBenchmarkDeclarations)\n                {\n                    validationErrors.Add(new ValidationError(true, $\"No [Benchmark] attribute found on '{benchmarkRunInfo.Type.Name}' benchmark case.\"));\n                    continue;\n                }\n\n                var validBenchmarks = benchmarkRunInfo.BenchmarksCases\n                    .Where(benchmark =>\n                    {\n\n                        var errors = benchmark.GetToolchain()\n                            .Validate(benchmark, resolver)\n                            .ToArray();\n\n                        validationErrors.AddRange(errors);\n\n                        return !errors.Any(error => error.IsCritical);\n                    })\n                    .ToArray();\n\n                runInfos.Add(\n                    new BenchmarkRunInfo(\n                        validBenchmarks,\n                        benchmarkRunInfo.Type,\n                        benchmarkRunInfo.Config,\n                        benchmarkRunInfo.CompositeInProcessDiagnoser\n                    ));\n\n\n            }\n            return (runInfos.ToArray(), validationErrors);\n        }\n\n        private static string GetRootArtifactsFolderPath(BenchmarkRunInfo[] benchmarkRunInfos)\n        {\n            var defaultPath = DefaultConfig.Instance.ArtifactsPath!;\n\n            var customPath = benchmarkRunInfos\n                .Where(benchmark => benchmark.Config.ArtifactsPath.IsNotBlank() && benchmark.Config.ArtifactsPath != defaultPath)\n                .Select(benchmark => benchmark.Config.ArtifactsPath)\n                .Distinct()\n                .SingleOrDefault();\n\n            return customPath != default ? customPath.CreateIfNotExists() : defaultPath;\n        }\n\n        private static string GetTitle(BenchmarkRunInfo[] benchmarkRunInfos, int desiredMaxLength = int.MaxValue)\n        {\n            // few types might have the same name: A.Name and B.Name will both report \"Name\"\n            // in that case, we can not use the type name as file name because they would be getting overwritten #529\n            var uniqueTargetTypes = benchmarkRunInfos.SelectMany(info => info.BenchmarksCases.Select(benchmark => benchmark.Descriptor.Type)).Distinct().ToArray();\n\n            var fileNamePrefix = (uniqueTargetTypes.Length == 1)\n                ? FolderNameHelper.ToFolderName(uniqueTargetTypes[0])\n                : \"BenchmarkRun\";\n            string dateTimeSuffix = DateTime.Now.ToString(DateTimeFormat);\n\n            int maxFileNamePrefixLength = desiredMaxLength - dateTimeSuffix.Length - 1;\n            if (maxFileNamePrefixLength <= 2)\n                return dateTimeSuffix;\n\n            if (fileNamePrefix.Length > maxFileNamePrefixLength)\n            {\n                int length1 = maxFileNamePrefixLength / 2;\n                int length2 = maxFileNamePrefixLength - length1 - 1;\n                fileNamePrefix = fileNamePrefix.Substring(0, length1) +\n                                 \"-\" +\n                                 fileNamePrefix.Substring(fileNamePrefix.Length - length2, length2);\n            }\n\n            return $\"{fileNamePrefix}-{dateTimeSuffix}\";\n        }\n\n        private static string GetResultsFolderPath(string rootArtifactsFolderPath, BenchmarkRunInfo[] benchmarkRunInfos)\n        {\n            if (benchmarkRunInfos.Any(info => info.Config.Options.IsSet(ConfigOptions.DontOverwriteResults)))\n                return Path.Combine(rootArtifactsFolderPath, DateTime.Now.ToString(DateTimeFormat)).CreateIfNotExists();\n\n            return Path.Combine(rootArtifactsFolderPath, \"results\").CreateIfNotExists();\n        }\n\n        private static StreamWriter GetLogFileStreamWriter(BenchmarkRunInfo[] benchmarkRunInfos, string logFilePath)\n        {\n            if (benchmarkRunInfos.Any(info => info.Config.Options.IsSet(ConfigOptions.DisableLogFile)))\n                return StreamWriter.Null;\n\n            return new StreamWriter(logFilePath, append: false);\n        }\n\n        private static ILogger CreateCompositeLogger(BenchmarkRunInfo[] benchmarkRunInfos, StreamLogger streamLogger)\n        {\n            var loggers = new Dictionary<string, ILogger>();\n\n            void AddLogger(ILogger logger)\n            {\n                if (!loggers.ContainsKey(logger.Id) || loggers[logger.Id].Priority < logger.Priority)\n                    loggers[logger.Id] = logger;\n            }\n\n            foreach (var benchmarkRunInfo in benchmarkRunInfos)\n                foreach (var logger in benchmarkRunInfo.Config.GetLoggers())\n                    AddLogger(logger);\n\n            if (benchmarkRunInfos.Length == 0)\n                AddLogger(new ConsoleLogger());\n\n            AddLogger(streamLogger);\n\n            return new CompositeLogger(loggers.Values.ToImmutableHashSet());\n        }\n\n        private static void Cleanup(ILogger logger, HashSet<string> artifactsToCleanup)\n        {\n            foreach (string path in artifactsToCleanup)\n            {\n                try\n                {\n                    if (Directory.Exists(path))\n                    {\n                        Directory.Delete(path, recursive: true);\n                    }\n                    else if (File.Exists(path))\n                    {\n                        File.Delete(path);\n                    }\n                }\n                catch (Exception)\n                {\n                    // sth is locking our auto-generated files\n                    // there is very little we can do about it\n                }\n            }\n        }\n\n        private static void LogProgress(ILogger logger, in StartedClock runsChronometer, int totalBenchmarkCount, int benchmarksToRunCount, ConsoleTitler consoleTitler, TaskbarProgress taskbarProgress)\n        {\n            int executedBenchmarkCount = totalBenchmarkCount - benchmarksToRunCount;\n            TimeSpan fromNow = GetEstimatedFinishTime(runsChronometer, benchmarksToRunCount, executedBenchmarkCount);\n            DateTime estimatedEnd = DateTime.Now.Add(fromNow);\n            string message = $\"// ** Remained {benchmarksToRunCount} ({(double)benchmarksToRunCount / totalBenchmarkCount:P1}) benchmark(s) to run.\" +\n                $\" Estimated finish {estimatedEnd:yyyy-MM-dd H:mm} ({(int)fromNow.TotalHours}h {fromNow.Minutes}m from now) **\";\n            logger.WriteLineHeader(message);\n\n            consoleTitler.UpdateTitle($\"{benchmarksToRunCount}/{totalBenchmarkCount} Remaining - {(int)fromNow.TotalHours}h {fromNow.Minutes}m to finish\");\n\n            taskbarProgress.SetProgress((float)executedBenchmarkCount / totalBenchmarkCount);\n        }\n\n        private static TimeSpan GetEstimatedFinishTime(in StartedClock runsChronometer, int benchmarksToRunCount, int executedBenchmarkCount)\n        {\n            double avgSecondsPerBenchmark = executedBenchmarkCount > 0 ? runsChronometer.GetElapsed().GetTimeSpan().TotalSeconds / executedBenchmarkCount : 0;\n            TimeSpan fromNow = TimeSpan.FromSeconds(avgSecondsPerBenchmark * benchmarksToRunCount);\n            return fromNow;\n        }\n\n        private static void PrintValidationErrors(ILogger logger, IEnumerable<ValidationError> validationErrors)\n        {\n            foreach (var validationError in validationErrors.Distinct())\n            {\n                if (validationError.BenchmarkCase != null)\n                {\n                    logger.WriteLineInfo($\"// Benchmark {validationError.BenchmarkCase.DisplayInfo}\");\n                }\n\n                logger.WriteLineError($\"//    * {validationError.Message}\");\n                logger.WriteLine();\n            }\n        }\n\n        private static int GetIdToResume(string rootArtifactsFolderPath, string currentLogFileName, BenchmarkRunInfo[] benchmarkRunInfos)\n        {\n            if (benchmarkRunInfos.Any(benchmark => benchmark.Config.Options.IsSet(ConfigOptions.Resume)))\n            {\n                var directoryInfo = new DirectoryInfo(rootArtifactsFolderPath);\n                var logFilesExceptCurrent = directoryInfo\n                    .GetFiles($\"{currentLogFileName.Split('-')[0]}*\")\n                    .Where(file => Path.GetFileNameWithoutExtension(file.Name) != currentLogFileName)\n                    .ToArray();\n\n                if (logFilesExceptCurrent.Length > 0)\n                {\n                    var previousRunLogFile = logFilesExceptCurrent\n                        .OrderByDescending(o => o.LastWriteTime)\n                        .First();\n\n                    var regex = new Regex(\"--benchmarkId (.*?) in\", RegexOptions.Compiled);\n                    foreach (var line in File.ReadLines(previousRunLogFile.FullName).Reverse())\n                    {\n                        var match = regex.Match(line);\n                        if (match.Success)\n                        {\n                            return int.Parse(match.Groups[1].Value);\n                        }\n                    }\n                }\n            }\n\n            return -1;\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Running/BenchmarkRunnerDirty.cs",
    "content": "﻿using System;\nusing System.ComponentModel;\nusing System.Linq;\nusing System.Reflection;\nusing System.Runtime.CompilerServices;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Portability;\nusing BenchmarkDotNet.Reports;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Running\n{\n    // VS generates bad assembly binding redirects for ValueTuple for Full .NET Framework\n    // we need to keep the logic that uses it in a separate method and create DirtyAssemblyResolveHelper first\n    // so it can ignore the version mismatch ;)\n    public static class BenchmarkRunner\n    {\n        [PublicAPI]\n        public static Summary Run<T>(IConfig? config = null, string[]? args = null)\n        {\n            using (DirtyAssemblyResolveHelper.Create())\n                return RunWithExceptionHandling(() => RunWithDirtyAssemblyResolveHelper(typeof(T), config, args));\n        }\n\n        [PublicAPI]\n        public static Summary Run(Type type, IConfig? config = null, string[]? args = null)\n        {\n            using (DirtyAssemblyResolveHelper.Create())\n                return RunWithExceptionHandling(() => RunWithDirtyAssemblyResolveHelper(type, config, args));\n        }\n\n        [PublicAPI]\n        public static Summary[] Run(Type[] types, IConfig? config = null, string[]? args = null)\n        {\n            using (DirtyAssemblyResolveHelper.Create())\n                return RunWithExceptionHandling(() => RunWithDirtyAssemblyResolveHelper(types, config, args));\n        }\n\n        [PublicAPI]\n        public static Summary Run(Type type, MethodInfo[] methods, IConfig? config = null)\n        {\n            using (DirtyAssemblyResolveHelper.Create())\n                return RunWithExceptionHandling(() => RunWithDirtyAssemblyResolveHelper(type, methods, config));\n        }\n\n        [PublicAPI]\n        public static Summary[] Run(Assembly assembly, IConfig? config = null, string[]? args = null)\n        {\n            using (DirtyAssemblyResolveHelper.Create())\n                return RunWithExceptionHandling(() => RunWithDirtyAssemblyResolveHelper(assembly, config, args));\n        }\n\n        [PublicAPI]\n        public static Summary Run(BenchmarkRunInfo benchmarkRunInfo)\n        {\n            using (DirtyAssemblyResolveHelper.Create())\n                return RunWithExceptionHandling(() => RunWithDirtyAssemblyResolveHelper(new[] { benchmarkRunInfo }).Single());\n        }\n\n        [PublicAPI]\n        public static Summary[] Run(BenchmarkRunInfo[] benchmarkRunInfos)\n        {\n            using (DirtyAssemblyResolveHelper.Create())\n                return RunWithExceptionHandling(() => RunWithDirtyAssemblyResolveHelper(benchmarkRunInfos));\n        }\n\n        [MethodImpl(MethodImplOptions.NoInlining)]\n        private static Summary RunWithDirtyAssemblyResolveHelper(Type type, IConfig? config, string[]? args)\n        {\n            var summaries = args == null\n                ? BenchmarkRunnerClean.Run([BenchmarkConverter.TypeToBenchmarks(type, config)])\n                : new BenchmarkSwitcher([type]).RunWithDirtyAssemblyResolveHelper(args, config, false);\n\n            return summaries.SingleOrDefault()\n                ?? Summary.ValidationFailed($\"No benchmarks found in type '{type.Name}'\", string.Empty, string.Empty);\n        }\n\n        [MethodImpl(MethodImplOptions.NoInlining)]\n        private static Summary RunWithDirtyAssemblyResolveHelper(Type type, MethodInfo[] methods, IConfig? config = null)\n        {\n            var summaries = BenchmarkRunnerClean.Run(new[] { BenchmarkConverter.MethodsToBenchmarks(type, methods, config) });\n\n            return summaries.SingleOrDefault()\n                ?? Summary.ValidationFailed($\"No benchmarks found in type '{type.Name}'\", string.Empty, string.Empty);\n        }\n\n        [MethodImpl(MethodImplOptions.NoInlining)]\n        private static Summary[] RunWithDirtyAssemblyResolveHelper(Assembly assembly, IConfig? config, string[]? args)\n            => args == null\n                ? BenchmarkRunnerClean.Run(assembly.GetRunnableBenchmarks().Select(type => BenchmarkConverter.TypeToBenchmarks(type, config)).ToArray())\n                : new BenchmarkSwitcher(assembly).RunWithDirtyAssemblyResolveHelper(args, config, false).ToArray();\n\n        [MethodImpl(MethodImplOptions.NoInlining)]\n        private static Summary[] RunWithDirtyAssemblyResolveHelper(Type[] types, IConfig? config, string[]? args)\n            => args == null\n                ? BenchmarkRunnerClean.Run(types.Select(type => BenchmarkConverter.TypeToBenchmarks(type, config)).ToArray())\n                : new BenchmarkSwitcher(types).RunWithDirtyAssemblyResolveHelper(args, config, false).ToArray();\n\n        [MethodImpl(MethodImplOptions.NoInlining)]\n        private static Summary[] RunWithDirtyAssemblyResolveHelper(BenchmarkRunInfo[] benchmarkRunInfos)\n            => BenchmarkRunnerClean.Run(benchmarkRunInfos);\n\n        private static Summary RunWithExceptionHandling(Func<Summary> run)\n        {\n            try\n            {\n                return run();\n            }\n            catch (InvalidBenchmarkDeclarationException e)\n            {\n                ConsoleLogger.Default.WriteLineError(e.Message);\n                return Summary.ValidationFailed(e.Message, string.Empty, string.Empty);\n            }\n        }\n\n        private static Summary[] RunWithExceptionHandling(Func<Summary[]> run)\n        {\n            try\n            {\n                return run();\n            }\n            catch (InvalidBenchmarkDeclarationException e)\n            {\n                ConsoleLogger.Default.WriteLineError(e.Message);\n                return new[] { Summary.ValidationFailed(e.Message, string.Empty, string.Empty) };\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Running/BenchmarkSwitcher.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Diagnostics.CodeAnalysis;\nusing System.Linq;\nusing System.Reflection;\nusing System.Runtime.CompilerServices;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.ConsoleArguments;\nusing BenchmarkDotNet.ConsoleArguments.ListBenchmarks;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Parameters;\nusing BenchmarkDotNet.Reports;\nusing JetBrains.Annotations;\nusing Perfolizer.Mathematics.OutlierDetection;\n\nnamespace BenchmarkDotNet.Running\n{\n    public class BenchmarkSwitcher\n    {\n        private readonly IUserInteraction userInteraction = new UserInteraction();\n        private readonly List<Type> types = [];\n        private readonly List<Assembly> assemblies = [];\n\n        internal BenchmarkSwitcher(IUserInteraction userInteraction) => this.userInteraction = userInteraction;\n\n        [PublicAPI] public BenchmarkSwitcher(Type[] types) => this.types.AddRange(types);\n\n        [PublicAPI] public BenchmarkSwitcher(Assembly assembly) => assemblies.Add(assembly);\n\n        [PublicAPI] public BenchmarkSwitcher(Assembly[] assemblies) => this.assemblies.AddRange(assemblies);\n\n        [PublicAPI] public BenchmarkSwitcher With(Type type) { types.Add(type); return this; }\n\n        [PublicAPI]\n        [SuppressMessage(\"ReSharper\", \"ParameterHidesMember\")]\n        public BenchmarkSwitcher With(Type[] types) { this.types.AddRange(types); return this; }\n\n        [PublicAPI] public BenchmarkSwitcher With(Assembly assembly) { assemblies.Add(assembly); return this; }\n\n        [PublicAPI]\n        [SuppressMessage(\"ReSharper\", \"ParameterHidesMember\")]\n        public BenchmarkSwitcher With(Assembly[] assemblies) { this.assemblies.AddRange(assemblies); return this; }\n\n        [PublicAPI] public static BenchmarkSwitcher FromTypes(Type[] types) => new BenchmarkSwitcher(types);\n\n        [PublicAPI] public static BenchmarkSwitcher FromAssembly(Assembly assembly) => new BenchmarkSwitcher(assembly);\n\n        [PublicAPI] public static BenchmarkSwitcher FromAssemblies(Assembly[] assemblies) => new BenchmarkSwitcher(assemblies);\n\n        /// <summary>\n        /// Run all available benchmarks.\n        /// </summary>\n        [PublicAPI] public IEnumerable<Summary> RunAll(IConfig? config = null, string[]? args = null)\n        {\n            args ??= [];\n            if (ConfigParser.TryUpdateArgs(args, out var updatedArgs, options => options.Filters = [\"*\"]))\n                args = updatedArgs;\n\n            return Run(args, config);\n        }\n\n        /// <summary>\n        /// Run all available benchmarks and join them to a single summary\n        /// </summary>\n        [PublicAPI] public Summary RunAllJoined(IConfig? config = null, string[]? args = null)\n        {\n            args ??= [];\n            if (ConfigParser.TryUpdateArgs(args, out var updatedArgs, options => (options.Join, options.Filters) = (true, new[] { \"*\" })))\n                args = updatedArgs;\n\n            return Run(args, config).Single();\n        }\n\n        [PublicAPI]\n        public IEnumerable<Summary> Run(string[]? args = null, IConfig? config = null)\n        {\n            // VS generates bad assembly binding redirects for ValueTuple for Full .NET Framework\n            // we need to keep the logic that uses it in a separate method and create DirtyAssemblyResolveHelper first\n            // so it can ignore the version mismatch ;)\n            using (DirtyAssemblyResolveHelper.Create())\n                return RunWithDirtyAssemblyResolveHelper(args, config, true);\n        }\n\n        [MethodImpl(MethodImplOptions.NoInlining)]\n        internal IEnumerable<Summary> RunWithDirtyAssemblyResolveHelper(string[]? args, IConfig? config, bool askUserForInput)\n        {\n            var notNullArgs = args ?? [];\n            var notNullConfig = config ?? DefaultConfig.Instance;\n\n            var logger = notNullConfig.GetNonNullCompositeLogger();\n            var (isParsingSuccess, parsedConfig, options) = ConfigParser.Parse(notNullArgs, logger, notNullConfig);\n            if (!isParsingSuccess) // invalid console args, the ConfigParser printed the error\n                return [];\n\n            if (args == null && Environment.GetCommandLineArgs().Length > 1) // The first element is the executable file name\n                logger.WriteLineHint(\"You haven't passed command line arguments to BenchmarkSwitcher.Run method. Running with default configuration.\");\n\n            if (options!.PrintInformation)\n            {\n                logger.WriteLine(HostEnvironmentInfo.GetInformation());\n                return [];\n            }\n\n            var effectiveConfig = ManualConfig.Union(notNullConfig, parsedConfig!);\n\n            var (allTypesValid, allAvailableTypesWithRunnableBenchmarks) = TypeFilter.GetTypesWithRunnableBenchmarks(types, assemblies, logger);\n            if (!allTypesValid) // there were some invalid and TypeFilter printed errors\n                return [];\n\n            if (allAvailableTypesWithRunnableBenchmarks.IsEmpty())\n            {\n                userInteraction.PrintNoBenchmarksError(logger);\n                return [];\n            }\n\n            if (options.ListBenchmarkCaseMode != ListBenchmarkCaseMode.Disabled)\n            {\n                PrintList(logger, effectiveConfig, allAvailableTypesWithRunnableBenchmarks, options);\n                return [];\n            }\n\n            var benchmarksToFilter = options.UserProvidedFilters || !askUserForInput\n                ? allAvailableTypesWithRunnableBenchmarks\n                : userInteraction.AskUser(allAvailableTypesWithRunnableBenchmarks, logger);\n\n            if (effectiveConfig.Options.HasFlag(ConfigOptions.ApplesToApples))\n            {\n                return ApplesToApples(ImmutableConfigBuilder.Create(effectiveConfig), benchmarksToFilter, logger, options);\n            }\n\n            var filteredBenchmarks = TypeFilter.Filter(effectiveConfig, benchmarksToFilter);\n\n            if (filteredBenchmarks.IsEmpty())\n            {\n                userInteraction.PrintWrongFilterInfo(benchmarksToFilter, logger, options.Filters.ToArray());\n                return [];\n            }\n\n            return BenchmarkRunnerClean.Run(filteredBenchmarks);\n        }\n\n        private static void PrintList(ILogger nonNullLogger, IConfig effectiveConfig, IReadOnlyList<Type> allAvailableTypesWithRunnableBenchmarks, CommandLineOptions options)\n        {\n            var printer = new BenchmarkCasesPrinter(options.ListBenchmarkCaseMode);\n\n            var testNames = TypeFilter.Filter(effectiveConfig, allAvailableTypesWithRunnableBenchmarks)\n                .SelectMany(p => p.BenchmarksCases)\n                .Select(p => p.Descriptor.GetFilterName())\n                .Distinct();\n\n            printer.Print(testNames, nonNullLogger);\n        }\n\n        private IEnumerable<Summary> ApplesToApples(ImmutableConfig effectiveConfig, IReadOnlyList<Type> benchmarksToFilter, ILogger logger, CommandLineOptions options)\n        {\n            var jobs = effectiveConfig.GetJobs().ToArray();\n            if (jobs.Length <= 1)\n            {\n                logger.WriteError(\"To use apples-to-apples comparison you must specify at least two Job objects.\");\n                return [];\n            }\n            var baselineJob = jobs.SingleOrDefault(job => job.Meta.Baseline);\n            if (baselineJob == default)\n            {\n                logger.WriteError(\"To use apples-to-apples comparison you must specify exactly ONE baseline Job object.\");\n                return [];\n            }\n            else if (jobs.Any(job => !job.Run.HasValue(RunMode.IterationCountCharacteristic)))\n            {\n                logger.WriteError(\"To use apples-to-apples comparison you must specify the number of iterations in explicit way.\");\n                return [];\n            }\n\n#pragma warning disable CS0618 // WithEvaluateOverhead is obsolete\n            Job invocationCountJob = baselineJob\n                .WithWarmupCount(1)\n                .WithIterationCount(1)\n                .WithEvaluateOverhead(false);\n#pragma warning restore CS0618 // WithEvaluateOverhead is obsolete\n\n            ManualConfig invocationCountConfig = ManualConfig.Create(effectiveConfig);\n            invocationCountConfig.RemoveAllJobs();\n            invocationCountConfig.RemoveAllDiagnosers();\n            invocationCountConfig.AddJob(invocationCountJob);\n\n            var invocationCountBenchmarks = TypeFilter.Filter(invocationCountConfig, benchmarksToFilter);\n            if (invocationCountBenchmarks.IsEmpty())\n            {\n                userInteraction.PrintWrongFilterInfo(benchmarksToFilter, logger, options.Filters.ToArray());\n                return [];\n            }\n\n            logger.WriteLineHeader(\"Each benchmark is going to be executed just once to get invocation counts.\");\n            Summary[] invocationCountSummaries = BenchmarkRunnerClean.Run(invocationCountBenchmarks);\n\n            Dictionary<(Descriptor Descriptor, ParameterInstances Parameters), Measurement> dictionary = invocationCountSummaries\n                .SelectMany(summary => summary.Reports)\n                .ToDictionary(\n                    report => (report.BenchmarkCase.Descriptor, report.BenchmarkCase.Parameters),\n                    report => report.AllMeasurements.Single(measurement => measurement.IsWorkload() && measurement.IterationStage == Engines.IterationStage.Actual));\n\n            int iterationCount = baselineJob.Run.IterationCount;\n            BenchmarkRunInfo[] benchmarksWithoutInvocationCount = TypeFilter.Filter(effectiveConfig, benchmarksToFilter);\n#pragma warning disable CS0618 // WithEvaluateOverhead is obsolete\n            BenchmarkRunInfo[] benchmarksWithInvocationCount = benchmarksWithoutInvocationCount\n                .Select(benchmarkInfo => new BenchmarkRunInfo(\n                    benchmarkInfo.BenchmarksCases.Select(benchmark =>\n                        new BenchmarkCase(\n                            benchmark.Descriptor,\n                            benchmark.Job\n                                .WithIterationCount(iterationCount)\n                                .WithEvaluateOverhead(false)\n                                .WithWarmupCount(1)\n                                .WithOutlierMode(OutlierMode.DontRemove)\n                                .WithInvocationCount(dictionary[(benchmark.Descriptor, benchmark.Parameters)].Operations)\n                                .WithUnrollFactor(dictionary[(benchmark.Descriptor, benchmark.Parameters)].Operations % 16 == 0 ? 16 : 1),\n                            benchmark.Parameters,\n                            benchmark.Config)).ToArray(),\n                    benchmarkInfo.Type, benchmarkInfo.Config, benchmarkInfo.CompositeInProcessDiagnoser))\n                .ToArray();\n#pragma warning restore CS0618 // WithEvaluateOverhead is obsolete\n\n            logger.WriteLineHeader(\"Actual benchmarking is going to happen now!\");\n            return BenchmarkRunnerClean.Run(benchmarksWithInvocationCount);\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Running/BuildPartition.cs",
    "content": "﻿using System;\nusing System.IO;\nusing System.Reflection;\nusing System.Threading;\nusing BenchmarkDotNet.Characteristics;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Detectors;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Helpers;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Portability;\nusing BenchmarkDotNet.Toolchains;\nusing BenchmarkDotNet.Toolchains.CsProj;\nusing BenchmarkDotNet.Toolchains.DotNetCli;\nusing BenchmarkDotNet.Toolchains.Roslyn;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Running\n{\n    public class BuildPartition\n    {\n        // We use an auto-increment global counter instead of Guid to guarantee uniqueness per benchmark run (Guid has a small chance to collide),\n        // assuming there are fewer than 4 billion build partitions (a safe assumption).\n        internal static int s_partitionCounter;\n\n        internal static readonly BuildPartition Empty = new();\n\n        public BuildPartition(BenchmarkBuildInfo[] benchmarks, IResolver resolver)\n        {\n            Resolver = resolver;\n            RepresentativeBenchmarkCase = benchmarks[0].BenchmarkCase;\n            Benchmarks = benchmarks;\n            ProgramName = GetProgramName(RepresentativeBenchmarkCase, Interlocked.Increment(ref s_partitionCounter));\n            LogBuildOutput = benchmarks[0].Config.Options.IsSet(ConfigOptions.LogBuildOutput);\n            GenerateMSBuildBinLog = benchmarks[0].Config.Options.IsSet(ConfigOptions.GenerateMSBuildBinLog);\n        }\n\n        private BuildPartition()\n        {\n            Resolver = default!;\n            RepresentativeBenchmarkCase = default!;\n            Benchmarks = [];\n            ProgramName = default!;\n        }\n\n        public BenchmarkBuildInfo[] Benchmarks { get; }\n\n        public string ProgramName { get; }\n\n        /// <summary>\n        /// the benchmarks are grouped by the build settings\n        /// so you can use this benchmark to get the runtime settings\n        /// </summary>\n        public BenchmarkCase RepresentativeBenchmarkCase { get; }\n\n        public IResolver Resolver { get; }\n\n        public string AssemblyLocation => GetResolvedAssemblyLocation(RepresentativeBenchmarkCase.Descriptor.Type.Assembly);\n\n        public string BuildConfiguration => RepresentativeBenchmarkCase.Job.ResolveValue(InfrastructureMode.BuildConfigurationCharacteristic, Resolver)!;\n\n        public Platform Platform => RepresentativeBenchmarkCase.Job.ResolveValue(EnvironmentMode.PlatformCharacteristic, Resolver);\n\n        [PublicAPI]\n        public Jit Jit => RepresentativeBenchmarkCase.Job.ResolveValue(EnvironmentMode.JitCharacteristic, Resolver);\n\n        public bool IsNativeAot => RepresentativeBenchmarkCase.Job.IsNativeAOT();\n\n        public bool IsNetFramework => Runtime is ClrRuntime\n            || (RepresentativeBenchmarkCase.Job.Infrastructure.TryGetToolchain(out var toolchain) && (toolchain is RoslynToolchain || toolchain is CsProjClassicNetToolchain));\n\n        public Runtime Runtime => RepresentativeBenchmarkCase.Job.Environment.GetRuntime();\n\n        public bool IsCustomBuildConfiguration => BuildConfiguration != InfrastructureMode.ReleaseConfigurationName;\n\n        public TimeSpan Timeout => IsNativeAot && RepresentativeBenchmarkCase.Config.BuildTimeout == DefaultConfig.Instance.BuildTimeout\n            ? TimeSpan.FromMinutes(5) // downloading all NativeAOT dependencies can take a LOT of time\n            : RepresentativeBenchmarkCase.Config.BuildTimeout;\n\n        public bool LogBuildOutput { get; }\n\n        public bool GenerateMSBuildBinLog { get; }\n\n        public override string ToString() => RepresentativeBenchmarkCase.Job.DisplayInfo;\n\n        private static string GetResolvedAssemblyLocation(Assembly assembly) =>\n            // in case of SingleFile, location.Length returns 0, so we use GetName() and\n            // manually construct the path.\n            assembly.Location.Length == 0 ? Path.Combine(AppContext.BaseDirectory, assembly.GetName().Name!) : assembly.Location;\n\n        internal static string GetProgramName(BenchmarkCase representativeBenchmarkCase, int id)\n        {\n            // Combine the benchmark's assembly name, folder info, and build partition id.\n            string benchmarkAssemblyName = representativeBenchmarkCase.Descriptor.Type.Assembly.GetName().Name!;\n            string folderInfo = representativeBenchmarkCase.Job.FolderInfo;\n            var programName = $\"{benchmarkAssemblyName}-{folderInfo}-{id}\";\n            // Very long program name can cause the path to exceed Windows' 260 character limit,\n            // for example BenchmarkDotNet.IntegrationTests.ManualRunning.MultipleFrameworks.\n            // 36 is an arbitrary limit, but it's the length of Guid strings which is what was used previously.\n            const int MaxLength = 36;\n            if (!OsDetector.IsWindows() || programName.Length <= MaxLength)\n            {\n                return programName;\n            }\n            programName = $\"{benchmarkAssemblyName}-{id}\";\n            if (programName.Length <= MaxLength)\n            {\n                return programName;\n            }\n            programName = $\"{folderInfo}-{id}\";\n            if (programName.Length <= MaxLength)\n            {\n                return programName;\n            }\n            return id.ToString();\n        }\n\n        internal bool ForcedNoDependenciesForIntegrationTests\n        {\n            get\n            {\n                if (!XUnitHelper.IsIntegrationTest.Value || !RuntimeInformation.IsNetCore)\n                    return false;\n\n                var job = RepresentativeBenchmarkCase.Job;\n                if (job.GetToolchain().Builder is not DotNetCliBuilder)\n                    return false;\n\n                return !job.HasDynamicBuildCharacteristic();\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Running/ConsoleTitler.cs",
    "content": "﻿using System;\nusing System.IO;\nusing System.Runtime.Versioning;\nusing BenchmarkDotNet.Detectors;\nusing BenchmarkDotNet.Helpers;\n\nnamespace BenchmarkDotNet.Running\n{\n    /// <summary>\n    /// Updates Console.Title, subject to platform capabilities and Console availability.\n    /// Restores the original (or fallback) title upon disposal.\n    /// </summary>\n    internal class ConsoleTitler : DisposeAtProcessTermination\n    {\n        /// <summary>\n        /// Whether this instance has any effect. This will be false if the platform doesn't support Console retitling,\n        /// or if Console output is redirected.\n        /// </summary>\n        public bool IsEnabled { get; private set; }\n\n        private string oldConsoleTitle = \"\";\n\n        public ConsoleTitler(string initialTitle)\n        {\n            try\n            {\n                // Return without enabling if Console output is redirected.\n                if (Console.IsOutputRedirected)\n                {\n                    return;\n                }\n            }\n            catch (PlatformNotSupportedException)\n            {\n                // Ignore the exception. Some platforms do not support Console.IsOutputRedirected.\n            }\n\n            try\n            {\n                oldConsoleTitle = PlatformSupportsTitleRead() ? Console.Title : \"\";\n            }\n            catch (IOException)\n            {\n                // We're unable to read Console.Title on a platform that supports it. This can happen when no console\n                // window is available due to the application being Windows Forms, WPF, Windows Service or a daemon.\n                oldConsoleTitle = \"\";\n            }\n\n            try\n            {\n                // Enable ConsoleTitler if and only if we can successfully set the Console.Title property.\n                Console.Title = initialTitle;\n                IsEnabled = true;\n            }\n            catch (IOException)\n            {\n            }\n            catch (PlatformNotSupportedException)\n            {\n                // As of .NET 7, platforms other than Windows, Linux and MacOS do not support Console retitling.\n            }\n        }\n\n        [SupportedOSPlatformGuard(\"windows\")]\n        private static bool PlatformSupportsTitleRead() => OsDetector.IsWindows();\n\n        /// <summary>\n        /// Updates Console.Title if enabled.\n        /// </summary>\n        public void UpdateTitle(string title)\n        {\n            if (IsEnabled)\n            {\n                Console.Title = title;\n            }\n        }\n\n        public override void Dispose()\n        {\n            if (IsEnabled)\n            {\n                Console.Title = oldConsoleTitle;\n                IsEnabled = false;\n            }\n            base.Dispose();\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Running/DefaultCategoryDiscoverer.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Reflection;\nusing BenchmarkDotNet.Attributes;\n\nnamespace BenchmarkDotNet.Running\n{\n    public class DefaultCategoryDiscoverer : ICategoryDiscoverer\n    {\n        public static readonly ICategoryDiscoverer Instance = new DefaultCategoryDiscoverer();\n\n        private readonly bool inherit;\n\n        public DefaultCategoryDiscoverer(bool inherit = true)\n        {\n            this.inherit = inherit;\n        }\n\n        public virtual string[] GetCategories(MethodInfo method)\n        {\n            var attributes = new List<BenchmarkCategoryAttribute>();\n            attributes.AddRange(method.GetCustomAttributes(typeof(BenchmarkCategoryAttribute), inherit).OfType<BenchmarkCategoryAttribute>());\n            var type = method.ReflectedType;\n            if (type != null)\n            {\n                attributes.AddRange(type.GetTypeInfo().GetCustomAttributes(typeof(BenchmarkCategoryAttribute), inherit).OfType<BenchmarkCategoryAttribute>());\n                attributes.AddRange(type.GetTypeInfo().Assembly.GetCustomAttributes().OfType<BenchmarkCategoryAttribute>());\n            }\n            if (attributes.Count == 0)\n                return [];\n            return attributes.SelectMany(attr => attr.Categories).Distinct(StringComparer.OrdinalIgnoreCase).ToArray();\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Running/Descriptor.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing System.Reflection;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Helpers;\nusing BenchmarkDotNet.Portability;\n\nnamespace BenchmarkDotNet.Running\n{\n    public class Descriptor : IEquatable<Descriptor>\n    {\n        public Type Type { get; }\n        public MethodInfo WorkloadMethod { get; }\n        public MethodInfo? GlobalSetupMethod { get; }\n        public MethodInfo? GlobalCleanupMethod { get; }\n        public MethodInfo? IterationSetupMethod { get; }\n        public MethodInfo? IterationCleanupMethod { get; }\n        public int OperationsPerInvoke { get; }\n        public string WorkloadMethodDisplayInfo { get; }\n        public int MethodIndex { get; }\n        public bool Baseline { get; }\n        public string[] Categories { get; }\n\n        internal string TypeInfo => Type.GetDisplayName();\n        private string MethodFolderInfo => WorkloadMethod.Name;\n\n        public string FolderInfo => $\"{FolderNameHelper.ToFolderName(Type)}_{MethodFolderInfo}\";\n        public string DisplayInfo => TypeInfo + \".\" + WorkloadMethodDisplayInfo;\n\n        public Descriptor(\n            Type type,\n            MethodInfo workloadMethod,\n            MethodInfo? globalSetupMethod = null,\n            MethodInfo? globalCleanupMethod = null,\n            MethodInfo? iterationSetupMethod = null,\n            MethodInfo? iterationCleanupMethod = null,\n            string? description = null,\n            bool baseline = false,\n            string[]? categories = null,\n            int operationsPerInvoke = 1,\n            int methodIndex = 0)\n        {\n            Assertion.NotNull(nameof(type), type);\n            Assertion.NotNull(nameof(workloadMethod), workloadMethod);\n\n            Type = type;\n            WorkloadMethod = workloadMethod;\n            GlobalSetupMethod = globalSetupMethod;\n            GlobalCleanupMethod = globalCleanupMethod;\n            IterationSetupMethod = iterationSetupMethod;\n            IterationCleanupMethod = iterationCleanupMethod;\n            OperationsPerInvoke = operationsPerInvoke;\n            WorkloadMethodDisplayInfo = FormatDescription(description) ?? workloadMethod?.Name ?? \"Untitled\";\n            Baseline = baseline;\n            Categories = categories ?? [];\n            MethodIndex = methodIndex;\n        }\n\n        public override string ToString() => DisplayInfo;\n\n        private static string? FormatDescription(string? description)\n        {\n            char[] specialSymbols = [' ', '\\'', '[', ']'];\n            return description != null && specialSymbols.Any(description.Contains)\n                ? \"'\" + description + \"'\"\n                : description;\n        }\n\n        public bool HasCategory(string category) => Categories.Any(c => c.EqualsWithIgnoreCase(category));\n\n        public string GetFilterName() => $\"{Type.GetCorrectCSharpTypeName(includeGenericArgumentsNamespace: false, prefixWithGlobal: false)}.{WorkloadMethod.Name}\";\n\n        public bool Equals(Descriptor? other) => GetFilterName().Equals(other?.GetFilterName());\n\n        public override bool Equals(object? obj) => obj is Descriptor descriptor && Equals(descriptor);\n\n        public override int GetHashCode() => GetFilterName().GetHashCode();\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Running/DescriptorComparer.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing BenchmarkDotNet.Order;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Running\n{\n    internal class DescriptorComparer : IComparer<Descriptor>\n    {\n        [PublicAPI] public static readonly IComparer<Descriptor> Alphabetical = new DescriptorComparer(MethodOrderPolicy.Alphabetical);\n        [PublicAPI] public static readonly IComparer<Descriptor> Declared = new DescriptorComparer(MethodOrderPolicy.Declared);\n\n        private readonly MethodOrderPolicy methodOrderPolicy;\n\n        public DescriptorComparer(MethodOrderPolicy methodOrderPolicy)\n        {\n            this.methodOrderPolicy = methodOrderPolicy;\n        }\n\n        public int Compare(Descriptor? x, Descriptor? y)\n        {\n            if (ReferenceEquals(x, y)) return 0;\n            if (x is null) return -1;\n            if (y is null) return 1;\n\n            switch (methodOrderPolicy)\n            {\n                case MethodOrderPolicy.Alphabetical:\n                    return string.CompareOrdinal(x.DisplayInfo, y.DisplayInfo);\n                case MethodOrderPolicy.Declared:\n                    return x.MethodIndex - y.MethodIndex;\n                default:\n                    throw new NotSupportedException($\"methodOrderPolicy = {methodOrderPolicy}\");\n            }\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Running/ICategoryDiscoverer.cs",
    "content": "using System.Reflection;\n\nnamespace BenchmarkDotNet.Running\n{\n    public interface ICategoryDiscoverer\n    {\n        string[] GetCategories(MethodInfo method);\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Running/IUserInteraction.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing BenchmarkDotNet.Loggers;\n\nnamespace BenchmarkDotNet.Running\n{\n    internal interface IUserInteraction\n    {\n        void PrintNoBenchmarksError(ILogger logger);\n\n        void PrintWrongFilterInfo(IReadOnlyList<Type> allTypes, ILogger logger, string[] userFilters);\n\n        IReadOnlyList<Type> AskUser(IReadOnlyList<Type> allTypes, ILogger logger);\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Running/InvalidBenchmarkDeclarationException.cs",
    "content": "using System;\n\nnamespace BenchmarkDotNet.Running\n{\n    public class InvalidBenchmarkDeclarationException : Exception\n    {\n        public InvalidBenchmarkDeclarationException(string message) : base(message) { }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Running/PowerManagementApplier.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing BenchmarkDotNet.Detectors;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Helpers;\nusing BenchmarkDotNet.Loggers;\n\nnamespace BenchmarkDotNet.Running\n{\n    internal class PowerManagementApplier : DisposeAtProcessTermination\n    {\n        private static readonly Guid UserPowerPlan = new Guid(\"67b4a053-3646-4532-affd-0535c9ea82a7\");\n\n        private static readonly Dictionary<PowerPlan, Guid> PowerPlansDict = new Dictionary<PowerPlan, Guid>()\n        {\n            { PowerPlan.UserPowerPlan, UserPowerPlan },\n            { PowerPlan.HighPerformance, new Guid(\"8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c\") },\n            { PowerPlan.PowerSaver, new Guid(\"a1841308-3541-4fab-bc81-f71556f20b4a\") },\n            { PowerPlan.Balanced, new Guid(\"381b4222-f694-41f0-9685-ff5bb260df2e\") },\n            { PowerPlan.UltimatePerformance, new Guid(\"e9a42b02-d5df-448d-aa00-03f14749eb61\") },\n        };\n\n        private readonly ILogger logger;\n        private Guid? userCurrentPowerPlan;\n        private bool powerPlanChanged;\n        private bool isInitialized;\n\n        internal PowerManagementApplier(ILogger logger) => this.logger = logger;\n\n        public override void Dispose()\n        {\n            ApplyUserPowerPlan();\n            base.Dispose();\n        }\n\n        internal static Guid Map(PowerPlan value) => PowerPlansDict[value];\n\n        internal void ApplyPerformancePlan(Guid id)\n        {\n            if (!OsDetector.IsWindows() || id == Guid.Empty)\n                return;\n\n            if (id != UserPowerPlan)\n                ApplyPlanByGuid(id);\n            else\n                ApplyUserPowerPlan();\n        }\n\n        private void ApplyUserPowerPlan()\n        {\n            if (powerPlanChanged && OsDetector.IsWindows())\n            {\n                try\n                {\n                    if (userCurrentPowerPlan != null && PowerManagementHelper.Set(userCurrentPowerPlan.Value))\n                    {\n                        powerPlanChanged = false;\n                        var powerPlanFriendlyName = PowerManagementHelper.CurrentPlanFriendlyName;\n                        logger.WriteLineInfo($\"Successfully reverted power plan (GUID: {userCurrentPowerPlan.Value} FriendlyName: {powerPlanFriendlyName})\");\n                    }\n                }\n                catch (Exception ex)\n                {\n                    logger.WriteLineError($\"Cannot revert power plan (error message: {ex.Message})\");\n                }\n            }\n        }\n\n        private void ApplyPlanByGuid(Guid guid)\n        {\n            try\n            {\n                if (isInitialized == false)\n                {\n                    userCurrentPowerPlan = PowerManagementHelper.CurrentPlan;\n                    isInitialized = true;\n                }\n\n                if (PowerManagementHelper.Set(guid))\n                {\n                    powerPlanChanged = true;\n                    var powerPlanFriendlyName = PowerManagementHelper.CurrentPlanFriendlyName;\n                    logger.WriteLineInfo($\"Setup power plan (GUID: {guid} FriendlyName: {powerPlanFriendlyName})\");\n                }\n                else\n                    logger.WriteLineError($\"Cannot setup power plan (GUID: {guid})\");\n            }\n            catch (Exception ex)\n            {\n                logger.WriteLineError($\"Cannot setup power plan (GUID: {guid}, error message: {ex.Message})\");\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Running/TypeFilter.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Reflection;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Helpers;\nusing BenchmarkDotNet.Loggers;\n\nnamespace BenchmarkDotNet.Running\n{\n    public static class TypeFilter\n    {\n        public static (bool allTypesValid, IReadOnlyList<Type> runnable) GetTypesWithRunnableBenchmarks(IEnumerable<Type> types, IEnumerable<Assembly> assemblies, ILogger logger)\n        {\n            var validRunnableTypes = new List<Type>();\n\n            bool hasRunnableTypeBenchmarks = types.Any(type => type.ContainsRunnableBenchmarks());\n            bool hasRunnableAssemblyBenchmarks = assemblies.Any(assembly => GenericBenchmarksBuilder.GetRunnableBenchmarks(assembly.GetRunnableBenchmarks()).Length > 0);\n\n            if (!hasRunnableTypeBenchmarks && !hasRunnableAssemblyBenchmarks)\n            {\n                if (types.Any())\n                {\n                    foreach (var type in types)\n                    {\n                        logger.WriteLineError($\"No [Benchmark] attribute found on '{type.Name}' benchmark case.\");\n                    }\n                }\n                else if (assemblies.Any())\n                {\n                    foreach (var assembly in assemblies)\n                    {\n                        logger.WriteLineError($\"No [Benchmark] attribute found on '{assembly.GetName().Name}' assembly.\");\n                    }\n                }\n                else\n                {\n                    logger.WriteLineError(\"No benchmarks were found.\");\n                }\n                return (false, Array.Empty<Type>());\n            }\n\n            foreach (var type in types)\n            {\n                if (type.ContainsRunnableBenchmarks())\n                {\n                    validRunnableTypes.AddRange(GenericBenchmarksBuilder.BuildGenericsIfNeeded(type).Where(tuple => tuple.isSuccess).Select(tuple => tuple.result));\n                }\n                else\n                {\n                    logger.WriteLineError($\"Type {type} is invalid. Only public, non-generic (closed generic types with public parameterless ctors are supported), non-abstract, non-sealed, non-static types with public instance [Benchmark] method(s) are supported.\");\n\n                    return (false, Array.Empty<Type>());\n                }\n            }\n\n            foreach (var assembly in assemblies)\n            {\n                validRunnableTypes.AddRange(GenericBenchmarksBuilder.GetRunnableBenchmarks(assembly.GetRunnableBenchmarks()));\n            }\n\n            return (true, validRunnableTypes);\n        }\n\n        public static BenchmarkRunInfo[] Filter(IConfig effectiveConfig, IEnumerable<Type> types)\n            => types\n                .Select(type => BenchmarkConverter.TypeToBenchmarks(type, effectiveConfig))\n                .Where(info => info.BenchmarksCases.Any())\n                .ToArray();\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Running/UserInteraction.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Globalization;\nusing System.Linq;\nusing BenchmarkDotNet.ConsoleArguments;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Helpers;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Portability;\n\nnamespace BenchmarkDotNet.Running\n{\n    internal class UserInteraction : IUserInteraction\n    {\n        private static bool consoleCancelKeyPressed;\n\n        static UserInteraction() => Console.CancelKeyPress += (_, __) => consoleCancelKeyPressed = true;\n\n        public void PrintNoBenchmarksError(ILogger logger)\n        {\n            logger.WriteError(\"No benchmarks to choose from. Make sure you provided public non-sealed non-static types with public [Benchmark] methods.\");\n        }\n\n        public IReadOnlyList<Type> AskUser(IReadOnlyList<Type> allTypes, ILogger logger)\n        {\n            var selectedTypes = new List<Type>();\n            string benchmarkCaptionExample = allTypes.First().GetDisplayName();\n\n            while (selectedTypes.Count == 0 && !consoleCancelKeyPressed)\n            {\n                PrintAvailable(allTypes, logger);\n\n                if (consoleCancelKeyPressed)\n                    break;\n\n                string filterExample = \"--filter \" + UserInteractionHelper.EscapeCommandExample($\"*{benchmarkCaptionExample}*\");\n                logger.WriteLineHelp($\"You should select the target benchmark(s). Please, print a number of a benchmark (e.g. `0`) or a contained benchmark caption (e.g. `{benchmarkCaptionExample}`).\");\n                logger.WriteLineHelp(\"If you want to select few, please separate them with space ` ` (e.g. `1 2 3`).\");\n                logger.WriteLineHelp($\"You can also provide the class name in console arguments by using --filter. (e.g. `{filterExample}`).\");\n                logger.WriteLineHelp($\"Enter the asterisk `*` to select all.\");\n\n                string? userInput = Console.ReadLine();\n                if (userInput == null)\n                {\n                    break;\n                }\n\n                selectedTypes.AddRange(GetMatching(allTypes, userInput.Split([' '], StringSplitOptions.RemoveEmptyEntries)));\n                logger.WriteLine();\n            }\n\n            return selectedTypes;\n        }\n\n        public void PrintWrongFilterInfo(IReadOnlyList<Type> allTypes, ILogger logger, string[] userFilters)\n        {\n            var correctionSuggester = new CorrectionsSuggester(allTypes);\n\n            var filterToNames = userFilters\n                .Select(userFilter => (userFilter: userFilter, suggestedBenchmarkNames: correctionSuggester.SuggestFor(userFilter)))\n                .ToArray();\n\n            foreach ((string userFilter, var suggestedBenchmarkNames) in filterToNames)\n                if (!suggestedBenchmarkNames.IsEmpty())\n                {\n                    logger.WriteLine($\"You must have made a typo in '{userFilter}'. Suggestions:\");\n                    foreach (string displayName in suggestedBenchmarkNames.Take(40))\n                        logger.WriteLineInfo($\"\\t{displayName}\");\n                }\n\n            var unknownFilters = filterToNames.Where(u => u.suggestedBenchmarkNames.IsEmpty()).Select(u => u.userFilter).ToArray();\n            string unknownBenchmarks = string.Join(\"', '\", unknownFilters);\n\n            if (unknownBenchmarks.IsNotBlank())\n            {\n                logger.WriteLineError($\"{(unknownFilters.Length == 1 ? \"The filter\" : \"Filters\")} '{unknownBenchmarks}' that you have provided returned 0 benchmarks.\");\n                logger.WriteLineInfo(\"Please remember that the filter is applied to full benchmark name: `namespace.typeName.methodName`.\");\n\n                foreach (string displayName in correctionSuggester.GetAllBenchmarkNames().Take(40))\n                    logger.WriteLineInfo($\"\\t{displayName}\");\n            }\n\n            logger.WriteLineInfo(\"To print all available benchmarks use `--list flat` or `--list tree`.\");\n            logger.WriteLineInfo(\"To learn more about filtering use `--help`.\");\n        }\n\n        private static IEnumerable<Type> GetMatching(IReadOnlyList<Type> allTypes, string[] userInput)\n        {\n            if (userInput.IsEmpty())\n                yield break;\n\n            var integerInput = userInput.Where(arg => IsInteger(arg)).ToArray();\n            var stringInput = userInput.Where(arg => !IsInteger(arg)).ToArray();\n\n            for (int i = 0; i < allTypes.Count; i++)\n            {\n                var type = allTypes[i];\n\n                if (stringInput.Any(arg => type.GetDisplayName().ContainsWithIgnoreCase(arg))\n                    || stringInput.Contains($\"#{i}\")\n                    || integerInput.Contains($\"{i}\")\n                    || stringInput.Contains(\"*\"))\n                {\n                    yield return type;\n                }\n            }\n\n            static bool IsInteger(string str) => int.TryParse(str, out _);\n        }\n\n        private static void PrintAvailable(IReadOnlyList<Type> allTypes, ILogger logger)\n        {\n            logger.WriteLineHelp($\"Available Benchmark{(allTypes.Count > 1 ? \"s\" : \"\")}:\");\n\n            int numberWidth = allTypes.Count.ToString().Length;\n            for (int i = 0; i < allTypes.Count && !consoleCancelKeyPressed; i++)\n                logger.WriteLineHelp(string.Format(CultureInfo.InvariantCulture, \"  #{0} {1}\", i.ToString().PadRight(numberWidth), allTypes[i].GetDisplayName()));\n\n            if (!consoleCancelKeyPressed)\n            {\n                logger.WriteLine();\n                logger.WriteLine();\n            }\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Running/WakeLock.PInvoke.cs",
    "content": "﻿using System;\nusing System.ComponentModel;\nusing System.Runtime.InteropServices;\n\nnamespace BenchmarkDotNet.Running;\n\ninternal partial class WakeLock\n{\n    private static class PInvoke\n    {\n        public static SafePowerHandle PowerCreateRequest(string reason)\n        {\n            IntPtr reasonPtr = Marshal.StringToHGlobalAuto(reason);\n            try\n            {\n                REASON_CONTEXT context = new REASON_CONTEXT()\n                {\n                    Version = POWER_REQUEST_CONTEXT_VERSION,\n                    Flags = POWER_REQUEST_CONTEXT_FLAGS.POWER_REQUEST_CONTEXT_SIMPLE_STRING,\n                    Reason = new REASON_CONTEXT.REASON_CONTEXT_UNION { SimpleReasonString = reasonPtr }\n\n                };\n                SafePowerHandle safePowerHandle = PowerCreateRequest(context);\n                if (safePowerHandle.IsInvalid) { throw new Win32Exception(); }\n                return safePowerHandle;\n            }\n            finally\n            {\n                if (reasonPtr != IntPtr.Zero)\n                {\n                    Marshal.FreeHGlobal(reasonPtr);\n                }\n            }\n        }\n\n        [DllImport(\"kernel32.dll\", ExactSpelling = true, SetLastError = true)]\n        private static extern SafePowerHandle PowerCreateRequest(REASON_CONTEXT Context);\n\n        public static void PowerSetRequest(SafePowerHandle safePowerHandle, POWER_REQUEST_TYPE requestType)\n        {\n            if (!InvokePowerSetRequest(safePowerHandle, requestType))\n            {\n                throw new Win32Exception();\n            }\n        }\n\n        [DllImport(\"kernel32.dll\", EntryPoint = \"PowerSetRequest\", ExactSpelling = true, SetLastError = true)]\n        private static extern bool InvokePowerSetRequest(SafePowerHandle PowerRequest, POWER_REQUEST_TYPE RequestType);\n\n        public static void PowerClearRequest(SafePowerHandle safePowerHandle, POWER_REQUEST_TYPE requestType)\n        {\n            if (!InvokePowerClearRequest(safePowerHandle, requestType))\n            {\n                throw new Win32Exception();\n            }\n        }\n\n        [DllImport(\"kernel32.dll\", EntryPoint = \"PowerClearRequest\", ExactSpelling = true, SetLastError = true)]\n        private static extern bool InvokePowerClearRequest(SafePowerHandle PowerRequest, POWER_REQUEST_TYPE RequestType);\n\n        [DllImport(\"kernel32.dll\", ExactSpelling = true, SetLastError = true)]\n        public static extern bool CloseHandle(nint hObject);\n\n        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]\n        private struct REASON_CONTEXT\n        {\n            public uint Version;\n\n            public POWER_REQUEST_CONTEXT_FLAGS Flags;\n\n            public REASON_CONTEXT_UNION Reason;\n\n            [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode)]\n            public struct REASON_CONTEXT_UNION\n            {\n                [FieldOffset(0)]\n                public nint SimpleReasonString;\n\n                // The DETAILED structure is not (yet) used, but needed for ARM CPUs, otherwise PowerCreateRequest fails, see #2745\n                [FieldOffset(0)]\n                public DETAILED Detailed;\n\n                [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]\n                public struct DETAILED\n                {\n                    public nint LocalizedReasonModule;\n                    public uint LocalizedReasonId;\n                    public uint ReasonStringCount;\n                    public nint ReasonStrings;\n                }\n            }\n        }\n\n        private const uint POWER_REQUEST_CONTEXT_VERSION = 0U;\n\n        private enum POWER_REQUEST_CONTEXT_FLAGS : uint\n        {\n            POWER_REQUEST_CONTEXT_DETAILED_STRING = 2U,\n            POWER_REQUEST_CONTEXT_SIMPLE_STRING = 1U,\n        }\n\n        public enum POWER_REQUEST_TYPE\n        {\n            PowerRequestDisplayRequired = 0,\n            PowerRequestSystemRequired = 1,\n            PowerRequestAwayModeRequired = 2,\n            PowerRequestExecutionRequired = 3,\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Running/WakeLock.SafePowerHandle.cs",
    "content": "﻿using Microsoft.Win32.SafeHandles;\n\nnamespace BenchmarkDotNet.Running;\n\ninternal partial class WakeLock\n{\n    private sealed class SafePowerHandle : SafeHandleZeroOrMinusOneIsInvalid\n    {\n        private SafePowerHandle() : base(true) { }\n\n        protected override bool ReleaseHandle() => PInvoke.CloseHandle(handle);\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Running/WakeLock.cs",
    "content": "﻿using BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Detectors;\nusing BenchmarkDotNet.Helpers;\nusing BenchmarkDotNet.Loggers;\nusing System;\nusing System.ComponentModel;\nusing System.Linq;\n\nnamespace BenchmarkDotNet.Running;\n\ninternal partial class WakeLock\n{\n    public static WakeLockType GetWakeLockType(BenchmarkRunInfo[] benchmarkRunInfos) =>\n        benchmarkRunInfos.Length == 0 ? WakeLockType.None : benchmarkRunInfos.Select(static i => i.Config.WakeLock).Max();\n\n    private static readonly bool OsVersionIsSupported =\n        // Must be windows 7 or greater\n        OsDetector.IsWindows() && Environment.OSVersion.Version >= new Version(6, 1);\n\n    public static IDisposable? Request(WakeLockType wakeLockType, string reason, ILogger logger) =>\n        wakeLockType == WakeLockType.None || !OsVersionIsSupported ? null : new WakeLockSentinel(wakeLockType, reason, logger);\n\n    private class WakeLockSentinel : DisposeAtProcessTermination\n    {\n        private readonly WakeLockType wakeLockType;\n        private readonly SafePowerHandle? safePowerHandle;\n        private readonly ILogger logger;\n\n        public WakeLockSentinel(WakeLockType wakeLockType, string reason, ILogger logger)\n        {\n            this.wakeLockType = wakeLockType;\n            this.logger = logger;\n            try\n            {\n                safePowerHandle = PInvoke.PowerCreateRequest(reason);\n                PInvoke.PowerSetRequest(safePowerHandle, PInvoke.POWER_REQUEST_TYPE.PowerRequestSystemRequired);\n                if (wakeLockType == WakeLockType.Display)\n                {\n                    PInvoke.PowerSetRequest(safePowerHandle, PInvoke.POWER_REQUEST_TYPE.PowerRequestDisplayRequired);\n                }\n            }\n            catch (Win32Exception ex)\n            {\n                logger.WriteLineError($\"Unable to prevent the system from entering sleep or turning off the display (error message: {ex.Message}).\");\n            }\n        }\n\n        public override void Dispose()\n        {\n            if (safePowerHandle != null)\n            {\n                try\n                {\n                    if (wakeLockType == WakeLockType.Display)\n                    {\n                        PInvoke.PowerClearRequest(safePowerHandle, PInvoke.POWER_REQUEST_TYPE.PowerRequestDisplayRequired);\n                    }\n                    PInvoke.PowerClearRequest(safePowerHandle, PInvoke.POWER_REQUEST_TYPE.PowerRequestSystemRequired);\n                }\n                catch (Win32Exception ex)\n                {\n                    logger.WriteLineError($\"Unable to allow the system from entering sleep or turning off the display (error message: {ex.Message}).\");\n                }\n                safePowerHandle.Dispose();\n            }\n            base.Dispose();\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Serialization/BdnJsonSerializer.cs",
    "content": "﻿using System.Text.Encodings.Web;\nusing System.Text.Json;\nusing System.Text.Json.Serialization;\n\nnamespace BenchmarkDotNet.Serialization;\n\ninternal static class BdnJsonSerializer\n{\n    private static readonly JsonSerializerOptions DefaultOptions = new()\n    {\n        Converters =\n        {\n            new JsonStringEnumConverter(),\n        },\n        DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,\n        DictionaryKeyPolicy = JsonNamingPolicy.CamelCase,\n        // Disable escaping non ASCII chars. https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json/character-encoding#serialize-all-characters\n        Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, // TODO: Replace to custom encoder that escape minimal chars. (https://github.com/dotnet/runtime/issues/87153)\n        NumberHandling = JsonNumberHandling.AllowNamedFloatingPointLiterals, // Required to support NaN\n        PropertyNameCaseInsensitive = true, // Accept PascalNaming that generated by JsonExporter.\n        PropertyNamingPolicy = JsonNamingPolicy.CamelCase,\n        RespectNullableAnnotations = true,\n        TypeInfoResolverChain =\n        {\n            BdnJsonSerializerContext.Default,\n        },\n        UnmappedMemberHandling = JsonUnmappedMemberHandling.Disallow, // Throw error if unknown entry exists.\n    };\n\n    private static readonly JsonSerializerOptions IndentedOptions = new(DefaultOptions)\n    {\n        WriteIndented = true,\n    };\n\n    public static string Serialize<T>(T item, bool indentJson = false)\n    {\n        if (indentJson)\n            return JsonSerializer.Serialize(item, IndentedOptions);\n        else\n            return JsonSerializer.Serialize(item, DefaultOptions);\n    }\n\n    public static T? Deserialize<T>(string json)\n    {\n        return JsonSerializer.Deserialize<T>(json, DefaultOptions);\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Serialization/BdnJsonSerializerContext.cs",
    "content": "﻿using BenchmarkDotNet.Disassemblers;\nusing System.Text.Json.Serialization;\n\nnamespace BenchmarkDotNet.Serialization;\n\n[JsonSerializable(typeof(ClrMdArgs))]\n[JsonSerializable(typeof(Sharp))]\n[JsonSerializable(typeof(MonoCode))]\n[JsonSerializable(typeof(IntelAsm))]\n[JsonSerializable(typeof(Arm64Asm))]\n[JsonSerializable(typeof(Map))]\n[JsonSerializable(typeof(DisassembledMethod))]\n[JsonSerializable(typeof(DisassemblyResult))]\ninternal partial class BdnJsonSerializerContext : JsonSerializerContext\n{\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Serialization/BdnSimpleJsonSerializer.cs",
    "content": "﻿using System;\nusing System.Text.Encodings.Web;\nusing System.Text.Json;\nusing System.Text.Json.Serialization;\nusing System.Text.Json.Serialization.Metadata;\n\nnamespace BenchmarkDotNet.Serialization;\n\n/// <summary>\n/// JsonSerializer that compatible with JsonExporter format.\n/// </summary>\ninternal static class BdnSimpleJsonSerializer\n{\n    private static readonly JsonSerializerOptions DefaultOptions = new()\n    {\n        Converters =\n        {\n            new SimpleJsonFloatConverter(),\n            new SimpleJsonDoubleConverter(),\n        },\n        // Disable escaping non ASCII chars. https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json/character-encoding#serialize-all-characters\n        Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,\n        TypeInfoResolverChain =\n        {\n            // Use Reflection based serialization/deserialization. Because Summary object contains anonymous type.\n            new DefaultJsonTypeInfoResolver(),\n        },\n        RespectNullableAnnotations = true,\n    };\n\n    private static readonly JsonSerializerOptions IndentedOptions = new(DefaultOptions)\n    {\n        WriteIndented = true,\n    };\n\n    public static string Serialize<T>(T item, bool indentJson = false)\n    {\n        if (indentJson)\n            return JsonSerializer.Serialize(item, IndentedOptions);\n        else\n            return JsonSerializer.Serialize(item, DefaultOptions);\n    }\n\n    /// <summary>\n    /// Custom JsonConverter for float that write Nan/PositiveInfinite/NegativeInfinite as empty string.\n    /// </summary>\n    private class SimpleJsonFloatConverter : JsonConverter<float>\n    {\n        public override float Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)\n        {\n            if (reader.TokenType == JsonTokenType.Number)\n                return reader.GetSingle();\n\n            throw new JsonException($\"Unexpected token {reader.TokenType} when parsing float.\");\n        }\n\n        public override void Write(Utf8JsonWriter writer, float value, JsonSerializerOptions options)\n        {\n            if (float.IsNaN(value) || float.IsInfinity(value))\n                writer.WriteStringValue(\"\");\n            else\n                writer.WriteNumberValue(value);\n        }\n    }\n\n    /// <summary>\n    /// Custom JsonConverter for double that write Nan/PositiveInfinite/NegativeInfinite as empty string.\n    /// </summary>\n    private class SimpleJsonDoubleConverter : JsonConverter<double>\n    {\n        public override double Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)\n        {\n            if (reader.TokenType == JsonTokenType.Number)\n                return reader.GetSingle();\n\n            throw new JsonException($\"Unexpected token {reader.TokenType} when parsing double.\");\n        }\n\n        public override void Write(Utf8JsonWriter writer, double value, JsonSerializerOptions options)\n        {\n            if (double.IsNaN(value) || double.IsInfinity(value))\n                writer.WriteStringValue(\"\");\n            else\n                writer.WriteNumberValue(value);\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Templates/BenchmarkProgram.txt",
    "content": "$ShadowCopyDefines$\n$ExtraDefines$\n// <auto-generated />\n// this file must not be importing any namespaces\n// we should use full names everywhere to avoid any potential naming conflicts, example: #1007, #778\n\n#if !NET7_0_OR_GREATER\n// User code could poly-fill the type and leave it public, so we disable the warning just in case.\n#pragma warning disable CS0436 // Type conflicts with imported type\nnamespace System.Diagnostics.CodeAnalysis\n{\n    [global::System.AttributeUsage(global::System.AttributeTargets.Constructor, AllowMultiple = false, Inherited = false)]\n    [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]\n    internal sealed class SetsRequiredMembersAttribute : global::System.Attribute\n    {\n    }\n}\n#endif\n\n// the namespace name must be in sync with DisassemblyDiagnoser.BuildClrMdArgs\nnamespace BenchmarkDotNet.Autogenerated\n{\n    public class UniqueProgramName // we need different name than typical \"Program\" to avoid problems with referencing \"Program\" types from benchmarked code, #691\n    {\n        $ExtraAttribute$\n        public static global::System.Int32 Main(global::System.String[] args)\n        {\n            // this method MUST NOT have any dependencies to BenchmarkDotNet and any other external dlls! (CoreRT is exception from this rule)\n            // otherwise if LINQPad's shadow copy is enabled, we will not register for AssemblyLoading event\n            // before .NET Framework tries to load it for this method\n#if NETFRAMEWORK\n            using(new DirtyAssemblyResolveHelper())\n#endif\n                return AfterAssemblyLoadingAttached(args);\n        }\n\n        private static global::System.Int32 AfterAssemblyLoadingAttached(global::System.String[] args)\n        {\n            global::BenchmarkDotNet.Engines.IHost host; // this variable name is used by CodeGenerator.GetBenchmarkRunCall, do NOT change it\n            if (global::BenchmarkDotNet.Engines.AnonymousPipesHost.TryGetFileHandles(args, out global::System.String writeHandle, out global::System.String readHandle))\n                host = new global::BenchmarkDotNet.Engines.AnonymousPipesHost(writeHandle, readHandle);\n            else\n                host = new global::BenchmarkDotNet.Engines.NoAcknowledgementConsoleHost();\n\n            // the first thing to do is to let diagnosers hook in before anything happens\n            // so all jit-related diagnosers can catch first jit compilation!\n            global::BenchmarkDotNet.Engines.HostExtensions.BeforeAnythingElse(host);\n\n            try\n            {\n                // These variable names are used by CodeGenerator.GetBenchmarkRunCall, do NOT change them!\n                global::System.String benchmarkName = global::System.Linq.Enumerable.FirstOrDefault(global::System.Linq.Enumerable.Skip(global::System.Linq.Enumerable.SkipWhile(args, arg => arg != \"--benchmarkName\"), 1)) ?? \"not provided\";\n                global::BenchmarkDotNet.Diagnosers.RunMode diagnoserRunMode = (global::BenchmarkDotNet.Diagnosers.RunMode) global::System.Int32.Parse(global::System.Linq.Enumerable.FirstOrDefault(global::System.Linq.Enumerable.Skip(global::System.Linq.Enumerable.SkipWhile(args, arg => arg != \"--diagnoserRunMode\"), 1)) ?? \"0\");\n                global::System.Int32 id = args.Length > 0\n                    ? global::System.Int32.Parse(args[args.Length - 1])\n                    : 0; // used when re-using generated exe without BDN (typically to repro a bug)\n\n                if (args.Length == 0)\n                {\n                    host.WriteLine(\"You have not specified benchmark id (an integer) so the first benchmark will be executed.\");\n                }\n                $BenchmarkRunCall$\n                return 0;\n            }\n            catch (global::System.Exception oom) when (oom is global::System.OutOfMemoryException || oom is global::System.Reflection.TargetInvocationException reflection && reflection.InnerException is global::System.OutOfMemoryException)\n            {\n                host.WriteLine();\n                host.WriteLine(\"OutOfMemoryException!\");\n                host.WriteLine(\"BenchmarkDotNet continues to run additional iterations until desired accuracy level is achieved. It's possible only if the benchmark method doesn't have any side-effects.\");\n                host.WriteLine(\"If your benchmark allocates memory and keeps it alive, you are creating a memory leak.\");\n                host.WriteLine(\"You should redesign your benchmark and remove the side-effects. You can use `OperationsPerInvoke`, `IterationSetup` and `IterationCleanup` to do that.\");\n                host.WriteLine();\n                host.WriteLine(oom.ToString());\n\n                return -1;\n            }\n            catch(global::System.Exception ex)\n            {\n                host.WriteLine();\n                host.WriteLine(ex.ToString());\n                return -1;\n            }\n            finally\n            {\n                global::BenchmarkDotNet.Engines.HostExtensions.AfterAll(host);\n\n                host.Dispose();\n            }\n        }\n    }\n\n#if NETFRAMEWORK\n    internal class DirtyAssemblyResolveHelper : global::System.IDisposable\n    {\n        internal DirtyAssemblyResolveHelper() => global::System.AppDomain.CurrentDomain.AssemblyResolve += HelpTheFrameworkToResolveTheAssembly;\n\n        public void Dispose() => global::System.AppDomain.CurrentDomain.AssemblyResolve -= HelpTheFrameworkToResolveTheAssembly;\n\n        /// <summary>\n        /// according to https://msdn.microsoft.com/en-us/library/ff527268(v=vs.110).aspx\n        /// \"the handler is invoked whenever the runtime fails to bind to an assembly by name.\"\n        /// </summary>\n        /// <returns>not null when we find it manually, null when can't help</returns>\n        private global::System.Reflection.Assembly HelpTheFrameworkToResolveTheAssembly(global::System.Object sender, global::System.ResolveEventArgs args)\n        {\n#if SHADOWCOPY // used for LINQPad\n            const global::System.String shadowCopyFolderPath = @\"$ShadowCopyFolderPath$\";\n\n            global::System.String guessedPath = global::System.IO.Path.Combine(shadowCopyFolderPath, $\"{new global::System.Reflection.AssemblyName(args.Name).Name}.dll\");\n\n            return global::System.IO.File.Exists(guessedPath) ? global::System.Reflection.Assembly.LoadFrom(guessedPath) : null;\n#else\n            global::System.Reflection.AssemblyName fullName = new global::System.Reflection.AssemblyName(args.Name);\n            global::System.String simpleName = fullName.Name;\n\n            global::System.String guessedPath = global::System.IO.Path.Combine(global::System.AppDomain.CurrentDomain.BaseDirectory, $\"{simpleName}.dll\");\n\n            if (!global::System.IO.File.Exists(guessedPath))\n            {\n                global::System.Console.WriteLine($\"// Wrong assembly binding redirects for {args.Name}.\");\n                return null; // we can't help, and we also don't call Assembly.Load which if fails comes back here, creates endless loop and causes StackOverflow\n            }\n\n            // the file is right there, but has most probably different version and there is no assembly binding redirect or there is a wrong one...\n            // so we just load it and ignore the version mismatch\n\n            // we warn the user about that, in case some Super User want to be aware of that\n            global::System.Console.WriteLine($\"// Wrong assembly binding redirects for {simpleName}, loading it from disk anyway.\");\n\n            return global::System.Reflection.Assembly.LoadFrom(guessedPath);\n#endif // SHADOWCOPY\n        }\n    }\n#endif // NETFRAMEWORK\n\n$DerivedTypes$\n}\n\n#if !NET7_0_OR_GREATER\nnamespace System.Runtime.CompilerServices\n{\n    [global::System.AttributeUsage(global::System.AttributeTargets.All, AllowMultiple = true, Inherited = false)]\n    [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]\n    internal sealed class CompilerFeatureRequiredAttribute : global::System.Attribute\n    {\n        public CompilerFeatureRequiredAttribute(global::System.String featureName)\n        {\n            FeatureName = featureName;\n        }\n\n        public global::System.String FeatureName { get; }\n        public global::System.Boolean IsOptional { get; set; }\n        public const global::System.String RefStructs = nameof(RefStructs);\n        public const global::System.String RequiredMembers = nameof(RequiredMembers);\n    }\n\n    [global::System.AttributeUsage(global::System.AttributeTargets.Class | global::System.AttributeTargets.Struct | global::System.AttributeTargets.Field | global::System.AttributeTargets.Property, AllowMultiple = false, Inherited = false)]\n    [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]\n    internal sealed class RequiredMemberAttribute : global::System.Attribute\n    {\n    }\n}\n#endif\n"
  },
  {
    "path": "src/BenchmarkDotNet/Templates/BenchmarkType.txt",
    "content": "    // Type name must be in sync with DisassemblyDiagnoser.BuildClrMdArgs.\n    public unsafe sealed class Runnable_$ID$ : $WorkloadTypeName$\n    {\n        public static void Run(global::BenchmarkDotNet.Engines.IHost host, global::System.String benchmarkName, global::BenchmarkDotNet.Diagnosers.RunMode diagnoserRunMode)\n        {\n            global::BenchmarkDotNet.Autogenerated.Runnable_$ID$ instance = new global::BenchmarkDotNet.Autogenerated.Runnable_$ID$();\n\n            host.WriteLine();\n            foreach (global::System.String infoLine in global::BenchmarkDotNet.Environments.BenchmarkEnvironmentInfo.GetCurrent().ToFormattedString())\n            {\n                host.WriteLine($\"// {infoLine}\");\n            }\n            global::BenchmarkDotNet.Jobs.Job job = new global::BenchmarkDotNet.Jobs.Job(); // use full name to avoid naming conflicts, #778\n            $JobSetDefinition$;\n            job.Freeze();\n            host.WriteLine($\"// Job: {job.DisplayInfo}\");\n            host.WriteLine();\n\n            global::System.Collections.Generic.IEnumerable<BenchmarkDotNet.Validators.ValidationError> errors = global::BenchmarkDotNet.Validators.BenchmarkProcessValidator.Validate(job, instance);\n            if (global::BenchmarkDotNet.Validators.ValidationErrorReporter.ReportIfAny(errors, host))\n                return;\n\n            global::BenchmarkDotNet.Diagnosers.CompositeInProcessDiagnoserHandler compositeInProcessDiagnoserHandler = new global::BenchmarkDotNet.Diagnosers.CompositeInProcessDiagnoserHandler(\n                new global::BenchmarkDotNet.Diagnosers.InProcessDiagnoserRouter[] {\n                    $InProcessDiagnoserRouters$\n                },\n                host,\n                diagnoserRunMode,\n                new global::BenchmarkDotNet.Diagnosers.InProcessDiagnoserActionArgs(instance)\n            );\n            if (diagnoserRunMode == global::BenchmarkDotNet.Diagnosers.RunMode.SeparateLogic)\n            {\n                compositeInProcessDiagnoserHandler.Handle(global::BenchmarkDotNet.Engines.BenchmarkSignal.SeparateLogic);\n                return;\n            }\n            compositeInProcessDiagnoserHandler.Handle(global::BenchmarkDotNet.Engines.BenchmarkSignal.BeforeEngine);\n\n            global::BenchmarkDotNet.Engines.EngineParameters engineParameters = new global::BenchmarkDotNet.Engines.EngineParameters()\n            {\n                Host = host,\n                WorkloadActionUnroll = instance.WorkloadActionUnroll,\n                WorkloadActionNoUnroll = instance.WorkloadActionNoUnroll,\n                OverheadActionNoUnroll = instance.OverheadActionNoUnroll,\n                OverheadActionUnroll = instance.OverheadActionUnroll,\n                GlobalSetupAction = instance.globalSetupAction,\n                GlobalCleanupAction = instance.globalCleanupAction,\n                IterationSetupAction = instance.iterationSetupAction,\n                IterationCleanupAction = instance.iterationCleanupAction,\n                TargetJob = job,\n                OperationsPerInvoke = $OperationsPerInvoke$,\n                RunExtraIteration = $RunExtraIteration$,\n                BenchmarkName = benchmarkName,\n                InProcessDiagnoserHandler = compositeInProcessDiagnoserHandler\n            };\n\n            global::BenchmarkDotNet.Engines.RunResults results = new $EngineFactoryType$().Create(engineParameters).Run();\n            host.ReportResults(results); // printing costs memory, do this after runs\n\n            instance.__TrickTheJIT__(); // compile the method for disassembler, but without actual run of the benchmark ;)\n            compositeInProcessDiagnoserHandler.Handle(global::BenchmarkDotNet.Engines.BenchmarkSignal.AfterEngine);\n        }\n\n        [global::System.Diagnostics.CodeAnalysis.SetsRequiredMembers]\n        public Runnable_$ID$()\n        {\n            this.globalSetupAction = $GlobalSetupMethodName$;\n            this.globalCleanupAction = $GlobalCleanupMethodName$;\n            this.iterationSetupAction = $IterationSetupMethodName$;\n            this.iterationCleanupAction = $IterationCleanupMethodName$;\n            $InitializeArgumentFields$\n            $ParamsContent$\n        }\n\n        private global::System.Action globalSetupAction;\n        private global::System.Action globalCleanupAction;\n        private global::System.Action iterationSetupAction;\n        private global::System.Action iterationCleanupAction;\n        $DeclareArgumentFields$\n\n        // this method is used only for the disassembly diagnoser purposes\n        // the goal is to get this and the benchmarked method jitted, but without executing the benchmarked method itself\n        public global::System.Int32 NotEleven;\n        [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.NoOptimization | global::System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]\n        public void __TrickTheJIT__()\n        {\n            this.NotEleven = new global::System.Random(123).Next(0, 10);\n            $DisassemblerEntryMethodName$();\n        }\n\n        [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.NoOptimization | global::System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]\n        public void $DisassemblerEntryMethodName$()\n        {\n            if (this.NotEleven == 11)\n            {\n                $LoadArguments$\n                $WorkloadMethodCall$;\n            }\n        }\n\n        [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]\n        private void __Overhead($ArgumentsDefinition$)\n        {\n        }\n\n        [global::System.Runtime.CompilerServices.MethodImpl(global::BenchmarkDotNet.Portability.CodeGenHelper.AggressiveOptimizationOption)]\n        private void OverheadActionUnroll(global::System.Int64 invokeCount)\n        {\n            $LoadArguments$\n            while (--invokeCount >= 0)\n            {\n                this.__Overhead($PassArguments$);@Unroll@\n            }\n        }\n\n        [global::System.Runtime.CompilerServices.MethodImpl(global::BenchmarkDotNet.Portability.CodeGenHelper.AggressiveOptimizationOption)]\n        private void OverheadActionNoUnroll(global::System.Int64 invokeCount)\n        {\n            $LoadArguments$\n            while (--invokeCount >= 0)\n            {\n                this.__Overhead($PassArguments$);\n            }\n        }\n\n        [global::System.Runtime.CompilerServices.MethodImpl(global::BenchmarkDotNet.Portability.CodeGenHelper.AggressiveOptimizationOption)]\n        private void WorkloadActionUnroll(global::System.Int64 invokeCount)\n        {\n            $LoadArguments$\n            while (--invokeCount >= 0)\n            {\n                $WorkloadMethodCall$;@Unroll@\n            }\n        }\n\n        [global::System.Runtime.CompilerServices.MethodImpl(global::BenchmarkDotNet.Portability.CodeGenHelper.AggressiveOptimizationOption)]\n        private void WorkloadActionNoUnroll(global::System.Int64 invokeCount)\n        {\n            $LoadArguments$\n            while (--invokeCount >= 0)\n            {\n                $WorkloadMethodCall$;\n            }\n        }\n    }"
  },
  {
    "path": "src/BenchmarkDotNet/Templates/BuildPlots.R",
    "content": "BenchmarkDotNetVersion <- \"$BenchmarkDotNetVersion$ \"\ndir.create(Sys.getenv(\"R_LIBS_USER\"), recursive = TRUE, showWarnings = FALSE)\nlist.of.packages <- c(\"ggplot2\", \"dplyr\", \"gdata\", \"tidyr\", \"grid\", \"gridExtra\", \"Rcpp\", \"R.devices\")\nnew.packages <- list.of.packages[!(list.of.packages %in% installed.packages()[,\"Package\"])]\nif(length(new.packages)) install.packages(new.packages, lib = Sys.getenv(\"R_LIBS_USER\"), repos = \"https://cran.rstudio.com/\")\nlibrary(ggplot2)\nlibrary(dplyr)\nlibrary(gdata)\nlibrary(tidyr)\nlibrary(grid)\nlibrary(gridExtra)\nlibrary(R.devices)\n\nisEmpty <- function(val){\n   is.null(val) | val == \"\"\n}\n\ncreatePrefix <- function(params){ \n   separator <- \"-\"\n   values <- params[!isEmpty(params)]\n   paste(replace(values, TRUE, paste0(separator, values)), collapse = \"\")\n}\n\nends_with <- function(vars, match, ignore.case = TRUE) {\n  if (ignore.case)\n    match <- tolower(match)\n  n <- nchar(match)\n\n  if (ignore.case)\n    vars <- tolower(vars)\n  length <- nchar(vars)\n\n  substr(vars, pmax(1, length - n + 1), length) == match\n}\nstd.error <- function(x) sqrt(var(x)/length(x))\ncummean <- function(x) cumsum(x)/(1:length(x))\nBenchmarkDotNetVersionGrob <- textGrob(BenchmarkDotNetVersion, gp = gpar(fontface=3, fontsize=10), hjust=1, x=1)\nnicePlot <- function(p) grid.arrange(p, bottom = BenchmarkDotNetVersionGrob)\nprintNice <- function(p) {} # print(nicePlot(p))\nggsaveNice <- function(fileName, p, ...) {\n  cat(paste0(\"*** Plot: \", fileName, \" ***\\n\"))\n  # See https://stackoverflow.com/a/51655831/184842\n  suppressGraphics(ggsave(fileName, plot = nicePlot(p), ...))\n  cat(\"------------------------------\\n\")\n}\n\nargs <- commandArgs(trailingOnly = TRUE)\nfiles <- if (length(args) > 0) args else list.files()[list.files() %>% ends_with(\"-measurements.csv\")]\nfor (file in files) {\n  title <- gsub(\"-measurements.csv\", \"\", basename(file))\n  measurements <- read.csv(file, sep = \"$CsvSeparator$\")\n\n  result <- measurements %>% filter(Measurement_IterationStage == \"Result\")\n  if (nrow(result[is.na(result$Job_Id),]) > 0)\n    result[is.na(result$Job_Id),]$Job_Id <- \"\"\n  if (nrow(result[is.na(result$Params),]) > 0) {\n    result[is.na(result$Params),]$Params <- \"\"\n  } else {\n    result$Job_Id <- trim(paste(result$Job_Id, result$Params))\n  }\n  result$Job_Id <- factor(result$Job_Id, levels = unique(result$Job_Id))\n\n  timeUnit <- \"ns\"\n  if (min(result$Measurement_Value) > 1000) {\n    result$Measurement_Value <- result$Measurement_Value / 1000\n    timeUnit <- \"us\"\n  }\n  if (min(result$Measurement_Value) > 1000) {\n    result$Measurement_Value <- result$Measurement_Value / 1000\n    timeUnit <- \"ms\"\n  }\n  if (min(result$Measurement_Value) > 1000) {\n    result$Measurement_Value <- result$Measurement_Value / 1000\n    timeUnit <- \"sec\"\n  }\n\n  resultStats <- result %>%\n    group_by_(.dots = c(\"Target_Method\", \"Job_Id\")) %>%\n    summarise(se = std.error(Measurement_Value), Value = mean(Measurement_Value))\n\n  benchmarkBoxplot <- ggplot(result, aes(x=Target_Method, y=Measurement_Value, fill=Job_Id)) +\n    guides(fill=guide_legend(title=\"Job\")) +\n    xlab(\"Target\") +\n    ylab(paste(\"Time,\", timeUnit)) +\n    ggtitle(title) +\n    geom_boxplot()\n  benchmarkBarplot <- ggplot(resultStats, aes(x=Target_Method, y=Value, fill=Job_Id)) +\n    guides(fill=guide_legend(title=\"Job\")) +\n    xlab(\"Target\") +\n    ylab(paste(\"Time,\", timeUnit)) +\n    ggtitle(title) +\n    geom_bar(position=position_dodge(), stat=\"identity\")\n    #geom_errorbar(aes(ymin=Value-1.96*se, ymax=Value+1.96*se), width=.2, position=position_dodge(.9))\n\n  printNice(benchmarkBoxplot)\n  printNice(benchmarkBarplot)\n  ggsaveNice(gsub(\"-measurements.csv\", \"-boxplot.png\", file), benchmarkBoxplot)\n  ggsaveNice(gsub(\"-measurements.csv\", \"-barplot.png\", file), benchmarkBarplot)\n\n  for (target in unique(result$Target_Method)) {\n    df <- result %>% filter(Target_Method == target)\n    df$Launch <- factor(df$Measurement_LaunchIndex)\n    df <- df %>% group_by(Job_Id, Launch) %>% mutate(cm = cummean(Measurement_Value))\n\n    densityPlot <- ggplot(df, aes(x=Measurement_Value, fill=Job_Id)) +\n      ggtitle(paste(title, \"/\", target)) +\n      xlab(paste(\"Time,\", timeUnit)) +\n      geom_density(alpha=.5, bw=\"sj\")\n    printNice(densityPlot)\n    ggsaveNice(gsub(\"-measurements.csv\", paste0(\"-\", target, \"-density.png\"), file), densityPlot)\n\n    facetDensityPlot <- densityPlot + facet_wrap(~Job_Id)\n    printNice(facetDensityPlot)\n    ggsaveNice(gsub(\"-measurements.csv\", paste0(\"-\", target, \"-facetDensity.png\"), file), facetDensityPlot)\n\n    for (params in unique(df$Params)) {\n      paramsDf <- df %>% filter(Params == params)\n      paramsDensityPlot <- ggplot(paramsDf, aes(x=Measurement_Value, fill=Job_Id)) +\n        ggtitle(paste(title, \"/\", target, \"/\", params)) +\n        xlab(paste(\"Time,\", timeUnit)) +\n        geom_density(alpha=.5, bw=\"sj\")\n      printNice(paramsDensityPlot)\n      prefix <- createPrefix(c(target,params))\n      ggsaveNice(gsub(\"-measurements.csv\", paste0(prefix, \"-density.png\"), file), paramsDensityPlot)\n\n      paramsFacetDensityPlot <- paramsDensityPlot + facet_wrap(~Job_Id)\n      printNice(paramsFacetDensityPlot)\n      ggsaveNice(gsub(\"-measurements.csv\", paste0(prefix, \"-facetDensity.png\"), file), paramsFacetDensityPlot)\n    }\n\n    for (job in unique(df$Job_Id)) {\n      jobDf <- df %>% filter(Job_Id == job)\n      timelinePlot <- ggplot(jobDf, aes(x = Measurement_IterationIndex, y=Measurement_Value, group=Launch, color=Launch)) +\n        ggtitle(paste(title, \"/\", target, \"/\", job)) +\n        xlab(\"IterationIndex\") +\n        ylab(paste(\"Time,\", timeUnit)) +\n        geom_line() +\n        geom_point()\n      printNice(timelinePlot)\n      ggsaveNice(gsub(\"-measurements.csv\", paste0(\"-\", target, \"-\", job, \"-timeline.png\"), file), timelinePlot)\n      timelinePlotSmooth <- timelinePlot + geom_smooth()\n      printNice(timelinePlotSmooth)\n      ggsaveNice(gsub(\"-measurements.csv\", paste0(\"-\", target, \"-\", job, \"-timelineSmooth.png\"), file), timelinePlotSmooth)\n\n      cummeanPlot <- ggplot(jobDf, aes(x = Measurement_IterationIndex, y=cm, group=Launch, color=Launch)) +\n        ggtitle(paste(title, \"/\", target, \"/\", job)) +\n        xlab(\"IterationIndex\") +\n        ylab(paste(\"Cumulative mean time,\", timeUnit)) +\n        geom_line() +\n        geom_point()\n      printNice(cummeanPlot)\n      ggsaveNice(gsub(\"-measurements.csv\", paste0(\"-\", target, \"-\", job, \"-cummean.png\"), file), cummeanPlot)\n\n\n      densityPlotJob <- ggplot(jobDf, aes(x=Measurement_Value, fill=\"red\")) +\n        ggtitle(paste(title, \"/\", target, \"/\", job)) +\n        xlab(paste(\"Time,\", timeUnit)) +\n        geom_density(alpha=.5, bw=\"sj\")\n      printNice(densityPlotJob)\n      ggsaveNice(gsub(\"-measurements.csv\", paste0(\"-\", target, \"-\", job, \"-density.png\"), file), densityPlotJob)\n    }\n\n    timelinePlot <- ggplot(df, aes(x = Measurement_IterationIndex, y=Measurement_Value, group=Launch, color=Launch)) +\n      ggtitle(paste(title, \"/\", target)) +\n      xlab(\"IterationIndex\") +\n      ylab(paste(\"Time,\", timeUnit)) +\n      geom_line() +\n      geom_point() +\n      facet_wrap(~Job_Id)\n    printNice(timelinePlot)\n    ggsaveNice(gsub(\"-measurements.csv\", paste0(\"-\", target, \"-facetTimeline.png\"), file), timelinePlot)\n    timelinePlotSmooth <- timelinePlot + geom_smooth()\n    printNice(timelinePlotSmooth)\n    ggsaveNice(gsub(\"-measurements.csv\", paste0(\"-\", target, \"-facetTimelineSmooth.png\"), file), timelinePlotSmooth)\n\n    facetCummeanPlot <- ggplot(df, aes(x = Measurement_IterationIndex, y=cm, group=Launch, color=Launch)) +\n      ggtitle(paste(title, \"/\", target)) +\n      xlab(\"IterationIndex\") +\n      ylab(paste(\"Cumulative mean time,\", timeUnit)) +\n      geom_line() +\n      geom_point() +\n      facet_wrap(~Job_Id)\n    printNice(facetCummeanPlot)\n    ggsaveNice(gsub(\"-measurements.csv\", paste0(\"-\", target, \"-cummean.png\"), file), facetCummeanPlot)\n  }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Templates/CsProj.txt",
    "content": "<Project Sdk=\"$SDKNAME$\">\n\n  <PropertyGroup>\n    <ImportDirectoryBuildProps>false</ImportDirectoryBuildProps>\n    <ImportDirectoryBuildTargets>false</ImportDirectoryBuildTargets>\n    <AssemblyTitle>$PROGRAMNAME$</AssemblyTitle>\n    <TargetFrameworks>$TFM$</TargetFrameworks>\n    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>\n    <PlatformTarget>$PLATFORM$</PlatformTarget>\n    <AssemblyName>$PROGRAMNAME$</AssemblyName>\n    <OutputType>Exe</OutputType>\n    <TreatWarningsAsErrors>False</TreatWarningsAsErrors>\n    <!-- Usage of System.Random can cause compilation errors if Code Analysis warnings are treated as Errors -->\n    <CodeAnalysisTreatWarningsAsErrors>false</CodeAnalysisTreatWarningsAsErrors>\n    <!-- disabled due to https://github.com/dotnet/roslyn/issues/59421 -->\n    <DebugSymbols>false</DebugSymbols>\n    <UseSharedCompilation>false</UseSharedCompilation>\n    <CodeAnalysisRuleSet></CodeAnalysisRuleSet>\n    <RunAnalyzers>false</RunAnalyzers>\n    <Deterministic>true</Deterministic>\n    <!-- needed for custom build configurations (only \"Release\" builds are optimized by default) -->\n    <Optimize Condition=\" '$(Configuration)' != 'Debug' \">true</Optimize>\n    <!-- we set LangVersion after any copied settings which might contain LangVersion copied from the benchmarks project -->\n    <LangVersion Condition=\"'$(LangVersion)' == '' Or ($([System.Char]::IsDigit('$(LangVersion)', 0)) And '$(LangVersion)' &lt; '7.3')\">latest</LangVersion>\n    <!-- fix for NETSDK1150: https://docs.microsoft.com/en-us/dotnet/core/compatibility/sdk/5.0/referencing-executable-generates-error -->\n    <ValidateExecutableReferencesMatchSelfContained>false</ValidateExecutableReferencesMatchSelfContained>\n    <!-- Suppress warning for nuget package used in old (unsupported) tfm. -->\n    <SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>\n    <StartupObject>BenchmarkDotNet.Autogenerated.UniqueProgramName</StartupObject>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <Compile Include=\"$CODEFILENAME$\" Exclude=\"bin\\**;obj\\**;**\\*.xproj;packages\\**\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <ProjectReference Include=\"$CSPROJPATH$\" />\n  </ItemGroup>\n\n  <!-- Begin copied settings from benchmarks project -->\n  $COPIEDSETTINGS$\n  <!-- End copied settings -->\n\n  $RUNTIMESETTINGS$\n\n</Project>\n"
  },
  {
    "path": "src/BenchmarkDotNet/Templates/MonoAOTLLVMCsProj.txt",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\" DefaultTarget=\"Publish\">\n  <PropertyGroup>\n    <OriginalCSProjPath>$CSPROJPATH$</OriginalCSProjPath>\n    <MonoPropsPath>$([System.IO.Path]::ChangeExtension('$(OriginalCSProjPath)', '.Mono.props'))</MonoPropsPath>\n    <MonoTargetsPath>$([System.IO.Path]::ChangeExtension('$(OriginalCSProjPath)', '.Mono.targets'))</MonoTargetsPath>\n  </PropertyGroup>\n\n  <Import Project=\"$(MonoPropsPath)\" Condition=\"Exists($(MonoPropsPath))\" />\n\n  <PropertyGroup>\n    <OutputType>Exe</OutputType>\n    <TargetFrameworks>$TFM$</TargetFrameworks>\n    <MicrosoftNetCoreAppRuntimePackDir>$RUNTIMEPACK$</MicrosoftNetCoreAppRuntimePackDir>\n    <RuntimeIdentifier>$RUNTIMEIDENTIFIER$</RuntimeIdentifier>\n    <EnableTargetingPackDownload>false</EnableTargetingPackDownload>\n    <PublishTrimmed>false</PublishTrimmed>\n    <AssemblyName>$PROGRAMNAME$</AssemblyName>\n    <ValidateExecutableReferencesMatchSelfContained>false</ValidateExecutableReferencesMatchSelfContained>\n    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>\n    <StartupObject>BenchmarkDotNet.Autogenerated.UniqueProgramName</StartupObject>\n    <SelfContained>true</SelfContained>\n    <!-- Suppress warning for nuget package used in old (unsupported) tfm. -->\n    <SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <PackageReference Include=\"Microsoft.NET.Runtime.MonoAOTCompiler.Task\" version=\"6.0.0-*\" GeneratePathProperty=\"true\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <Compile Include=\"$CODEFILENAME$\" Exclude=\"bin\\**;obj\\**;**\\*.xproj;packages\\**\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <ProjectReference Include=\"$CSPROJPATH$\" />\n  </ItemGroup>\n\n  <!-- Begin copied settings from benchmarks project -->\n  $COPIEDSETTINGS$\n  <!-- End copied settings -->\n\n  <!-- Redirect 'dotnet publish' to in-tree runtime pack -->\n  <Target Name=\"TrickRuntimePackLocation\" AfterTargets=\"ProcessFrameworkReferences\">\n    <ItemGroup>\n      <RuntimePack>\n        <PackageDirectory>$(MicrosoftNetCoreAppRuntimePackDir)</PackageDirectory>\n      </RuntimePack>\n    </ItemGroup>\n    <Message Text=\"Packaged ID: %(RuntimePack.PackageDirectory)\" Importance=\"high\" />\n  </Target>\n\n  <UsingTask TaskName=\"MonoAOTCompiler\" AssemblyFile=\"$(PkgMicrosoft_NET_Runtime_MonoAOTCompiler_Task)/MonoAOTCompiler.dll\" /> \n\n  <Target Name=\"AotApp\" AfterTargets=\"Build\" DependsOnTargets=\"Publish\">\n\n   <PropertyGroup>\n      <PublishDirFullPath>$([System.IO.Path]::GetFullPath($(PublishDir)))</PublishDirFullPath>\n      <SharedLibraryType Condition=\"$([MSBuild]::IsOSPlatform('OSX'))\">Dylib</SharedLibraryType>\n      <SharedLibraryType Condition=\"$([MSBuild]::IsOSPlatform('Windows'))\">Dll</SharedLibraryType>\n      <SharedLibraryType Condition=\"'$(SharedLibraryType)' == ''\">So</SharedLibraryType>\n   </PropertyGroup>\n\n   <ItemGroup>\n     <AotInputAssemblies Include=\"$(PublishDirFullPath)\\*.dll\">\n        <AotArguments>mcpu=native</AotArguments>\n     </AotInputAssemblies>\n   </ItemGroup>\n\n\n   <MonoAOTCompiler\n        CompilerBinaryPath=\"$COMPILERBINARYPATH$\"\n        Mode=\"Normal\"\n        OutputType=\"Library\"\n        LibraryFormat=\"$(SharedLibraryType)\"\n        Assemblies=\"@(AotInputAssemblies)\"\n        UseLLVM=\"$USELLVM$\"\n        LLVMPath=\"$(MicrosoftNetCoreAppRuntimePackDir)\\runtimes\\$(RuntimeIdentifier)\\native\"\n        OutputDir=\"$(PublishDir)\"\n        UseAotDataFile=\"false\"\n        IntermediateOutputPath=\"$(IntermediateOutputPath)\">\n        <Output TaskParameter=\"CompiledAssemblies\" ItemName=\"BundleAssemblies\" />\n    </MonoAOTCompiler>\n\n   <Message Text=\"CompiledAssemblies: $(BundleAssemblies)\" Importance=\"high\"/>\n\n   </Target>\n\n  <Import Project=\"$(MonoTargetsPath)\" Condition=\"Exists($(MonoTargetsPath))\" />\n</Project>\n"
  },
  {
    "path": "src/BenchmarkDotNet/Templates/R2RCsProj.txt",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\" DefaultTarget=\"Publish\">\n\n   <!-- Properties same as standard CsProj.txt template -->\n   <PropertyGroup>\n    <ImportDirectoryBuildProps>false</ImportDirectoryBuildProps>\n    <ImportDirectoryBuildTargets>false</ImportDirectoryBuildTargets>\n    <AssemblyTitle>$PROGRAMNAME$</AssemblyTitle>\n    <TargetFrameworks>$TFM$</TargetFrameworks>\n    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>\n    <PlatformTarget>$PLATFORM$</PlatformTarget>\n    <AssemblyName>$PROGRAMNAME$</AssemblyName>\n    <OutputType>Exe</OutputType>\n    <TreatWarningsAsErrors>False</TreatWarningsAsErrors>\n    <!-- Usage of System.Random can cause compilation errors if Code Analysis warnings are treated as Errors -->\n    <CodeAnalysisTreatWarningsAsErrors>false</CodeAnalysisTreatWarningsAsErrors>\n    <!-- disabled due to https://github.com/dotnet/roslyn/issues/59421 -->\n    <DebugSymbols>false</DebugSymbols>\n    <UseSharedCompilation>false</UseSharedCompilation>\n    <CodeAnalysisRuleSet></CodeAnalysisRuleSet>\n    <RunAnalyzers>false</RunAnalyzers>\n    <Deterministic>true</Deterministic>\n    <!-- needed for custom build configurations (only \"Release\" builds are optimized by default) -->\n    <Optimize Condition=\" '$(Configuration)' != 'Debug' \">true</Optimize>\n    <!-- we set LangVersion after any copied settings which might contain LangVersion copied from the benchmarks project -->\n    <LangVersion Condition=\"'$(LangVersion)' == '' Or ($([System.Char]::IsDigit('$(LangVersion)', 0)) And '$(LangVersion)' &lt; '7.3')\">latest</LangVersion>\n    <!-- fix for NETSDK1150: https://docs.microsoft.com/en-us/dotnet/core/compatibility/sdk/5.0/referencing-executable-generates-error -->\n    <ValidateExecutableReferencesMatchSelfContained>false</ValidateExecutableReferencesMatchSelfContained>\n    <!-- Suppress warning for nuget package used in old (unsupported) tfm. -->\n    <SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>\n    <StartupObject>BenchmarkDotNet.Autogenerated.UniqueProgramName</StartupObject>\n    <!-- workaround for 'Found multiple publish output files with the same relative path.' error -->\n    <ErrorOnDuplicatePublishOutputFiles>false</ErrorOnDuplicatePublishOutputFiles>\n  </PropertyGroup>\n\n  <PropertyGroup>\n    <SelfContained>true</SelfContained>\n    <RuntimeIdentifier>$RUNTIMEIDENTIFIER$</RuntimeIdentifier>\n    <PublishReadyToRun>true</PublishReadyToRun>\n    <PublishReadyToRunComposite>true</PublishReadyToRunComposite>\n  </PropertyGroup>\n  <ItemGroup>\n    <!-- Temporary fix until https://github.com/dotnet/sdk/pull/52296 is resolved -->\n    <PublishReadyToRunCompositeExclusions Include=\"Dia2Lib.dll\" />\n    <PublishReadyToRunCompositeExclusions Include=\"TraceReloggerLib.dll\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <Compile Include=\"$CODEFILENAME$\" Exclude=\"bin\\**;obj\\**;**\\*.xproj;packages\\**\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <ProjectReference Include=\"$CSPROJPATH$\" />\n  </ItemGroup>\n\n  <!-- Begin copied settings from benchmarks project -->\n  $COPIEDSETTINGS$\n  <!-- End copied settings -->\n\n  <!-- The purpose of this project is to publish the app with r2r composite using a custom runtime pack and a custom crossgen2, built locally -->\n\n  <Target Name=\"TrickRuntimePackLocation\" AfterTargets=\"ProcessFrameworkReferences\">\n    <ItemGroup>\n      <RuntimePack>\n        <PackageDirectory>$RUNTIMEPACK$</PackageDirectory>\n      </RuntimePack>\n      <Crossgen2Pack>\n        <PackageDirectory>$CROSSGEN2PACK$</PackageDirectory>\n      </Crossgen2Pack>\n    </ItemGroup>\n  </Target>\n</Project>\n"
  },
  {
    "path": "src/BenchmarkDotNet/Templates/WasmCsProj.txt",
    "content": "﻿<Project Sdk=\"$SDKNAME$\" DefaultTargets=\"publish\">\n  <PropertyGroup>\n    <OriginalCSProjPath>$CSPROJPATH$</OriginalCSProjPath>\n    <WasmPropsPath>$([System.IO.Path]::ChangeExtension('$(OriginalCSProjPath)', '.Wasm.props'))</WasmPropsPath>\n    <WasmTargetsPath>$([System.IO.Path]::ChangeExtension('$(OriginalCSProjPath)', '.Wasm.targets'))</WasmTargetsPath>\n    <WasmMainJSPath>$MAINJS$</WasmMainJSPath>\n  </PropertyGroup>\n\n  <Import Project=\"$(WasmPropsPath)\" Condition=\"Exists($(WasmPropsPath))\" />\n$CORECLR_OVERRIDES$\n  <PropertyGroup>\n    <OutputType>Exe</OutputType>\n    <RuntimeConfig>Release</RuntimeConfig>\n    <EnableDefaultCompileItems>false</EnableDefaultCompileItems>\n    <TargetFrameworks>$TFM$</TargetFrameworks>\n    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>\n    <AppDir>$(PublishDir)</AppDir>\n    <AssemblyName>$PROGRAMNAME$</AssemblyName>\n    <RuntimeIdentifier>browser-wasm</RuntimeIdentifier>\n    <SuppressTrimAnalysisWarnings>true</SuppressTrimAnalysisWarnings>\n    <RunAOTCompilation>$RUN_AOT$</RunAOTCompilation>\n    <PublishTrimmed>$(RunAOTCompilation)</PublishTrimmed>\n    <ErrorOnDuplicatePublishOutputFiles>false</ErrorOnDuplicatePublishOutputFiles>\n    <ValidateExecutableReferencesMatchSelfContained>false</ValidateExecutableReferencesMatchSelfContained>\n    <EnableDefaultWasmAssembliesToBundle>false</EnableDefaultWasmAssembliesToBundle>\n    <!-- Suppress warning for nuget package used in old (unsupported) tfm. -->\n    <SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>\n    <StartupObject>BenchmarkDotNet.Autogenerated.UniqueProgramName</StartupObject>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <Compile Include=\"$CODEFILENAME$\" Exclude=\"bin\\**;obj\\**;**\\*.xproj;packages\\**\" />\n    <TrimmerRootDescriptor Include=\"WasmLinkerDescription.xml\" Condition=\"'$(RunAOTCompilation)' == 'true'\" />\n    <Content Update=\"wwwroot\\**\" CopyToOutputDirectory=\"PreserveNewest\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <ProjectReference Include=\"$(OriginalCSProjPath)\" />\n  </ItemGroup>\n\n  <!-- Begin copied settings from benchmarks project -->\n  $COPIEDSETTINGS$\n  <!-- End copied settings -->\n\n  <PropertyGroup>\n    <WasmBuildAppAfterThisTarget>PrepareForWasmBuild</WasmBuildAppAfterThisTarget>\n  </PropertyGroup>\n\n  <Target Name=\"PrepareForWasmBuild\" AfterTargets=\"Publish\">\n    <ItemGroup>\n      <WasmAssembliesToBundle Include=\"$(PublishDir)*.dll\" Condition=\"'$(RunAOTCompilation)' != 'true'\" />\n      <WasmAssembliesToBundle Include=\"$(PublishDir)*.dll\" Exclude=\"$(PublishDir)KernelTraceControl.dll\" Condition=\"'$(RunAOTCompilation)' == 'true'\" />\n    </ItemGroup>\n  </Target>\n\n  <Import Project=\"$(WasmTargetsPath)\" Condition=\"Exists($(WasmTargetsPath))\" />\n</Project>\n"
  },
  {
    "path": "src/BenchmarkDotNet/Templates/WasmLinkerDescription.xml",
    "content": "<linker>\n  <assembly fullname=\"System.Private.CoreLib\">\n    <type fullname=\"System.IntPtr\" />\n  </assembly>\n</linker>\n"
  },
  {
    "path": "src/BenchmarkDotNet/Templates/benchmark-main.mjs",
    "content": "// Licensed to the .NET Foundation under one or more agreements.\n// The .NET Foundation licenses this file to you under the MIT license.\n\nimport { dotnet } from \"./_framework/dotnet.js\";\n\nconst ENVIRONMENT_IS_NODE = typeof process == \"object\" && typeof process.versions == \"object\" && typeof process.versions.node == \"string\";\nconst ENVIRONMENT_IS_WEB_WORKER = typeof importScripts == \"function\";\nconst ENVIRONMENT_IS_WEB = typeof window == \"object\" || (ENVIRONMENT_IS_WEB_WORKER && !ENVIRONMENT_IS_NODE);\n\nif (!ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WEB && typeof globalThis.crypto === 'undefined') {\n    // **NOTE** this is a simple insecure polyfill for JS shells (like v8/d8) that lack Web Crypto API.\n    // /dev/random doesn't work on js shells, so define our own.\n    globalThis.crypto = {\n        getRandomValues: function (buffer) {\n            for (let i = 0; i < buffer.length; i++)\n                buffer[i] = (Math.random() * 256) | 0;\n        }\n    }\n}\n\nfunction getAppArgs() {\n    // v8\n    if (globalThis.arguments !== undefined)\n        return globalThis.arguments;\n\n    // spidermonkey\n    if (globalThis.scriptArgs !== undefined)\n        return globalThis.scriptArgs;\n\n    // Node / Bun\n    if (globalThis.process !== undefined) {\n        const argv = globalThis.process.argv ?? [];\n        const sep = argv.indexOf(\"--\");\n        return sep >= 0 ? argv.slice(sep + 1) : argv.slice(2);\n    }\n\n    throw new Error(\"Unable to determine application arguments for the current runtime.\");\n}\n\nconst args = getAppArgs();\n\nawait dotnet\n    .withDiagnosticTracing(false)\n    .withApplicationArguments(...args)\n    .run();\n"
  },
  {
    "path": "src/BenchmarkDotNet/Templates/highlightingLabelsScript.js",
    "content": "﻿$(document).ready(function () {\n    var selectedIndex = 0;\n\n    function highlight() {\n        $('td.reference.highlighted').removeClass('highlighted');\n\n        var selectedLabel = $(this).attr('data-label');\n        if (selectedLabel) {\n            $('td.reference[data-reference=' + selectedLabel + ']').addClass('highlighted');\n        }\n        selectedIndex = 0;\n    }\n\n    function selectNext() {\n        var $highlighted = $('td.reference.highlighted');\n        var selected = $highlighted[selectedIndex++ % $highlighted.length];\n\n        if (selected) {\n            var selectedReference = $(selected).attr('id');\n            if (selectedReference) {\n                window.location.hash = '#' + selectedReference;\n            }\n        }\n    }\n\n    $('td.label').on('click', highlight);\n\n    $(document).on('keydown', function (event) {\n        if (event.keyCode == 114) { // F3\n            event.preventDefault();\n            // Remap F3 to some other key that the browser doesn't care about\n            selectNext();\n        }\n    });\n});"
  },
  {
    "path": "src/BenchmarkDotNet/Templates/perfcollect",
    "content": "#!/bin/bash \n\n#############################################################################################################\n# .NET Performance Data Collection Script\n#############################################################################################################\n\n#############################################################################################################\n#\n# ***** HOW TO USE THIS SCRIPT *****\n#\n# This script can be used to collect and view performance data collected with perf_event on Linux.\n\n# It's job is to make it simple to collect performance traces.\n#\n# How to collect a performance trace:\n# 1. Prior to starting the .NET process, set the environment variable COMPlus_PerfMapEnabled=1.\n#    This tells the runtime to emit information that enables perf_event to resolve JIT-compiled code symbols.\n# \n# 2. Setup your system to reproduce the performance issue you'd like to capture.  Data collection can be\n#    started on already running processes.\n# \n# 3. [Usage #1] use \"collect\" command\n#    - Run this script: sudo ./perfcollect collect samplePerfTrace. This will start data collection.\n#    - Let the repro run as long as you need to capture the performance problem.\n#    - Hit CTRL+C to stop collection.\n#\n#    [Usage #2] use \"start\" and \"stop\" command\n#    - Run this script: sudo ./perfcollect start samplePerfTrace. This will start data colletion.\n#    - Let the repro run as long as you need to capture the performance problem.\n#    - Run: sudo ./perfcollect stop samplePerfTrace. This will stop collection.\n#\n# 4. When collection is stopped, the script will create a trace.zip file matching the name specified on the\n#    command line.  This file will contain the trace, JIT-compiled symbol information, and all debugging\n#    symbols for binaries referenced by this trace that were available on the machine at collection time.\n#\n# How to view a performance trace:\n# 1. Run this script: ./perfcollect view samplePerfTrace.trace.zip\n#    This will extract the trace, place and register all symbol files and JIT-compiled symbol information\n#    and start the perf_event viewer.  By default, you will be looking at a callee view - stacks are ordered\n#    top down.  For a caller or bottom up view, specify '-graphtype caller'. \n#############################################################################################################\n\n######################################\n## FOR DEBUGGING ONLY\n######################################\n# set -x\n\n######################################\n## Collection Options\n## NOTE: These values represent the collection defaults.\n######################################\n\n# Set when we parse command line arguments to determine if we should enable specific collection options.\ncollect_cpu=1\ncollect_threadTime=0\ncollect_offcpu=0\n\n######################################\n## .NET Event Categories\n######################################\n\n# Separate GCCollectOnly list because our LTTng implementation doesn't set tracepoint verbosity.\n# Once tracepoint verbosity is set, we can set verbosity and collapse this with DotNETRuntime_GCKeyword.\ndeclare -a DotNETRuntime_GCKeyword_GCCollectOnly=(\n    DotNETRuntime:GCStart\n    DotNETRuntime:GCStart_V1\n    DotNETRuntime:GCStart_V2\n    DotNETRuntime:GCEnd\n    DotNETRuntime:GCEnd_V1\n    DotNETRuntime:GCRestartEEEnd\n    DotNETRuntime:GCRestartEEEnd_V1\n    DotNETRuntime:GCHeapStats\n    DotNETRuntime:GCHeapStats_V1\n    DotNETRuntime:GCCreateSegment\n    DotNETRuntime:GCCreateSegment_V1\n    DotNETRuntime:GCFreeSegment\n    DotNETRuntime:GCFreeSegment_V1\n    DotNETRuntime:GCRestartEEBegin\n    DotNETRuntime:GCRestartEEBegin_V1\n    DotNETRuntime:GCSuspendEEEnd\n    DotNETRuntime:GCSuspendEEEnd_V1\n    DotNETRuntime:GCSuspendEEBegin\n    DotNETRuntime:GCSuspendEEBegin_V1\n    DotNETRuntime:GCCreateConcurrentThread\n    DotNETRuntime:GCTerminateConcurrentThread\n    DotNETRuntime:GCFinalizersEnd\n    DotNETRuntime:GCFinalizersEnd_V1\n    DotNETRuntime:GCFinalizersBegin\n    DotNETRuntime:GCFinalizersBegin_V1\n    DotNETRuntime:GCMarkStackRoots\n    DotNETRuntime:GCMarkFinalizeQueueRoots\n    DotNETRuntime:GCMarkHandles\n    DotNETRuntime:GCMarkOlderGenerationRoots\n    DotNETRuntime:FinalizeObject\n    DotNETRuntime:GCTriggered\n    DotNETRuntime:IncreaseMemoryPressure\n    DotNETRuntime:DecreaseMemoryPressure\n    DotNETRuntime:GCMarkWithType\n    DotNETRuntime:GCPerHeapHistory_V3\n    DotNETRuntime:GCGlobalHeapHistory_V2\n    DotNETRuntime:GCCreateConcurrentThread_V1\n    DotNETRuntime:GCTerminateConcurrentThread_V1\n)\n\n\ndeclare -a DotNETRuntime_GCKeyword=(\n    DotNETRuntime:GCStart\n    DotNETRuntime:GCStart_V1\n    DotNETRuntime:GCStart_V2\n    DotNETRuntime:GCEnd\n    DotNETRuntime:GCEnd_V1\n    DotNETRuntime:GCRestartEEEnd\n    DotNETRuntime:GCRestartEEEnd_V1\n    DotNETRuntime:GCHeapStats\n    DotNETRuntime:GCHeapStats_V1\n    DotNETRuntime:GCCreateSegment\n    DotNETRuntime:GCCreateSegment_V1\n    DotNETRuntime:GCFreeSegment\n    DotNETRuntime:GCFreeSegment_V1\n    DotNETRuntime:GCRestartEEBegin\n    DotNETRuntime:GCRestartEEBegin_V1\n    DotNETRuntime:GCSuspendEEEnd\n    DotNETRuntime:GCSuspendEEEnd_V1\n    DotNETRuntime:GCSuspendEEBegin\n    DotNETRuntime:GCSuspendEEBegin_V1\n    DotNETRuntime:GCAllocationTick\n    DotNETRuntime:GCAllocationTick_V1\n    DotNETRuntime:GCAllocationTick_V2\n    DotNETRuntime:GCAllocationTick_V3\n    DotNETRuntime:GCCreateConcurrentThread\n    DotNETRuntime:GCTerminateConcurrentThread\n    DotNETRuntime:GCFinalizersEnd\n    DotNETRuntime:GCFinalizersEnd_V1\n    DotNETRuntime:GCFinalizersBegin\n    DotNETRuntime:GCFinalizersBegin_V1\n    DotNETRuntime:GCMarkStackRoots\n    DotNETRuntime:GCMarkFinalizeQueueRoots\n    DotNETRuntime:GCMarkHandles\n    DotNETRuntime:GCMarkOlderGenerationRoots\n    DotNETRuntime:FinalizeObject\n    DotNETRuntime:PinObjectAtGCTime\n    DotNETRuntime:GCTriggered\n    DotNETRuntime:IncreaseMemoryPressure\n    DotNETRuntime:DecreaseMemoryPressure\n    DotNETRuntime:GCMarkWithType\n    DotNETRuntime:GCJoin_V2\n    DotNETRuntime:GCPerHeapHistory_V3\n    DotNETRuntime:GCGlobalHeapHistory_V2\n    DotNETRuntime:GCCreateConcurrentThread_V1\n    DotNETRuntime:GCTerminateConcurrentThread_V1\n)\n\ndeclare -a DotNETRuntime_TypeKeyword=(\n    DotNETRuntime:BulkType\n)\n\ndeclare -a DotNETRuntime_GCHeapDumpKeyword=(\n    DotNETRuntime:GCBulkRootEdge\n    DotNETRuntime:GCBulkRootConditionalWeakTableElementEdge\n    DotNETRuntime:GCBulkNode\n    DotNETRuntime:GCBulkEdge\n    DotNETRuntime:GCBulkRootCCW\n    DotNETRuntime:GCBulkRCW\n    DotNETRuntime:GCBulkRootStaticVar\n)\n\ndeclare -a DotNETRuntime_GCSampledObjectAllocationHighKeyword=(\n    DotNETRuntime:GCSampledObjectAllocationHigh\n)\n\ndeclare -a DotNETRuntime_GCHeapSurvivalAndMovementKeyword=(\n    DotNETRuntime:GCBulkSurvivingObjectRanges\n    DotNETRuntime:GCBulkMovedObjectRanges\n    DotNETRuntime:GCGenerationRange\n)\n\ndeclare -a DotNETRuntime_GCHandleKeyword=(\n    DotNETRuntime:SetGCHandle\n    DotNETRuntime:DestroyGCHandle\n)\n\ndeclare -a DotNETRuntime_GCSampledObjectAllocationLowKeyword=(\n    DotNETRuntime:GCSampledObjectAllocationLow\n)\n\ndeclare -a DotNETRuntime_ThreadingKeyword=(\n    DotNETRuntime:WorkerThreadCreate\n    DotNETRuntime:WorkerThreadTerminate\n    DotNETRuntime:WorkerThreadRetire\n    DotNETRuntime:WorkerThreadUnretire\n    DotNETRuntime:IOThreadCreate\n    DotNETRuntime:IOThreadCreate_V1\n    DotNETRuntime:IOThreadTerminate\n    DotNETRuntime:IOThreadTerminate_V1\n    DotNETRuntime:IOThreadRetire\n    DotNETRuntime:IOThreadRetire_V1\n    DotNETRuntime:IOThreadUnretire\n    DotNETRuntime:IOThreadUnretire_V1\n    DotNETRuntime:ThreadpoolSuspensionSuspendThread\n    DotNETRuntime:ThreadpoolSuspensionResumeThread\n    DotNETRuntime:ThreadPoolWorkerThreadStart\n    DotNETRuntime:ThreadPoolWorkerThreadStop\n    DotNETRuntime:ThreadPoolWorkerThreadRetirementStart\n    DotNETRuntime:ThreadPoolWorkerThreadRetirementStop\n    DotNETRuntime:ThreadPoolWorkerThreadAdjustmentSample\n    DotNETRuntime:ThreadPoolWorkerThreadAdjustmentAdjustment\n    DotNETRuntime:ThreadPoolWorkerThreadAdjustmentStats\n    DotNETRuntime:ThreadPoolWorkerThreadWait\n    DotNETRuntime:ThreadPoolWorkingThreadCount\n    DotNETRuntime:ThreadPoolIOPack\n    DotNETRuntime:GCCreateConcurrentThread_V1\n    DotNETRuntime:GCTerminateConcurrentThread_V1\n)\n\ndeclare -a DotNETRuntime_ThreadingKeyword_ThreadTransferKeyword=(\n    DotNETRuntime:ThreadPoolEnqueue\n    DotNETRuntime:ThreadPoolDequeue\n    DotNETRuntime:ThreadPoolIOEnqueue\n    DotNETRuntime:ThreadPoolIODequeue\n    DotNETRuntime:ThreadCreating\n    DotNETRuntime:ThreadRunning\n)\n\ndeclare -a DotNETRuntime_NoKeyword=(\n    DotNETRuntime:ExceptionThrown\n    DotNETRuntime:Contention\n    DotNETRuntime:RuntimeInformationStart\n    DotNETRuntime:EventSource\n)\n\ndeclare -a DotNETRuntime_ExceptionKeyword=(\n    DotNETRuntime:ExceptionThrown_V1\n    DotNETRuntime:ExceptionCatchStart\n    DotNETRuntime:ExceptionCatchStop\n    DotNETRuntime:ExceptionFinallyStart\n    DotNETRuntime:ExceptionFinallyStop\n    DotNETRuntime:ExceptionFilterStart\n    DotNETRuntime:ExceptionFilterStop\n    DotNETRuntime:ExceptionThrownStop\n)\n\ndeclare -a DotNETRuntime_ContentionKeyword=(\n    DotNETRuntime:ContentionStart_V1\n    DotNETRuntime:ContentionStop\n    DotNETRuntime:ContentionStop_V1\n)\n\ndeclare -a DotNETRuntime_StackKeyword=(\n    DotNETRuntime:CLRStackWalk\n)\n\ndeclare -a DotNETRuntime_AppDomainResourceManagementKeyword=(\n    DotNETRuntime:AppDomainMemAllocated\n    DotNETRuntime:AppDomainMemSurvived\n)\n\ndeclare -a DotNETRuntime_AppDomainResourceManagementKeyword_ThreadingKeyword=(\n    DotNETRuntime:ThreadCreated\n    DotNETRuntime:ThreadTerminated\n    DotNETRuntime:ThreadDomainEnter\n)\n\ndeclare -a DotNETRuntime_InteropKeyword=(\n    DotNETRuntime:ILStubGenerated\n    DotNETRuntime:ILStubCacheHit\n)\n\ndeclare -a DotNETRuntime_JitKeyword_NGenKeyword=(\n    DotNETRuntime:DCStartCompleteV2\n    DotNETRuntime:DCEndCompleteV2\n    DotNETRuntime:MethodDCStartV2\n    DotNETRuntime:MethodDCEndV2\n    DotNETRuntime:MethodDCStartVerboseV2\n    DotNETRuntime:MethodDCEndVerboseV2\n    DotNETRuntime:MethodLoad\n    DotNETRuntime:MethodLoad_V1\n    DotNETRuntime:MethodLoad_V2\n    DotNETRuntime:MethodUnload\n    DotNETRuntime:MethodUnload_V1\n    DotNETRuntime:MethodUnload_V2\n    DotNETRuntime:MethodLoadVerbose\n    DotNETRuntime:MethodLoadVerbose_V1\n    DotNETRuntime:MethodLoadVerbose_V2\n    DotNETRuntime:MethodUnloadVerbose\n    DotNETRuntime:MethodUnloadVerbose_V1\n    DotNETRuntime:MethodUnloadVerbose_V2\n)\n\ndeclare -a DotNETRuntime_JitKeyword=(\n    DotNETRuntime:MethodJittingStarted\n    DotNETRuntime:MethodJittingStarted_V1\n)\n\ndeclare -a DotNETRuntime_JitTracingKeyword=(\n    DotNETRuntime:MethodJitInliningSucceeded\n    DotNETRuntime:MethodJitInliningFailed\n    DotNETRuntime:MethodJitTailCallSucceeded\n    DotNETRuntime:MethodJitTailCallFailed\n)\n\ndeclare -a DotNETRuntime_JittedMethodILToNativeMapKeyword=(\n    DotNETRuntime:MethodILToNativeMap\n)\n\ndeclare -a DotNETRuntime_LoaderKeyword=(\n    DotNETRuntime:ModuleDCStartV2\n    DotNETRuntime:ModuleDCEndV2\n    DotNETRuntime:DomainModuleLoad\n    DotNETRuntime:DomainModuleLoad_V1\n    DotNETRuntime:ModuleLoad\n    DotNETRuntime:ModuleUnload\n    DotNETRuntime:AssemblyLoad\n    DotNETRuntime:AssemblyLoad_V1\n    DotNETRuntime:AssemblyUnload\n    DotNETRuntime:AssemblyUnload_V1\n    DotNETRuntime:AppDomainLoad\n    DotNETRuntime:AppDomainLoad_V1\n    DotNETRuntime:AppDomainUnload\n    DotNETRuntime:AppDomainUnload_V1\n)\n\ndeclare -a DotNETRuntime_LoaderKeyword=(\n    DotNETRuntime:ModuleLoad_V1\n    DotNETRuntime:ModuleLoad_V2\n    DotNETRuntime:ModuleUnload_V1\n    DotNETRuntime:ModuleUnload_V2\n)\n\ndeclare -a DotNETRuntime_SecurityKeyword=(\n    DotNETRuntime:StrongNameVerificationStart\n    DotNETRuntime:StrongNameVerificationStart_V1\n    DotNETRuntime:StrongNameVerificationStop\n    DotNETRuntime:StrongNameVerificationStop_V1\n    DotNETRuntime:AuthenticodeVerificationStart\n    DotNETRuntime:AuthenticodeVerificationStart_V1\n    DotNETRuntime:AuthenticodeVerificationStop\n    DotNETRuntime:AuthenticodeVerificationStop_V1\n)\n\ndeclare -a DotNETRuntime_DebuggerKeyword=(\n    DotNETRuntime:DebugIPCEventStart\n    DotNETRuntime:DebugIPCEventEnd\n    DotNETRuntime:DebugExceptionProcessingStart\n    DotNETRuntime:DebugExceptionProcessingEnd\n)\n\ndeclare -a DotNETRuntime_CodeSymbolsKeyword=(\n    DotNETRuntime:CodeSymbols\n)\n\ndeclare -a DotNETRuntime_CompilationKeyword=(\n    DotNETRuntime:TieredCompilationSettings\n    DotNETRuntime:TieredCompilationPause\n    DotNETRuntime:TieredCompilationResume\n    DotNETRuntime:TieredCompilationBackgroundJitStart\n    DotNETRuntime:TieredCompilationBackgroundJitStop\n    DotNETRuntimeRundown:TieredCompilationSettingsDCStart\n)\n\n# Separate GCCollectOnly list because our LTTng implementation doesn't set tracepoint verbosity.\n# Once tracepoint verbosity is set, we can set verbosity and collapse this with DotNETRuntimePrivate_GCPrivateKeyword.\ndeclare -a DotNETRuntimePrivate_GCPrivateKeyword_GCCollectOnly=(\n    DotNETRuntimePrivate:GCDecision\n    DotNETRuntimePrivate:GCDecision_V1\n    DotNETRuntimePrivate:GCSettings\n    DotNETRuntimePrivate:GCSettings_V1\n    DotNETRuntimePrivate:GCPerHeapHistory\n    DotNETRuntimePrivate:GCPerHeapHistory_V1\n    DotNETRuntimePrivate:GCGlobalHeapHistory\n    DotNETRuntimePrivate:GCGlobalHeapHistory_V1\n    DotNETRuntimePrivate:PrvGCMarkStackRoots\n    DotNETRuntimePrivate:PrvGCMarkStackRoots_V1\n    DotNETRuntimePrivate:PrvGCMarkFinalizeQueueRoots\n    DotNETRuntimePrivate:PrvGCMarkFinalizeQueueRoots_V1\n    DotNETRuntimePrivate:PrvGCMarkHandles\n    DotNETRuntimePrivate:PrvGCMarkHandles_V1\n    DotNETRuntimePrivate:PrvGCMarkCards\n    DotNETRuntimePrivate:PrvGCMarkCards_V1\n    DotNETRuntimePrivate:BGCBegin\n    DotNETRuntimePrivate:BGC1stNonConEnd\n    DotNETRuntimePrivate:BGC1stConEnd\n    DotNETRuntimePrivate:BGC2ndNonConBegin\n    DotNETRuntimePrivate:BGC2ndNonConEnd\n    DotNETRuntimePrivate:BGC2ndConBegin\n    DotNETRuntimePrivate:BGC2ndConEnd\n    DotNETRuntimePrivate:BGCPlanEnd\n    DotNETRuntimePrivate:BGCSweepEnd\n    DotNETRuntimePrivate:BGCDrainMark\n    DotNETRuntimePrivate:BGCRevisit\n    DotNETRuntimePrivate:BGCOverflow\n    DotNETRuntimePrivate:BGCAllocWaitBegin\n    DotNETRuntimePrivate:BGCAllocWaitEnd\n    DotNETRuntimePrivate:GCFullNotify\n    DotNETRuntimePrivate:GCFullNotify_V1\n    DotNETRuntimePrivate:PrvFinalizeObject\n    DotNETRuntimePrivate:PinPlugAtGCTime\n)\n\ndeclare -a DotNETRuntimePrivate_GCPrivateKeyword=(\n    DotNETRuntimePrivate:GCDecision\n    DotNETRuntimePrivate:GCDecision_V1\n    DotNETRuntimePrivate:GCSettings\n    DotNETRuntimePrivate:GCSettings_V1\n    DotNETRuntimePrivate:GCOptimized\n    DotNETRuntimePrivate:GCOptimized_V1\n    DotNETRuntimePrivate:GCPerHeapHistory\n    DotNETRuntimePrivate:GCPerHeapHistory_V1\n    DotNETRuntimePrivate:GCGlobalHeapHistory\n    DotNETRuntimePrivate:GCGlobalHeapHistory_V1\n    DotNETRuntimePrivate:GCJoin\n    DotNETRuntimePrivate:GCJoin_V1\n    DotNETRuntimePrivate:PrvGCMarkStackRoots\n    DotNETRuntimePrivate:PrvGCMarkStackRoots_V1\n    DotNETRuntimePrivate:PrvGCMarkFinalizeQueueRoots\n    DotNETRuntimePrivate:PrvGCMarkFinalizeQueueRoots_V1\n    DotNETRuntimePrivate:PrvGCMarkHandles\n    DotNETRuntimePrivate:PrvGCMarkHandles_V1\n    DotNETRuntimePrivate:PrvGCMarkCards\n    DotNETRuntimePrivate:PrvGCMarkCards_V1\n    DotNETRuntimePrivate:BGCBegin\n    DotNETRuntimePrivate:BGC1stNonConEnd\n    DotNETRuntimePrivate:BGC1stConEnd\n    DotNETRuntimePrivate:BGC2ndNonConBegin\n    DotNETRuntimePrivate:BGC2ndNonConEnd\n    DotNETRuntimePrivate:BGC2ndConBegin\n    DotNETRuntimePrivate:BGC2ndConEnd\n    DotNETRuntimePrivate:BGCPlanEnd\n    DotNETRuntimePrivate:BGCSweepEnd\n    DotNETRuntimePrivate:BGCDrainMark\n    DotNETRuntimePrivate:BGCRevisit\n    DotNETRuntimePrivate:BGCOverflow\n    DotNETRuntimePrivate:BGCAllocWaitBegin\n    DotNETRuntimePrivate:BGCAllocWaitEnd\n    DotNETRuntimePrivate:GCFullNotify\n    DotNETRuntimePrivate:GCFullNotify_V1\n    DotNETRuntimePrivate:PrvFinalizeObject\n    DotNETRuntimePrivate:PinPlugAtGCTime\n)\n\ndeclare -a DotNETRuntimePrivate_StartupKeyword=(\n    DotNETRuntimePrivate:EEStartupStart\n    DotNETRuntimePrivate:EEStartupStart_V1\n    DotNETRuntimePrivate:EEStartupEnd\n    DotNETRuntimePrivate:EEStartupEnd_V1\n    DotNETRuntimePrivate:EEConfigSetup\n    DotNETRuntimePrivate:EEConfigSetup_V1\n    DotNETRuntimePrivate:EEConfigSetupEnd\n    DotNETRuntimePrivate:EEConfigSetupEnd_V1\n    DotNETRuntimePrivate:LdSysBases\n    DotNETRuntimePrivate:LdSysBases_V1\n    DotNETRuntimePrivate:LdSysBasesEnd\n    DotNETRuntimePrivate:LdSysBasesEnd_V1\n    DotNETRuntimePrivate:ExecExe\n    DotNETRuntimePrivate:ExecExe_V1\n    DotNETRuntimePrivate:ExecExeEnd\n    DotNETRuntimePrivate:ExecExeEnd_V1\n    DotNETRuntimePrivate:Main\n    DotNETRuntimePrivate:Main_V1\n    DotNETRuntimePrivate:MainEnd\n    DotNETRuntimePrivate:MainEnd_V1\n    DotNETRuntimePrivate:ApplyPolicyStart\n    DotNETRuntimePrivate:ApplyPolicyStart_V1\n    DotNETRuntimePrivate:ApplyPolicyEnd\n    DotNETRuntimePrivate:ApplyPolicyEnd_V1\n    DotNETRuntimePrivate:LdLibShFolder\n    DotNETRuntimePrivate:LdLibShFolder_V1\n    DotNETRuntimePrivate:LdLibShFolderEnd\n    DotNETRuntimePrivate:LdLibShFolderEnd_V1\n    DotNETRuntimePrivate:PrestubWorker\n    DotNETRuntimePrivate:PrestubWorker_V1\n    DotNETRuntimePrivate:PrestubWorkerEnd\n    DotNETRuntimePrivate:PrestubWorkerEnd_V1\n    DotNETRuntimePrivate:GetInstallationStart\n    DotNETRuntimePrivate:GetInstallationStart_V1\n    DotNETRuntimePrivate:GetInstallationEnd\n    DotNETRuntimePrivate:GetInstallationEnd_V1\n    DotNETRuntimePrivate:OpenHModule\n    DotNETRuntimePrivate:OpenHModule_V1\n    DotNETRuntimePrivate:OpenHModuleEnd\n    DotNETRuntimePrivate:OpenHModuleEnd_V1\n    DotNETRuntimePrivate:ExplicitBindStart\n    DotNETRuntimePrivate:ExplicitBindStart_V1\n    DotNETRuntimePrivate:ExplicitBindEnd\n    DotNETRuntimePrivate:ExplicitBindEnd_V1\n    DotNETRuntimePrivate:ParseXml\n    DotNETRuntimePrivate:ParseXml_V1\n    DotNETRuntimePrivate:ParseXmlEnd\n    DotNETRuntimePrivate:ParseXmlEnd_V1\n    DotNETRuntimePrivate:InitDefaultDomain\n    DotNETRuntimePrivate:InitDefaultDomain_V1\n    DotNETRuntimePrivate:InitDefaultDomainEnd\n    DotNETRuntimePrivate:InitDefaultDomainEnd_V1\n    DotNETRuntimePrivate:InitSecurity\n    DotNETRuntimePrivate:InitSecurity_V1\n    DotNETRuntimePrivate:InitSecurityEnd\n    DotNETRuntimePrivate:InitSecurityEnd_V1\n    DotNETRuntimePrivate:AllowBindingRedirs\n    DotNETRuntimePrivate:AllowBindingRedirs_V1\n    DotNETRuntimePrivate:AllowBindingRedirsEnd\n    DotNETRuntimePrivate:AllowBindingRedirsEnd_V1\n    DotNETRuntimePrivate:EEConfigSync\n    DotNETRuntimePrivate:EEConfigSync_V1\n    DotNETRuntimePrivate:EEConfigSyncEnd\n    DotNETRuntimePrivate:EEConfigSyncEnd_V1\n    DotNETRuntimePrivate:FusionBinding\n    DotNETRuntimePrivate:FusionBinding_V1\n    DotNETRuntimePrivate:FusionBindingEnd\n    DotNETRuntimePrivate:FusionBindingEnd_V1\n    DotNETRuntimePrivate:LoaderCatchCall\n    DotNETRuntimePrivate:LoaderCatchCall_V1\n    DotNETRuntimePrivate:LoaderCatchCallEnd\n    DotNETRuntimePrivate:LoaderCatchCallEnd_V1\n    DotNETRuntimePrivate:FusionInit\n    DotNETRuntimePrivate:FusionInit_V1\n    DotNETRuntimePrivate:FusionInitEnd\n    DotNETRuntimePrivate:FusionInitEnd_V1\n    DotNETRuntimePrivate:FusionAppCtx\n    DotNETRuntimePrivate:FusionAppCtx_V1\n    DotNETRuntimePrivate:FusionAppCtxEnd\n    DotNETRuntimePrivate:FusionAppCtxEnd_V1\n    DotNETRuntimePrivate:Fusion2EE\n    DotNETRuntimePrivate:Fusion2EE_V1\n    DotNETRuntimePrivate:Fusion2EEEnd\n    DotNETRuntimePrivate:Fusion2EEEnd_V1\n    DotNETRuntimePrivate:SecurityCatchCall\n    DotNETRuntimePrivate:SecurityCatchCall_V1\n    DotNETRuntimePrivate:SecurityCatchCallEnd\n    DotNETRuntimePrivate:SecurityCatchCallEnd_V1\n)\n\ndeclare -a DotNETRuntimePrivate_StackKeyword=(\n    DotNETRuntimePrivate:CLRStackWalkPrivate\n)\n\ndeclare -a DotNETRuntimePrivate_PerfTrackPrivateKeyword=(\n    DotNETRuntimePrivate:ModuleRangeLoadPrivate\n)\n\ndeclare -a DotNETRuntimePrivate_BindingKeyword=(\n    DotNETRuntimePrivate:BindingPolicyPhaseStart\n    DotNETRuntimePrivate:BindingPolicyPhaseEnd\n    DotNETRuntimePrivate:BindingNgenPhaseStart\n    DotNETRuntimePrivate:BindingNgenPhaseEnd\n    DotNETRuntimePrivate:BindingLookupAndProbingPhaseStart\n    DotNETRuntimePrivate:BindingLookupAndProbingPhaseEnd\n    DotNETRuntimePrivate:LoaderPhaseStart\n    DotNETRuntimePrivate:LoaderPhaseEnd\n    DotNETRuntimePrivate:BindingPhaseStart\n    DotNETRuntimePrivate:BindingPhaseEnd\n    DotNETRuntimePrivate:BindingDownloadPhaseStart\n    DotNETRuntimePrivate:BindingDownloadPhaseEnd\n    DotNETRuntimePrivate:LoaderAssemblyInitPhaseStart\n    DotNETRuntimePrivate:LoaderAssemblyInitPhaseEnd\n    DotNETRuntimePrivate:LoaderMappingPhaseStart\n    DotNETRuntimePrivate:LoaderMappingPhaseEnd\n    DotNETRuntimePrivate:LoaderDeliverEventsPhaseStart\n    DotNETRuntimePrivate:LoaderDeliverEventsPhaseEnd\n    DotNETRuntimePrivate:FusionMessageEvent\n    DotNETRuntimePrivate:FusionErrorCodeEvent\n)\n\ndeclare -a DotNETRuntimePrivate_SecurityPrivateKeyword=(\n    DotNETRuntimePrivate:EvidenceGenerated\n    DotNETRuntimePrivate:ModuleTransparencyComputationStart\n    DotNETRuntimePrivate:ModuleTransparencyComputationEnd\n    DotNETRuntimePrivate:TypeTransparencyComputationStart\n    DotNETRuntimePrivate:TypeTransparencyComputationEnd\n    DotNETRuntimePrivate:MethodTransparencyComputationStart\n    DotNETRuntimePrivate:MethodTransparencyComputationEnd\n    DotNETRuntimePrivate:FieldTransparencyComputationStart\n    DotNETRuntimePrivate:FieldTransparencyComputationEnd\n    DotNETRuntimePrivate:TokenTransparencyComputationStart\n    DotNETRuntimePrivate:TokenTransparencyComputationEnd\n)\n\ndeclare -a DotNETRuntimePrivate_PrivateFusionKeyword=(\n    DotNETRuntimePrivate:NgenBindEvent\n)\n\ndeclare -a DotNETRuntimePrivate_NoKeyword=(\n    DotNETRuntimePrivate:FailFast\n)\n\ndeclare -a DotNETRuntimePrivate_InteropPrivateKeyword=(\n    DotNETRuntimePrivate:CCWRefCountChange\n)\n\ndeclare -a DotNETRuntimePrivate_GCHandlePrivateKeyword=(\n    DotNETRuntimePrivate:PrvSetGCHandle\n    DotNETRuntimePrivate:PrvDestroyGCHandle\n)\n\ndeclare -a DotNETRuntimePrivate_LoaderHeapPrivateKeyword=(\n    DotNETRuntimePrivate:AllocRequest\n)\n\ndeclare -a DotNETRuntimePrivate_MulticoreJitPrivateKeyword=(\n    DotNETRuntimePrivate:MulticoreJit\n    DotNETRuntimePrivate:MulticoreJitMethodCodeReturned\n)\n\ndeclare -a DotNETRuntimePrivate_DynamicTypeUsageKeyword=(\n    DotNETRuntimePrivate:IInspectableRuntimeClassName\n    DotNETRuntimePrivate:WinRTUnbox\n    DotNETRuntimePrivate:CreateRCW\n    DotNETRuntimePrivate:RCWVariance\n    DotNETRuntimePrivate:RCWIEnumerableCasting\n    DotNETRuntimePrivate:CreateCCW\n    DotNETRuntimePrivate:CCWVariance\n    DotNETRuntimePrivate:ObjectVariantMarshallingToNative\n    DotNETRuntimePrivate:GetTypeFromGUID\n    DotNETRuntimePrivate:GetTypeFromProgID\n    DotNETRuntimePrivate:ConvertToCallbackEtw\n    DotNETRuntimePrivate:BeginCreateManagedReference\n    DotNETRuntimePrivate:EndCreateManagedReference\n    DotNETRuntimePrivate:ObjectVariantMarshallingToManaged\n)\n\ndeclare -a EventSource=(\n    DotNETRuntime:EventSource\n)\n\ndeclare -a LTTng_Kernel_ProcessLifetimeKeyword=(\n    sched_process_exec\n    sched_process_exit\n)\n\n\n######################################\n## Global Variables\n######################################\n\n# Install without waiting for standard input\nforceInstall=0\n\n# Declare an array of events to collect.\ndeclare -a eventsToCollect\n\n# Use Perf_Event\nusePerf=1\n\n# Use LTTng\nuseLTTng=1\n\n# LTTng Installed\nlttngInstalled=0\n\n# Collect hardware events\ncollect_HWevents=0\n\n# Set to 1 when the CTRLC_Handler gets invoked.\nhandlerInvoked=0\n\n# Log file\ndeclare logFile\nlogFilePrefix='/tmp/perfcollect'\nlogEnabled=0\n\n# Collect info to pass between processes\ncollectInfoFile=$(dirname `mktemp -u`)/'perfcollect.sessioninfo'\n\n######################################\n## Logging Functions\n######################################\nLogAppend()\n{\n    if (( $logEnabled == 1 ))\n    then\n        echo $* >> $logFile\n    fi\n}\n\nRunSilent()\n{\n    if (( $logEnabled == 1 ))\n    then\n        echo \"Running \\\"$*\\\"\" >> $logFile\n        $* >> $logFile 2>&1\n        echo \"\" >> $logFile\n    else\n        $* > /dev/null 2>&1\n    fi\n}\n\nRunSilentBackground()\n{\n    if (( $logEnabled == 1 ))\n    then\n        echo \"Running \\\"$*\\\"\" >> $logFile\n        $* >> $logFile 2>&1  & sleep 1\n        echo \"\" >> $logFile\n    else\n        $* > /dev/null 2>&1  & sleep 1\n    fi\n\n    # When handler is invoked, kill the process.\n    pid=$!\n    for (( ; ; ))\n    do\n        if [ \"$handlerInvoked\" == \"1\" ]\n        then\n            kill -INT $pid\n            break;\n        else\n            sleep 1\n        fi\t\n    done\n\n    # Wait for the process to exit.\n    wait $pid\n}\n\nInitializeLog()\n{\n    # Pick the log file name.\n    logFile=\"$logFilePrefix.log\"\n    while [ -f $logFile ];\n    do\n        logFile=\"$logFilePrefix.$RANDOM.log\"\n    done\n\n    # Mark the log as enabled.\n    logEnabled=1\n\n    # Start the log\n    date=`date`\n    echo \"Log started at ${date}\" > $logFile\n    echo '' >> $logFile\n\n    # The system information.\n    LogAppend 'Machine info: '  `uname -a`\n    if [ \"$perfcmd\" != \"\" ]\n    then\n        LogAppend 'perf version:'   `$perfcmd --version 2>&1`\n    fi\n    if [ \"$lttngcmd\" != \"\" ]\n    then\n        LogAppend 'LTTng version: ' `$lttngcmd --version`\n    fi\n    LogAppend\n}\n\nCloseLog()\n{\n    LogAppend \"END LOG FILE\"\n    LogAppend \"NOTE: It is normal for the log file to end right before the trace is actually compressed.  This occurs because the log file is part of the archive, and thus can't be written anymore.\"\n\n    # The log itself doesn't need to be closed,\n    # but we need to tell the script not to log anymore.\n    logEnabled=0\n}\n\n\n######################################\n## Helper Functions\n######################################\n\n##\n# Console text color modification helpers.\n##\nRedText()\n{\n    tput=`GetCommandFullPath \"tput\"`\n    if [ \"$tput\" != \"\" ]\n    then\n    \t$tput setaf 1\n    fi\n}\n\nGreenText()\n{\n    tput=`GetCommandFullPath \"tput\"`\n    if [ \"$tput\" != \"\" ]\n    then\n        $tput setaf 2\n    fi\n}\n\nBlueText()\n{\n    tput=`GetCommandFullPath \"tput\"`\n    if [ \"$tput\" != \"\" ]\n    then\n        $tput setaf 6\n    fi\n}\nYellowText()\n{\n    tput=`GetCommandFullPath \"tput\"`\n    if [ \"$tput\" != \"\" ]\n    then\n        $tput setaf 3\n    fi\n}\n\nResetText()\n{\n    tput=`GetCommandFullPath \"tput\"`\n    if [ \"$tput\" != \"\" ]\n    then\n        $tput sgr0\n    fi\n}\n\n# $1 == Status message\nWriteStatus()\n{\n    LogAppend $*\n    BlueText\n    echo $1\n    ResetText\n}\n\n# $1 == Message.\nWriteWarning()\n{\n    LogAppend $*\n    YellowText\n    echo $1\n    ResetText\n}\n\n# $1 == Message.\nFatalError()\n{\n    RedText\n    echo \"ERROR: $1\"\n    ResetText\n    PrintUsage\n    exit 1\n}\n\nEnsureRoot()\n{\n    # Warn non-root users.\n    if [ `whoami` != \"root\" ]\n    then\n        RedText\n        echo \"This script must be run as root.\"\n        ResetText\n        exit 1;\n    fi\n}\n\n######################################\n# Command Discovery\n######################################\nDiscoverCommands()\n{\n    perfcmd=`GetCommandFullPath \"perf\"`\n    if [ \"$(IsDebian)\" == \"1\" ]\n    then\n        # Test perf to see if it successfully runs or fails because it doesn't match the kernel version.\n        $perfcmd --version > /dev/null 2>&1\n        if [ \"$?\" == \"1\" ]\n        then\n            perf49Cmd=`GetCommandFullPath \"perf_4.9\"`\n            $perf49Cmd --version > /dev/null 2>&1\n            if [ \"$?\" == \"0\" ]\n            then\n                perfcmd=$perf49Cmd\n            else\n                perf419Cmd=`GetCommandFullPath \"perf_4.19\"`\n                $perf419Cmd --version > /dev/null 2>&1\n                if [ \"$?\" == \"0\" ]\n                then\n                    perfcmd=$perf419Cmd\n                else\n                    perf316Cmd=`GetCommandFullPath \"perf_3.16\"`\n                    $perf316Cmd --version > /dev/null 2>&1\n                    if [ \"$?\" == \"0\" ]\n                    then\n                        perfcmd=$perf316Cmd\n                    fi\n                fi\n            fi\n        fi\n    fi\n\n    # Check to see if perf is installed, but doesn't exactly match the current kernel version.\n    # This happens when the kernel gets upgraded, or when running inside of a container where the\n    # host and container OS versions don't match.\n    perfoutput=$($perfcmd 2>&1)\n    if [ $? -eq 2 ]\n    then\n        # Check the beginning of the output to see if it matches the kernel warning.\n        warningText=\"WARNING: perf not found for kernel\"\n        if [[ \"$perfoutput\" == \"$warningText\"* ]]\n        then\n            foundWorkingPerf=0\n            WriteWarning \"Perf is installed, but does not exactly match the version of the running kernel.\"\n            WriteWarning \"This is often OK, and we'll try to workaround this.\"\n            WriteStatus \"Attempting to find a working copy of perf.\"\n            # Attempt to find an existing version of perf to use.\n            # Order the search by newest directory first.\n            baseDir=\"/usr/lib/linux-tools\"\n            searchPath=\"$baseDir/*/\"\n            for dirName in $(ls -d --sort=time $searchPath)\n            do\n                candidatePerfPath=\"$dirName\"\"perf\"\n                $($candidatePerfPath > /dev/null 2>&1)\n                if [ $? -eq 1 ]\n                then\n                    # If $? == 1, then use this copy of perf.\n                    perfcmd=$candidatePerfPath\n                    foundWorkingPerf=1\n                    break;\n                fi\n            done\n            if [ $foundWorkingPerf -eq 0 ]\n            then\n                FatalError \"Unable to find a working copy of perf.  Try re-installing via ./perfcollect install.\"\n            fi\n            WriteStatus \"...FINISHED\"\n        fi\n    fi\n\n    lttngcmd=`GetCommandFullPath \"lttng\"`\n    zipcmd=`GetCommandFullPath \"zip\"`\n    unzipcmd=`GetCommandFullPath \"unzip\"`\n    objdumpcmd=`GetCommandFullPath \"objdump\"`\n}\n\nGetCommandFullPath()\n{\n    echo `command -v $1`\n}\n\n######################################\n# Prerequisite Installation\n######################################\nIsAlpine()\n{\n    local alpine=0\n    local apk=`GetCommandFullPath \"apk\"`\n    if [ \"$apk\" != \"\" ]\n    then\n        alpine=1\n    fi\n\n    echo $alpine\n}\n\nInstallPerf_Alpine()\n{\n    # Disallow non-root users.\n    EnsureRoot\n\n    # Install perf\n    apk add perf --repository=http://dl-cdn.alpinelinux.org/alpine/edge/community\n\n    # Install zip and unzip\n    apk add zip unzip\n}\n\nIsRHEL()\n{\n    local rhel=0\n    if [ -f /etc/redhat-release ]\n    then\n        rhel=1\n    fi\n\n    echo $rhel\n}\n\nInstallPerf_RHEL()\n{\n    # Disallow non-root users.\n    EnsureRoot\n\n    # Install perf\n    yum install perf zip unzip\n}\n\nIsDebian()\n{\n    local debian=0\n    local uname=`uname -a`\n    if [[ $uname =~ .*Debian.* ]]\n    then\n        debian=1\n    elif [ -f /etc/debian_version ]\n    then\n        debian=1\n    fi\n\n    echo $debian\n}\n\nInstallPerf_Debian()\n{\n    # Disallow non-root users.\n    EnsureRoot\n\n    # Check for the existence of the linux-tools package.\n    pkgName='linux-tools'\n    pkgCount=`apt-cache search $pkgName | grep -c $pkgName`\n    if [ \"$pkgCount\" == \"0\" ]\n    then\n        pkgName='linux-perf'\n        pkgCount=`apt-cache search $pkgName | grep -c $pkgName`\n        if [ \"$pkgCount\" == \"0\" ]\n        then\n            FatalError \"Unable to find a perf package to install.\"\n        fi\n    fi\n\n    # Install zip and perf.\n    apt-get install -y zip binutils $pkgName\n}\n\nIsSUSE()\n{\n    local suse=0\n    if [ -f /usr/bin/zypper ]\n    then\n        suse=1\n    fi\n\n    echo $suse\n}\n\nInstallPerf_SUSE()\n{\n    # Disallow non-root users.\n    EnsureRoot\n\n    # Install perf.\n    zypper install perf zip unzip\n}\n\nIsUbuntu()\n{\n    local ubuntu=0\n    if [ -f /etc/lsb-release ]\n    then\n        local flavor=`cat /etc/lsb-release | grep DISTRIB_ID`\n        if [ \"$flavor\" == \"DISTRIB_ID=Ubuntu\" ]\n        then\n            ubuntu=1\n        fi\n    fi\n        \n    echo $ubuntu\n}\n\nInstallPerf_Ubuntu()\n{\n    # Disallow non-root users.\n    EnsureRoot\n\n    # Install packages.\n    BlueText\n    echo \"Installing perf_event packages.\"\n    ResetText\n\n    # Handle Azure instances.\n    release=`uname -r`\n    if [[ \"$release\" == *\"-azure\" ]]\n    then\n        apt-get install -y linux-tools-azure zip software-properties-common\n    else\n        apt-get install -y linux-tools-common linux-tools-`uname -r` linux-cloud-tools-`uname -r` zip software-properties-common\n    fi\n}\n\nInstallPerf()\n{\n    if [ \"$(IsUbuntu)\" == \"1\" ]\n    then\n        InstallPerf_Ubuntu\n    elif [ \"$(IsSUSE)\" == \"1\" ]\n    then\n        InstallPerf_SUSE\n    elif [ \"$(IsDebian)\" == \"1\" ]\n    then\n        InstallPerf_Debian\n    elif [ \"$(IsRHEL)\" == \"1\" ]\n    then\n        InstallPerf_RHEL\n    elif [ \"$(IsAlpine)\" == \"1\" ]\n    then\n        InstallPerf_Alpine\n    else\n        FatalError \"Auto install unsupported for this distribution.  Install perf manually to continue.\"\n    fi\n}\n\nInstallLTTng_RHEL()\n{\n    # Disallow non-root users.\n    EnsureRoot\n\n    local isRHEL7=0\n    local isRHEL8=0\n    if [ -e /etc/redhat-release ]; then\n        local redhatRelease=$(</etc/redhat-release)\n        if   [[ $redhatRelease == \"CentOS Linux release 7.\"* || $redhatRelease == \"Red Hat Enterprise Linux \"*\"release 7.\"* ]]; then\n            isRHEL7=1\n        elif [[ $redhatRelease == \"CentOS Linux release 8.\"* || $redhatRelease == \"Red Hat Enterprise Linux \"*\"release 8.\"* ]]; then\n            isRHEL8=1\n        fi\n    fi\n\n    if  [ \"$isRHEL7\" == \"1\" ] || [ \"$isRHEL8\" == \"1\" ]\n    then\n        packageRepo=\"https://packages.efficios.com/repo.files/EfficiOS-RHEL7-x86-64.repo\"\n\n        if [ \"$forceInstall\" != 1 ]\n        then\n            # Prompt for confirmation, since we need to add a new repository.\n            BlueText\n            echo \"LTTng installation requires that a new package repo be added to your yum configuration.\"\n            echo \"The package repo url is: $packageRepo\"\n            echo \"\"\n            read -p \"Would you like to add the LTTng package repo to your YUM configuration? [Y/N]\" resp\n            ResetText\n        fi\n\n        # Make sure that wget is installed.\n        BlueText\n        echo \"Installing wget.  Required to add package repo.\"\n        ResetText\n        yum install wget\n\n        # Connect to the LTTng package repo.\n        wget -P /etc/yum.repos.d/ $packageRepo\n\n        # Import package signing key.\n        rpmkeys --import https://packages.efficios.com/rhel/repo.key\n\n        # Update the yum package database.\n        yum updateinfo\n    fi\n\n    # Install LTTng\n    yum install -y lttng-tools lttng-ust babeltrace\n    if  [ \"$isRHEL7\" == \"1\" ]\n    then\n        yum install -y kmod-lttng-modules\n    else\n        YellowText\n        echo \"LTTng kernel package (kmod-lttng-modules) is not available on this platform.\"\n        ResetText\n    fi\n}\n\nInstallLTTng_Debian()\n{\n    # Disallow non-root users.\n    EnsureRoot\n\n    # Install LTTng\n    apt-get install -y lttng-tools liblttng-ust-dev\n}\n\nInstallLTTng_SUSE()\n{\n    # Disallow non-root users.\n    EnsureRoot\n\n    # Package repo url\n    packageRepo=\"http://download.opensuse.org/repositories/devel:/tools:/lttng/openSUSE_13.2/devel:tools:lttng.repo\"\n\n    if [ \"$forceInstall\" != 1 ]\n    then\n        # Prompt for confirmation, since we need to add a new repository.\n        BlueText\n        echo \"LTTng installation requires that a new package repo be added to your zypper configuration.\"\n        echo \"The package repo url is: $packageRepo\"\n        echo \"\"\n        read -p \"Would you like to add the LTTng package repo to your zypper configuration? [Y/N]\" resp\n        ResetText\n    fi\n    if [ \"$resp\" == \"Y\" ] || [ \"$resp\" == \"y\" ] || [ \"$forceInstall\" == 1 ]\n    then\n\n        # Add package repo.\n        BlueText\n        echo \"Adding LTTng repo and running zypper refresh.\"\n        ResetText\n        zypper addrepo $packageRepo\n        zypper refresh\n\n        # Install packages.\n        BlueText\n        echo \"Installing LTTng packages.\"\n        ResetText\n        zypper install lttng-tools lttng-modules lttng-ust-devel\n    fi\n}\n\nInstallLTTng_Ubuntu()\n{\n    # Disallow non-root users.\n    EnsureRoot\n\n    # Install packages.\n    BlueText\n    echo \"Installing LTTng packages.\"\n    ResetText\n    apt-get install -y lttng-tools lttng-modules-dkms liblttng-ust0\n}\n\nInstallLTTng()\n{\n    if [ \"$(IsUbuntu)\" == \"1\" ]\n    then\n        InstallLTTng_Ubuntu\n    elif [ \"$(IsSUSE)\" == \"1\" ]\n    then\n        InstallLTTng_SUSE\n    elif [ \"$(IsDebian)\" == \"1\" ]\n    then\n        InstallLTTng_Debian\n    elif [ \"$(IsRHEL)\" == \"1\" ]\n    then\n        InstallLTTng_RHEL\n    elif [ \"$(IsAlpine)\" == \"1\" ]\n    then\n        echo \"lttng-tools is not available on Alpine Linux, so no lttng-ust events will be collected.\"\n    else\n        FatalError \"Auto install unsupported for this distribution.  Install lttng and lttng-ust packages manually.\"\n    fi\n}\n\nSupportsAutoInstall()\n{\n    local supportsAutoInstall=0\n    if [ \"$(IsUbuntu)\" == \"1\" ] || [ \"$(IsSUSE)\" == \"1\" ]\n    then\n        supportsAutoInstall=1\n    fi\n    \n    echo $supportsAutoInstall\n}\n\nEnsurePrereqsInstalled()\n{\n    # If perf is not installed, then bail, as it is currently required.\n    if [ \"$perfcmd\" == \"\" ]\n    then\n        RedText\n        echo \"Perf not installed.\"\n        if  [ \"$(SupportsAutoInstall)\" == \"1\" ]\n        then\n            echo \"Run ./perfcollect install\"\n            echo \"or install perf manually.\"\n        else\n            echo \"Install perf to proceed.\"\n        fi\n        ResetText\n        exit 1\n    fi\n\n    # Disable LTTng use if running on Alpine.\n    if [ \"$(IsAlpine)\" == \"1\" ]\n    then\n        useLTTng=0\n    fi\n\n    # If LTTng is installed, consider using it.\n    if [ \"$lttngcmd\" == \"\" ] && [ \"$useLTTng\" == \"1\" ]\n    then\n        RedText\n        echo \"LTTng not installed.\"\n        if  [ \"$(SupportsAutoInstall)\" == \"1\" ]\n        then\n            echo \"Run ./perfcollect install\"\n            echo \"or install LTTng manually.\"\n        else\n            echo \"Install LTTng to proceed.\"\n        fi\n        ResetText\n        exit 1\n\n    fi\n\n    # If zip or unzip are not installing, then bail.\n    if [ \"$zipcmd\" == \"\" ] || [ \"$unzipcmd\" == \"\" ]\n    then\n        RedText\n        echo \"Zip and unzip are not installed.\"\n        if [ \"$(SupportsAutoInstall)\" == \"1\" ]\n        then\n            echo \"Run ./perfcollect install\"\n            echo \"or install zip and unzip manually.\"\n        else\n            echo \"Install zip and unzip to proceed.\"\n        fi\n        ResetText\n        exit 1\n    fi\n}\n\n######################################\n# Argument Processing\n######################################\naction=''\ninputTraceName=''\ncollectionPid=''\nprocessFilter=''\ngraphType=''\nperfOpt=''\nviewer='perf'\ngcCollectOnly=''\ngcOnly=''\ngcWithHeap=''\nevents=''\n\nProcessArguments()\n{\n    # Set the action\n    action=$1\n\n    # Actions with no arguments.\n    if [ \"$action\" == \"livetrace\" ]\n    then\n        return\n    fi\n    \n    # Not enough arguments.\n    if [ \"$#\" -le \"1\" ]\n    then\n        FatalError \"Not enough arguments have been specified.\"\n    fi\n\n    # Validate action name.\n    if [ \"$action\" != \"collect\" ] && [ \"$action\" != \"view\" ] \\\n    && [ \"$action\" != \"start\" ] && [ \"$action\" != \"stop\" ]\n    then\n        FatalError \"Invalid action specified.\"\n    fi\n\n    # Set the data file.\n    inputTraceName=$2\n    if [ \"$inputTraceName\" == \"\" ] \n    then\n        FatalError \"Invalid trace name specified.\"\n    fi\n\n    # Process remaining arguments.\n    # First copy the args into an array so that we can walk the array.\n    args=( \"$@\" )\n    for (( i=2; i<${#args[@]}; i++ ))\n    do\n        # Get the arg.\n        local arg=${args[$i]}\n\n        # Convert the arg to lower case.\n        arg=`echo $arg | tr '[:upper:]' '[:lower:]'`\n\n        # Get the arg value.\n        if [ ${i+1} -lt $# ]\n        then\n            local value=${args[$i+1]}\n\n            # Keep the cases of '-events' value to match keyword variables\n            if [ \"-events\" != \"$arg\" ]\n            then\n                # Convert the value to lower case.\n                value=`echo $value | tr '[:upper:]' '[:lower:]'`\n            fi\n        fi\n\n        # Match the arg to a known value.\n        if [ \"-pid\" == \"$arg\" ]\n        then\n            collectionPid=$value\n            i=$i+1\n        elif [ \"-processfilter\" == \"$arg\" ]\n        then\n            processFilter=$value\n            i=$i+1\n        elif [ \"-graphtype\" == \"$arg\" ]\n        then\n            graphType=$value\n            i=$i+1\n        elif [ \"-threadtime\" == \"$arg\" ]\n        then\n            collect_threadTime=1\n        elif [ \"-offcpu\" == \"$arg\" ]\n        then\n            # Perf doesn't support capturing cpu-clock events and sched events concurrently.\n            collect_cpu=0\n            collect_offcpu=1\n        elif [ \"-hwevents\" == \"$arg\" ]\n        then\n            collect_HWevents=1\n        elif [ \"-perfopt\" == \"$arg\" ]\n        then\n            perfOpt=$value\n            i=$i+1\n        elif [ \"-viewer\" == \"$arg\" ]\n        then\n            viewer=$value\n            i=$i+1\n\n            # Validate the viewer.\n            if [ \"$viewer\" != \"perf\" ] && [ \"$viewer\" != \"lttng\" ]\n            then\n                FatalError \"Invalid viewer specified.  Valid values are 'perf' and 'lttng'.\"\n            fi\n        elif [ \"-nolttng\" == \"$arg\" ]\n        then\n            useLTTng=0\n        elif [ \"-noperf\" == \"$arg\" ]\n        then \n            usePerf=0\n        elif [ \"-gccollectonly\" == \"$arg\" ]\n        then\n            gcCollectOnly=1\n        elif [ \"-gconly\" == \"$arg\" ]\n        then\n            gcOnly=1\n        elif [ \"-gcwithheap\" == \"$arg\" ]\n        then\n            gcWithHeap=1\n        elif [ \"-events\" == \"$arg\" ]\n        then\n            events=$value\n            i=$i+1\n        elif [ \"-collectsec\" == \"$arg\" ]\n        then\n            duration=$value\n            i=$i+1\n        else\n            echo \"Unknown arg ${arg}, ignored...\"\n        fi\n    done\n    \n}\n\n\n\n##\n# LTTng collection\n##\nlttngSessionName=''\nlttngTraceDir=''\nCreateLTTngSession()\n{\n    if [ \"$action\" == \"livetrace\" ]\n    then\n        output=`$lttngcmd create --live`\n    else\n        output=`$lttngcmd create`\n    fi\n\n    lttngSessionName=`echo $output | grep -o \"Session.*created.\" | sed 's/\\(Session \\| created.\\)//g'`\n    lttngTraceDir=`echo $output | grep -o \"Traces.*\" | sed 's/\\(Traces will be written in \\|\\)//g' | sed 's/\\(Traces will be output to \\|\\)//g'`\n}\n\nSetupLTTngSession()\n{\n    \n    # Setup per-event context information.\n    RunSilent \"$lttngcmd add-context --userspace --type vpid\"\n    RunSilent \"$lttngcmd add-context --userspace --type vtid\"\n    RunSilent \"$lttngcmd add-context --userspace --type procname\"\n    RunSilent \"$lttngcmd add-context --kernel -t pid -t procname\"\n\n    if [ \"$action\" == \"livetrace\" ]\n    then\n        RunSilent \"$lttngcmd enable-event --userspace --tracepoint DotNETRuntime:EventSource\"\n    elif [ \"$gcCollectOnly\" == \"1\" ]\n    then\n        usePerf=0\n        EnableLTTngEvents ${DotNETRuntime_GCKeyword_GCCollectOnly[@]}\n        EnableLTTngEvents ${DotNETRuntimePrivate_GCPrivateKeyword_GCCollectOnly[@]}\n        EnableLTTngEvents ${DotNETRuntime_ExceptionKeyword[@]}\n    elif [ \"$gcOnly\" == \"1\" ]\n    then\n        usePerf=0\n        EnableLTTngEvents ${DotNETRuntime_GCKeyword[@]}\n        EnableLTTngEvents ${DotNETRuntimePrivate_GCPrivateKeyword[@]}\n        EnableLTTngEvents ${DotNETRuntime_JitKeyword[@]}\n        EnableLTTngEvents ${DotNETRuntime_LoaderKeyword[@]}\n        EnableLTTngEvents ${DotNETRuntime_ExceptionKeyword[@]}\n    elif [ \"$gcWithHeap\" == \"1\" ]\n    then\n        usePerf=0\n        EnableLTTngEvents ${DotNETRuntime_GCKeyword[@]}\n        EnableLTTngEvents ${DotNETRuntime_GCHeapSurvivalAndMovementKeyword[@]}\n    else\n        if [ \"$events\" == \"\" ]\n        then\n            # Enable the default set of events.\n            EnableLTTngEvents ${DotNETRuntime_ThreadingKeyword[@]}\n            EnableLTTngEvents ${DotNETRuntime_ThreadingKeyword_ThreadTransferKeyword[@]}\n            EnableLTTngEvents ${DotNETRuntime_NoKeyword[@]}\n            EnableLTTngEvents ${DotNETRuntime_ExceptionKeyword[@]}\n            EnableLTTngEvents ${DotNETRuntime_ContentionKeyword[@]}\n            EnableLTTngEvents ${DotNETRuntime_JitKeyword_NGenKeyword[@]}\n            EnableLTTngEvents ${DotNETRuntime_JitKeyword[@]}\n            EnableLTTngEvents ${DotNETRuntime_LoaderKeyword[@]}\n            EnableLTTngEvents ${DotNETRuntime_GCKeyword_GCCollectOnly[@]}\n            EnableLTTngEvents ${DotNETRuntimePrivate_GCPrivateKeyword_GCCollectOnly[@]}\n            EnableLTTngEvents ${DotNETRuntimePrivate_BindingKeyword[@]}\n            EnableLTTngEvents ${DotNETRuntimePrivate_MulticoreJitPrivateKeyword[@]}\n            EnableLTTngEvents ${DotNETRuntime_CompilationKeyword[@]}\n        elif [ \"$events\" == \"threading\" ]\n        then\n            EnableLTTngEvents ${DotNETRuntime_ThreadingKeyword[@]}\n        else     \n            # Enable other keywords\n            events=(${events//\",\"/\" \"})\n            for event in ${events[@]}\n            do \n                if [ \"${!event}\" == \"\" ] || [ \"$( echo `declare -p $event | grep -- -a` )\" == \"\" ]\n                then\n                    echo Invalid keyword $event, skipped...\n                    continue\n                fi\n                local -a 'keywords=(\"${'\"$event\"'[@]}\")'\n                if [ \"${event#\"LTTng_Kernel_\"}\" != \"$event\" ]\n                then \n                    EnableLTTngKernelEvents ${keywords[@]}\n                else\n                    EnableLTTngEvents ${keywords[@]}\n                fi\n            done\n        fi\n    fi\n}\n\nDestroyLTTngSession()\n{\n    RunSilent \"$lttngcmd destroy $lttngSessionName\"\n}\n\nStartLTTngCollection()\n{\n    CreateLTTngSession\n    SetupLTTngSession\n\n    RunSilent \"$lttngcmd start $lttngSessionName\"\n}\n\nStopLTTngCollection()\n{\n    RunSilent \"$lttngcmd stop $lttngSessionName\"\n    DestroyLTTngSession\n}\n\n# $@ == event names to be enabled\nEnableLTTngEvents()\n{\n    args=( \"$@\" )\n    for (( i=0; i<${#args[@]}; i++ ))\n    do\n        RunSilent \"$lttngcmd enable-event -s $lttngSessionName -u --tracepoint ${args[$i]}\"\n    done\n}\n\nEnableLTTngKernelEvents()\n{\n    args=( \"$@\" )\n    for (( i=0; i<${#args[@]}; i++ ))\n    do \n        RunSilent \"$lttngcmd enable-event -s $lttngSessionName -k ${args[$i]}\"\n    done\n}\n\n##\n# Helper that processes collected data.\n# This helper is called when the CTRL+C signal is handled.\n##\nProcessCollectedData()\n{\n    # Make a new target directory.\n    local traceSuffix=\".trace\"\n    local traceName=$inputTraceName\n    local directoryName=$traceName$traceSuffix\n    mkdir $directoryName\n\n    # Save LTTng trace files.\n    if [ \"$useLTTng\" == \"1\" ]\n    then\n        LogAppend \"Saving LTTng trace files.\"\n\n        if [ -d $lttngTraceDir ]\n        then\n            RunSilent \"mkdir lttngTrace\"\n            RunSilent \"cp -r $lttngTraceDir lttngTrace\"\n        fi\n    fi\n\n    if [ \"$usePerf\" == 1 ]\n    then\n        # Get any perf-$pid.map files that were used by the\n        # trace and store them alongside the trace.\n        local writeCrossgenWarning=1\n        LogAppend \"Saving perf.map files.\"\n        RunSilent \"$perfcmd buildid-list --with-hits\"\n        local mapFiles=`$perfcmd buildid-list --with-hits | grep /tmp/perf- | cut -d ' ' -f 2`\n        for mapFile in $mapFiles\n        do\n            if [ -f $mapFile ]\n            then\n                LogAppend \"Saving $mapFile\"\n\n                # Change permissions on the file before saving, as perf will need to access the file later\n                # in this script when running perf script.\n                RunSilent \"chown root $mapFile\"\n                RunSilent \"cp $mapFile .\"\n\n                local perfinfoFile=${mapFile/perf/perfinfo}\n\n                LogAppend \"Attempting to find ${perfinfoFile}\"\n\n                if [ -f $perfinfoFile ]\n                then\n                    LogAppend \"Saving $perfinfoFile\"\n                    RunSilent \"chown root $perfinfoFile\"\n                    RunSilent \"cp $perfinfoFile .\"\n                else\n                    LogAppend \"Skipping ${perfinfoFile}.\"\n                fi\n            else\n                LogAppend \"Skipping $mapFile.  Some managed symbols may not be resolvable, but trace is still valid.\"\n            fi\n\n            # Also check for jit-<pid>.dump files.\n            # Convert to jit dump file name.\n            local pid=`echo $mapFile | awk -F\"-\" '{print $NF}' | awk -F\".\" '{print $1}'`\n            local path=`echo $mapFile | awk -F\"/\" '{OFS=\"/\";NF--;print $0;}'`\n            local jitDumpFile=\"$path/jit-$pid.dump\"\n\n            if [ -f $jitDumpFile ]\n            then\n                LogAppend \"Saving $jitDumpFile\"\n                RunSilent \"cp $jitDumpFile .\"\n                writeCrossgenWarning=0\n            fi\n        done\n\n        WriteStatus \"Generating native image symbol files\"\n\n        # Get the list of loaded images and use the path to libcoreclr.so to find crossgen.\n        # crossgen is expected to sit next to libcoreclr.so.\n        local buildidList=`$perfcmd buildid-list | grep libcoreclr.so | cut -d ' ' -f 2`\n        local crossgenCmd=''\n        local crossgenDir=''\n        for file in $buildidList\n        do\n            crossgenDir=`dirname \"${file}\"`\n            if [ -f ${crossgenDir}/crossgen ]\n            then\n                crossgenCmd=${crossgenDir}/crossgen\n                LogAppend \"Found crossgen at ${crossgenCmd}\"\n                break\n            fi\n        done\n\n        OLDIFS=$IFS\n\n        imagePaths=\"\"\n\n        if [ \"$crossgenCmd\" != \"\" ]\n        then\n                local perfinfos=`ls . | grep perfinfo | cut -d ' ' -f 2`\n                for perfinfo in $perfinfos\n                do\n                    if [ -f $perfinfo ]\n                    then\n                        IFS=\";\"\n                        while read command dll guid; do\n                            if [ $command ]; then\n                                if [ $command = \"ImageLoad\" ]; then\n                                    if [ -f $dll ]; then\n                                        imagePaths=\"${dll}:${imagePaths}\"\n                                    fi\n                                fi\n                            fi\n                        done < $perfinfo\n                        IFS=$OLDIFS\n                    fi\n                done\n\n                IFS=\":\"\n                LogAppend \"Generating PerfMaps for native images\"\n                for path in $imagePaths\n                do\n                    if [ `echo ${path} | grep ^.*\\.dll$` ]\n                    then\n                        IFS=\"\"\n                        LogAppend \"Generating PerfMap for ${path}\"\n                        LogAppend \"Running ${crossgenCmd} /r $imagePaths /CreatePerfMap . ${path}\"\n                        ${crossgenCmd} /r $imagePaths /CreatePerfMap . ${path} >> $logFile 2>&1\n                        IFS=\":\"\n                    else\n                        LogAppend \"Skipping ${path}\"\n                    fi\n                done\n        else\n        if [ \"$buildidList\" != \"\" ] && [ $writeCrossgenWarning -eq 1 ]\n        then\n            LogAppend \"crossgen not found, skipping native image map generation.\"\n            WriteStatus \"...SKIPPED\"\n            WriteWarning \"Crossgen not found.  Framework symbols will be unavailable.\"\n            WriteWarning \"See https://github.com/dotnet/coreclr/blob/master/Documentation/project-docs/linux-performance-tracing.md#resolving-framework-symbols for details.\"\n        fi\n        fi\n\n        IFS=$OLDIFS\n\n        WriteStatus \"...FINISHED\"\n\n        if [ \"$objdumpcmd\" != \"\" ]\n        then\n            # Create debuginfo files (separate symbols) for all modules in the trace.\n            WriteStatus \"Saving native symbols\"\n\n            # Get the list of DSOs with hits in the trace file (those that are actually used).\n            # Filter out /tmp/perf-$pid.map files and files that end in .dll.\n            local dsosWithHits=`$perfcmd buildid-list --with-hits | grep -v /tmp/perf- | grep -v .dll$`\n            for dso in $dsosWithHits\n            do\n                # Build up tuples of buildid and binary path.\n                local processEntry=0\n                if [ -f $dso ]\n                then\n                    local pathToBinary=$dso\n                    processEntry=1\n                else\n                    local buildid=$dso\n                    pathToBinary=''\n                fi\n\n                # Once we have a tuple for a binary path that exists, process it.\n                if [ \"$processEntry\" == \"1\" ]\n                then\n                    # Get the binary name without path.\n                    local binaryName=`basename $pathToBinary`\n\n                    # Build the debuginfo file name.\n                    local destFileName=$binaryName.debuginfo\n\n                    # Build the destination directory for the debuginfo file.\n                    local currentDir=`pwd`\n                    local destDir=$currentDir/debuginfo/$buildid\n\n                    # Build the full path to the debuginfo file.\n                    local destPath=$destDir/$destFileName\n\n                    # Check to see if the DSO contains symbols, and if so, build the debuginfo file.\n                    local noSymbols=`$objdumpcmd -t $pathToBinary | grep \"no symbols\" -c`\n                    if [ \"$noSymbols\" == \"0\" ]\n                    then\n                        LogAppend \"Generating debuginfo for $binaryName with buildid=$buildid\"\n                        RunSilent \"mkdir -p $destDir\"\n                        RunSilent \"objcopy --only-keep-debug $pathToBinary $destPath\"\n                    else\n                        LogAppend \"Skipping $binaryName with buildid=$buildid.  No symbol information.\"\n                    fi\n                fi\n            done\n\n            WriteStatus \"...FINISHED\"\n        fi\n\n        WriteStatus \"Resolving JIT and R2R symbols\"\n\n        originalFile=\"perf.data\"\n        inputFile=\"perf-jit.data\"\n        RunSilent $perfcmd inject --input $originalFile --jit --output $inputFile\n\n        WriteStatus \"...FINISHED\"\n\n        WriteStatus \"Exporting perf.data file\"\n\n        outputDumpFile=\"perf.data.txt\"\n\n        # I've not found a good way to get the behavior that we want here - running the command and redirecting the output\n        # when passing the command line to a function.  Thus, this case is hardcoded.\n\n        # There is a breaking change where the capitalization of the -f parameter changed.\n        LogAppend \"Running $perfcmd script -i $inputFile -F comm,pid,tid,cpu,time,period,event,ip,sym,dso,trace > $outputDumpFile\"\n        $perfcmd script -i $inputFile -F comm,pid,tid,cpu,time,period,event,ip,sym,dso,trace > $outputDumpFile 2>>$logFile\n        LogAppend\n\n        if [ $? -ne 0 ]\n        then\n            LogAppend \"Running $perfcmd script -i $inputFile -f comm,pid,tid,cpu,time,period,event,ip,sym,dso,trace > $outputDumpFile\"\n            $perfcmd script -i $inputFile -f comm,pid,tid,cpu,time,period,event,ip,sym,dso,trace > $outputDumpFile 2>>$logFile\n            LogAppend\n        fi\n\n        # If the dump file is zero length, try to collect without the period field, which was added recently.\n        if [ ! -s $outputDumpFile ]\n        then\n            LogAppend \"Running $perfcmd script -i $inputFile -f comm,pid,tid,cpu,time,event,ip,sym,dso,trace > $outputDumpFile\"\n            $perfcmd script -i $inputFile -f comm,pid,tid,cpu,time,event,ip,sym,dso,trace > $outputDumpFile 2>>$logFile\n            LogAppend\n        fi\n\n        WriteStatus \"...FINISHED\"\n    fi\n\n    WriteStatus \"Compressing trace files\"\n    \n    # Move all collected files to the new directory.\n    RunSilent \"mv -f * $directoryName\"\n\n    # Close the log - this stops all writing to the log, so that we can move it into the archive.\n    CloseLog\n\n    # Move the log file to the new directory and rename it to the standard log name.\n    RunSilent \"mv $logFile $directoryName/perfcollect.log\"\n\n    # Compress the data.\n    local archiveSuffix=\".zip\"\n    local archiveName=$directoryName$archiveSuffix\n    RunSilent \"$zipcmd -r $archiveName $directoryName\"\n\n    # Move back to the original directory.\n    popd > /dev/null\n\n    # Move the archive.\n    RunSilent \"mv $tempDir/$archiveName .\"\n\n    WriteStatus \"...FINISHED\"\n\n    WriteStatus \"Cleaning up artifacts\"\n\n    # Delete the temp directory.\n    RunSilent \"rm -rf $tempDir $collectInfoFile\"\n\n    WriteStatus \"...FINISHED\"\n\n    # Tell the user where the trace is.\n    WriteStatus\n    WriteStatus \"Trace saved to $archiveName\"\n}\n\n##\n# Handle the CTRL+C signal.\n##\nCTRLC_Handler()\n{\n    # Mark the handler invoked.\n    handlerInvoked=1\n}\n\nEndCollect()\n{\n    # The user must either use \"collect stop\" or CTRL+C to stop collection.\n    if [ \"$action\" == \"stop\" ]\n    then \n        # Recover trace info in the previous program.\n        source $collectInfoFile  # TODO: exit and dispose upon missing file\n        # New program started, so go back to the temp directory.\n        pushd $tempDir > /dev/null\n    fi\n\n    if [ \"$useLTTng\" == \"1\" ]\n    then\n        StopLTTngCollection\n    fi\n\n    # Update the user.\n    WriteStatus\n    WriteStatus \"...STOPPED.\"\n    WriteStatus\n    WriteStatus \"Starting post-processing.  This may take some time.\"\n    WriteStatus\n\n    # The user used CTRL+C to stop collection.\n    # When this happens, we catch the signal and finish our work.\n    ProcessCollectedData\n}\n\n##\n# Print usage information.\n##\nPrintUsage()\n{\n    echo \"This script uses perf_event and LTTng to collect and view performance traces for .NET applications.\"\n    echo \"For detailed collection and viewing steps, view this script in a text editor or viewer.\"\n    echo \"\"\n    echo \"./perfcollect <action> <tracename>\"\n    echo \"Valid Actions: collect start/stop view livetrace install\"\n    echo \"\"\n    echo \"collect options:\"\n    echo \"By default, collection includes CPU samples collected every ms.\"\n    echo \"    -pid          : Only collect data from the specified process id.\"\n    echo \"    -threadtime   : Collect events for thread time analysis (on and off cpu).\"\n    echo \"    -offcpu       : Collect events for off-cpu analysis.\"\n    echo \"    -hwevents     : Collect (some) hardware counters.\"\n    echo \"\"\n    echo \"start:\"\n    echo \"    Start collection, but with Lttng trace ONLY. It needs to be used with 'stop' action.\"\n    echo \"\"\n    echo \"stop:\"\n    echo \"    Stop collection if 'start' action is used.\"\n    echo \"\"\n    echo \"view options:\"\n    echo \"    -processfilter      : Filter data by the specified process name.\"\n    echo \"    -graphtype      : Specify the type of graph.  Valid values are 'caller' and 'callee'.  Default is 'callee'.\"\n    echo \"    -viewer          : Specify the data viewer.  Valid values are 'perf' and 'lttng'.  Default is 'perf'.\"\n    echo \"\"\n    echo \"livetrace:\"\n    echo \"    Print EventSource events directly to the console.  Root privileges not required.\"\n    echo \"\"\n    echo \"install options:\"\n    echo \"    Useful for first-time setup.  Installs/upgrades perf_event and LTTng.\"\n    echo \"    -force    : Force installation of required packages without prompt\"\n    echo \"\"\n}\n\n##\n# Validate and set arguments.\n##\n\nBuildPerfRecordArgs()\n{\n    # Start with default collection arguments that record at realtime priority, all CPUs (-a), and collect call stacks (-g)\n    collectionArgs=\"record -k 1 -g\"\n\n    # Filter to a single process if desired\n    if [ \"$collectionPid\" != \"\" ]\n    then\n        collectionArgs=\"$collectionArgs --pid=$collectionPid\"\n    else\n        collectionArgs=\"$collectionArgs -a\"\n    fi\n\n    # Enable CPU Collection\n    if [ $collect_cpu -eq 1 ]\n    then\n        collectionArgs=\"$collectionArgs\"\n        eventsToCollect=( \"${eventsToCollect[@]}\" \"cpu-clock\" )\n\n        # If only collecting CPU events, set the sampling rate to 1000.\n        # Otherwise, use the default sampling rate to avoid sampling sched events.\n        if [ $collect_threadTime -eq 0 ] && [ $collect_offcpu -eq 0 ]\n        then\n            collectionArgs=\"$collectionArgs -F 1000\"\n        fi\n    fi\n\n    # Enable HW counters event collection\n    if [ $collect_HWevents -eq 1 ]\n    then\n        collectionArgs=\"$collectionArgs -e cycles,instructions,branches,cache-misses\"\n    fi\n    \n    # Enable context switches.\n    if [ $collect_threadTime -eq 1 ]\n    then\n        eventsToCollect=( \"${eventsToCollect[@]}\" \"sched:sched_stat_sleep\" \"sched:sched_switch\" \"sched:sched_process_exit\" )\n    fi\n\n    # Enable offcpu collection\n    if [ $collect_offcpu -eq 1 ]\n    then\n        eventsToCollect=( \"${eventsToCollect[@]}\" \"sched:sched_stat_sleep\" \"sched:sched_switch\" \"sched:sched_process_exit\" )\n    fi\n\n    # Build up the set of events.\n    local eventString=\"\"\n    local comma=\",\"\n    for (( i=0; i<${#eventsToCollect[@]}; i++ ))\n    do\n        # Get the arg.\n        eventName=${eventsToCollect[$i]}\n\n        # Build up the comma separated list.\n        if [ \"$eventString\" == \"\" ]\n        then\n            eventString=$eventName\n        else\n            eventString=\"$eventString$comma$eventName\"\n        fi\n\n    done\n\n    if [ ! -z ${duration} ]\n    then\n        durationString=\"sleep ${duration}\"\n    fi\n\n    # Add the events onto the collection command line args.    \n    collectionArgs=\"$collectionArgs -e $eventString $durationString\"\n}\n\nDoCollect()\n{\n    # Ensure the script is run as root.\n    EnsureRoot\n\n    # Build collection args.\n    # Places the resulting args in $collectionArgs\n    BuildPerfRecordArgs\n\n    # Trap CTRL+C\n    trap CTRLC_Handler SIGINT\n\n    # Create a temp directory to use for collection.\n    local tempDir=`mktemp -d`\n    LogAppend \"Created temp directory $tempDir\"\n\n    # Switch to the directory.\n    pushd $tempDir > /dev/null\n\n    # Start LTTng collection.\n    if [ \"$useLTTng\" == \"1\" ]\n    then\n        StartLTTngCollection\n    fi\n\n    # Tell the user that collection has started and how to exit.\n    if [ \"$duration\" != \"\" ]\n    then\n        WriteStatus \"Collection started. Collection will automatically stop in $duration second(s).  Press CTRL+C to stop early.\"\n    elif [ \"$action\" == \"start\" ]\n    then\n        WriteStatus \"Collection started.\"\n    else\n        WriteStatus \"Collection started. Press CTRL+C to stop.\"\n    fi\n\n    # Start perf record.\n    if [ \"$action\" == \"start\" ]\n    then \n        # Skip perf, which can only be stopped by CTRL+C.\n        # Pass trace directory and session name to the stop process.\n        popd > /dev/null\n        usePerf=0\n        declare -p | grep -e lttngTraceDir -e lttngSessionName -e tempDir -e usePerf -e useLttng -e logFile > $collectInfoFile\n    else\n        if [ \"$usePerf\" == \"1\" ]\n        then\n            if [ ! -z ${duration} ]\n            then\n                RunSilent $perfcmd $collectionArgs\n            else\n                RunSilentBackground $perfcmd $collectionArgs\n            fi\n        else\n            # Wait here until CTRL+C handler gets called when user types CTRL+C.\n            LogAppend \"Waiting for CTRL+C handler to get called.\"\n\n            waitTime=0\n            for (( ; ; ))\n            do\n                if [ \"$handlerInvoked\" == \"1\" ]\n                then\n                    break;\n                fi\n\n                # Wait and then check to see if the handler has been invoked or we've crossed the duration threshold.\n                sleep 1\n                waitTime=$waitTime+1\n                if (( duration > 0 && duration <= waitTime ))\n                then\n                    break;\n                fi\n            done\n        fi\n        # End collection if action is 'collect'.\n        EndCollect\n    fi\n}\n\nDoLiveTrace()\n{\n    # Start the session\n    StartLTTngCollection\n\n    # View the event stream (until the user hits CTRL+C)\n    WriteStatus \"Listening for events from LTTng.  Hit CTRL+C to stop.\"\n    $lttngcmd view\n\n    # Stop the LTTng sessoin\n    StopLTTngCollection\n}\n\n# $1 == Path to directory containing trace files\nPropSymbolsAndMapFilesForView()\n{\n    # Get the current directory\n    local currentDir=`pwd`    \n\n    # Copy map files to /tmp since they aren't supported by perf buildid-cache.\n    local mapFiles=`find -name *.map`\n    for mapFile in $mapFiles\n    do\n        echo \"Copying $mapFile to /tmp.\"\n        cp $mapFile /tmp\n    done\n\n    # Cache all debuginfo files saved with the trace in the buildid cache.\n    local debugInfoFiles=`find $currentDir -name *.debuginfo`\n    for debugInfoFile in $debugInfoFiles\n    do\n        echo \"Caching $debugInfoFile in buildid cache using perf buildid-cache.\"\n        $perfcmd buildid-cache --add=$debugInfoFile\n    done\n}\n\nDoView()\n{\n    # Generate a temp directory to extract the trace files into.\n    local tempDir=`mktemp -d`\n    \n    # Extract the trace files.\n    $unzipcmd $inputTraceName -d $tempDir\n    \n    # Move the to temp directory.\n    pushd $tempDir\n    cd `ls`\n\n    # Select the viewer.\n    if [ \"$viewer\" == \"perf\" ]\n    then\n        # Prop symbols and map files.\n        PropSymbolsAndMapFilesForView `pwd`\n\n        # Choose the view\n        if [ \"$graphType\" == \"\" ]\n        then\n            graphType=\"callee\"\n        elif [ \"$graphType\" != \"callee\" ] && [ \"$graphType\" != \"caller\"]\n        then\n            FatalError \"Invalid graph type specified.  Valid values are 'callee' and 'caller'.\"\n        fi\n\n        # Filter to specific process names if desired.\n        if [ \"$processFilter\" != \"\" ]\n        then\n            processFilter=\"--comms=$processFilter\"\n        fi\n\n        # Execute the viewer.\n        $perfcmd report -n -g graph,0.5,$graphType $processFilter $perfOpt\n    elif [ \"$viewer\" == \"lttng\" ]\n    then\n        babeltrace lttngTrace/ | more\n    fi\n    \n    # Switch back to the original directory.\n    popd\n\n    # Delete the temp directory.\n    rm -rf $tempDir\n}\n\n#####################################\n## Main Script Start\n#####################################\n\n# No arguments\nif [ \"$#\" == \"0\" ]\nthen\n    PrintUsage\n    exit 0\nfi\n\n# Install perf if requested.  Do this before all other validation.\nif [ \"$1\" == \"install\" ]\nthen\n    if [ \"$2\" == \"-force\" ]\n    then \n        forceInstall=1\n    fi\n    InstallPerf\n    InstallLTTng\n    exit 0\nfi\n\n# Discover external commands that will be called by this script.\nDiscoverCommands\n\n# Initialize the log.\nif [ \"$1\" != \"stop\" ]\nthen\n    InitializeLog\nfi\n\n# Process arguments.\nProcessArguments $@\n\n# Ensure prerequisites are installed.\nEnsurePrereqsInstalled\n\n# Take the appropriate action.\nif [ \"$action\" == \"collect\" ] || [ \"$action\" == \"start\" ]\nthen\n    DoCollect\nelif [ \"$action\" == \"stop\" ]\nthen\n    EndCollect\nelif [ \"$action\" == \"view\" ]\nthen\n    DoView\nelif [ \"$action\" == \"livetrace\" ]\nthen\n    DoLiveTrace\nfi"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/AppConfigGenerator.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.IO;\nusing System.Xml;\nusing BenchmarkDotNet.Characteristics;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Jobs;\n\nnamespace BenchmarkDotNet.Toolchains\n{\n    internal static class AppConfigGenerator\n    {\n        private static readonly HashSet<string> JobRuntimeSettings =\n        [\n            \"useLegacyJit\",\n            \"gcConcurrent\",\n            \"gcServer\",\n            \"GCCpuGroup\",\n            \"gcAllowVeryLargeObjects\",\n            \"GCHeapCount\",\n            \"GCNoAffinitize\",\n            \"GCHeapAffinitizeMask\"\n        ];\n\n        internal static void Generate(Job job, TextReader source, TextWriter destination, IResolver resolver)\n        {\n            var xmlDocument = new XmlDocument();\n\n            XmlNode configurationElement;\n\n            if (source == TextReader.Null)\n            {\n                // Create a new configuration node.\n                configurationElement = xmlDocument.CreateNode(XmlNodeType.Element, \"configuration\", string.Empty);\n                xmlDocument.AppendChild(configurationElement);\n            }\n            else\n            {\n                // Try to get configuration node from specified TextReader.\n                using var xmlReader = XmlReader.Create(source);\n                configurationElement = GetOrCreateConfigurationElement(xmlDocument, xmlReader);\n            }\n\n            var runtimeElement = GetOrCreateRuntimeElement(xmlDocument, configurationElement);\n\n            ClearStartupSettingsForCustomClr(configurationElement, job.Environment.Runtime);\n            ClearAllRuntimeSettingsThatCanBeSetOnlyByJobConfiguration(runtimeElement);\n\n            GenerateJitSettings(xmlDocument, runtimeElement, job.Environment);\n            GenerateGCSettings(xmlDocument, runtimeElement, job.Environment.Gc, resolver);\n\n            xmlDocument.Save(destination);\n        }\n\n        private static XmlNode GetOrCreateConfigurationElement(XmlDocument xmlDocument, XmlReader xmlReader)\n        {\n            try\n            {\n                xmlDocument.Load(xmlReader);\n                var configurationNode = xmlDocument.SelectSingleNode(\"/configuration\");\n                if (configurationNode != null)\n                    return configurationNode;\n            }\n            catch (XmlException)\n            {\n                // Failed to load XML content.\n            }\n\n            // If the XML is invalid or configuration node is not exists. Create a new configuration element\n            return xmlDocument.AppendChild(xmlDocument.CreateNode(XmlNodeType.Element, \"configuration\", string.Empty))!;\n        }\n\n        private static XmlNode GetOrCreateRuntimeElement(XmlDocument xmlDocument, XmlNode configurationElement)\n        {\n            return configurationElement.SelectSingleNode(\"runtime\")\n                   ?? configurationElement.AppendChild(xmlDocument.CreateNode(XmlNodeType.Element, \"runtime\", string.Empty))!;\n        }\n\n        private static void ClearAllRuntimeSettingsThatCanBeSetOnlyByJobConfiguration(XmlNode runtimeElement)\n        {\n            foreach (XmlNode runtimeSetting in runtimeElement.ChildNodes)\n            {\n                if (JobRuntimeSettings.Contains(runtimeSetting.Name))\n                {\n                    runtimeElement.RemoveChild(runtimeSetting);\n                }\n            }\n        }\n\n        private static void ClearStartupSettingsForCustomClr(XmlNode configurationElement, Runtime? runtime)\n        {\n            if (!(runtime is ClrRuntime clrRuntime) || clrRuntime.Version.IsBlank())\n                return;\n\n            foreach (XmlNode configurationChild in configurationElement.ChildNodes)\n            {\n                if (configurationChild.Name == \"startup\")\n                {\n                    configurationElement.RemoveChild(configurationChild);\n                }\n            }\n        }\n\n        private static void GenerateJitSettings(XmlDocument xmlDocument, XmlNode runtimeElement, EnvironmentMode environmentMode)\n        {\n            if (environmentMode.HasValue(EnvironmentMode.JitCharacteristic))\n            {\n                string useLegacyJit = environmentMode.Jit.ToConfig();\n                CreateNodeWithAttribute(xmlDocument, runtimeElement, \"useLegacyJit\", \"enabled\", useLegacyJit);\n            }\n        }\n\n        private static void GenerateGCSettings(XmlDocument xmlDocument, XmlNode runtimeElement, GcMode gcMode, IResolver resolver)\n        {\n            CreateNodeWithAttribute(xmlDocument, runtimeElement, \"gcConcurrent\", \"enabled\", gcMode.ResolveValue(GcMode.ConcurrentCharacteristic, resolver).ToLowerCase());\n            CreateNodeWithAttribute(xmlDocument, runtimeElement, \"gcServer\", \"enabled\", gcMode.ResolveValue(GcMode.ServerCharacteristic, resolver).ToLowerCase());\n\n            if (gcMode.HasValue(GcMode.CpuGroupsCharacteristic))\n                CreateNodeWithAttribute(xmlDocument, runtimeElement, \"GCCpuGroup\", \"enabled\", gcMode.ResolveValue(GcMode.CpuGroupsCharacteristic, resolver).ToLowerCase());\n            if (gcMode.HasValue(GcMode.AllowVeryLargeObjectsCharacteristic))\n                CreateNodeWithAttribute(xmlDocument, runtimeElement, \"gcAllowVeryLargeObjects\", \"enabled\", gcMode.ResolveValue(GcMode.AllowVeryLargeObjectsCharacteristic, resolver).ToLowerCase());\n            if (gcMode.HasValue(GcMode.NoAffinitizeCharacteristic))\n                CreateNodeWithAttribute(xmlDocument, runtimeElement, \"GCNoAffinitize\", \"enabled\", gcMode.ResolveValue(GcMode.NoAffinitizeCharacteristic, resolver).ToLowerCase());\n            if (gcMode.HasValue(GcMode.HeapAffinitizeMaskCharacteristic))\n                CreateNodeWithAttribute(xmlDocument, runtimeElement, \"GCHeapAffinitizeMask\", \"enabled\", gcMode.ResolveValue(GcMode.HeapAffinitizeMaskCharacteristic, resolver).ToString());\n            if (gcMode.HasValue(GcMode.HeapCountCharacteristic))\n                CreateNodeWithAttribute(xmlDocument, runtimeElement, \"GCHeapCount\", \"enabled\", gcMode.ResolveValue(GcMode.HeapCountCharacteristic, resolver).ToString());\n        }\n\n        private static void CreateNodeWithAttribute(\n            XmlDocument document,\n            XmlNode parentNode,\n            string nodeName,\n            string attributeName,\n            string attributeValue)\n        {\n            Debug.Assert(JobRuntimeSettings.Contains(nodeName), \"Please add the new setting to the JobRuntimeSettings list\");\n\n            var node = document.CreateNode(XmlNodeType.Element, nodeName, string.Empty);\n            var attribute = document.CreateAttribute(attributeName);\n            attribute.Value = attributeValue;\n            if (node.Attributes == null)\n                throw new NullReferenceException(nameof(node.Attributes));\n            node.Attributes.SetNamedItem(attribute);\n\n            parentNode.AppendChild(node);\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/ArtifactsPaths.cs",
    "content": "using BenchmarkDotNet.Extensions;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Toolchains\n{\n    public class ArtifactsPaths\n    {\n        public static readonly ArtifactsPaths Empty = new(\"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\");\n\n        [PublicAPI] public string RootArtifactsFolderPath { get; }\n        [PublicAPI] public string BuildArtifactsDirectoryPath { get; }\n        [PublicAPI] public string BinariesDirectoryPath { get; }\n        [PublicAPI] public string PublishDirectoryPath { get; }\n        [PublicAPI] public string ProgramCodePath { get; }\n        [PublicAPI] public string AppConfigPath { get; }\n        [PublicAPI] public string NuGetConfigPath { get; }\n        [PublicAPI] public string ProjectFilePath { get; }\n        [PublicAPI] public string BuildScriptFilePath { get; }\n        [PublicAPI] public string ExecutablePath { get; }\n        [PublicAPI] public string ProgramName { get; }\n        [PublicAPI] public string PackagesDirectoryName { get; }\n\n        public ArtifactsPaths(\n            string rootArtifactsFolderPath,\n            string buildArtifactsDirectoryPath,\n            string binariesDirectoryPath,\n            string publishDirectoryPath,\n            string programCodePath,\n            string appConfigPath,\n            string nuGetConfigPath,\n            string projectFilePath,\n            string buildScriptFilePath,\n            string executablePath,\n            string programName,\n            string packagesDirectoryName)\n        {\n            RootArtifactsFolderPath = rootArtifactsFolderPath;\n            BuildArtifactsDirectoryPath = buildArtifactsDirectoryPath;\n            BinariesDirectoryPath = binariesDirectoryPath;\n            PublishDirectoryPath = publishDirectoryPath.EnsureNotNull();\n            ProgramCodePath = programCodePath.EnsureNotNull();\n            AppConfigPath = appConfigPath.EnsureNotNull();\n            NuGetConfigPath = nuGetConfigPath.EnsureNotNull();\n            ProjectFilePath = projectFilePath.EnsureNotNull();\n            BuildScriptFilePath = buildScriptFilePath.EnsureNotNull();\n            ExecutablePath = executablePath;\n            ProgramName = programName;\n            PackagesDirectoryName = packagesDirectoryName.EnsureNotNull();\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/CoreRun/CoreRunGenerator.cs",
    "content": "﻿using System.IO;\nusing System.Linq;\nusing BenchmarkDotNet.Toolchains.CsProj;\n\nnamespace BenchmarkDotNet.Toolchains.CoreRun\n{\n    public class CoreRunGenerator : CsProjGenerator\n    {\n        public CoreRunGenerator(FileInfo sourceCoreRun, FileInfo copyCoreRun, string targetFrameworkMoniker, string cliPath, string packagesPath)\n            : base(targetFrameworkMoniker, cliPath, packagesPath)\n        {\n            SourceCoreRun = sourceCoreRun;\n            CopyCoreRun = copyCoreRun;\n        }\n\n        private FileInfo SourceCoreRun { get; }\n\n        private FileInfo CopyCoreRun { get; }\n\n        private bool NeedsCopy => SourceCoreRun != CopyCoreRun;\n\n        protected override string GetPackagesDirectoryPath(string buildArtifactsDirectoryPath) => PackagesPath;\n\n        protected override string GetBinariesDirectoryPath(string buildArtifactsDirectoryPath, string configuration)\n            => Path.Combine(buildArtifactsDirectoryPath, \"bin\", configuration, TargetFrameworkMoniker, \"publish\");\n\n        protected override void CopyAllRequiredFiles(ArtifactsPaths artifactsPaths)\n        {\n            if (NeedsCopy)\n                CopyFilesRecursively(SourceCoreRun.Directory!, CopyCoreRun.Directory!);\n\n            base.CopyAllRequiredFiles(artifactsPaths);\n        }\n\n        protected override string[] GetArtifactsToCleanup(ArtifactsPaths artifactsPaths)\n            => NeedsCopy\n                ? base.GetArtifactsToCleanup(artifactsPaths).Concat([CopyCoreRun.Directory!.FullName]).ToArray()\n                : base.GetArtifactsToCleanup(artifactsPaths);\n\n        // source: https://stackoverflow.com/a/58779/5852046\n        private static void CopyFilesRecursively(DirectoryInfo source, DirectoryInfo target)\n        {\n            if (!target.Exists)\n                target.Create();\n\n            foreach (DirectoryInfo dir in source.GetDirectories())\n                CopyFilesRecursively(dir, target.CreateSubdirectory(dir.Name));\n\n            foreach (FileInfo file in source.GetFiles())\n                file.CopyTo(Path.Combine(target.FullName, file.Name), overwrite: true);\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/CoreRun/CoreRunPublisher.cs",
    "content": "﻿using System;\nusing System.Diagnostics;\nusing System.IO;\nusing System.Linq;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Toolchains.DotNetCli;\nusing BenchmarkDotNet.Toolchains.Results;\n\nnamespace BenchmarkDotNet.Toolchains.CoreRun\n{\n    public class CoreRunPublisher(string tfm, FileInfo coreRun, FileInfo? customDotNetCliPath = null) : DotNetCliPublisher(tfm, customDotNetCliPath?.FullName ?? \"\")\n    {\n        public override BuildResult Build(GenerateResult generateResult, BuildPartition buildPartition, ILogger logger)\n        {\n            var buildResult = base.Build(generateResult, buildPartition, logger);\n\n            if (buildResult.IsBuildSuccess)\n                UpdateDuplicatedDependencies(buildResult.ArtifactsPaths, logger);\n\n            return buildResult;\n        }\n\n        /// <summary>\n        /// update CoreRun folder with newer versions of duplicated dependencies\n        /// </summary>\n        private void UpdateDuplicatedDependencies(ArtifactsPaths artifactsPaths, ILogger logger)\n        {\n            var publishedDirectory = new DirectoryInfo(artifactsPaths.BinariesDirectoryPath);\n            var coreRunDirectory =  coreRun.Directory!;\n\n            foreach (var publishedDependency in publishedDirectory\n                .EnumerateFileSystemInfos()\n                .Where(file => file.Extension == \".dll\" || file.Extension == \".exe\" ))\n            {\n                var coreRunDependency = new FileInfo(Path.Combine(coreRunDirectory.FullName, publishedDependency.Name));\n\n                if (!coreRunDependency.Exists)\n                    continue; // the file does not exist in CoreRun directory, we don't need to worry, it will be just loaded from publish directory by CoreRun\n\n                var publishedVersionInfo = FileVersionInfo.GetVersionInfo(publishedDependency.FullName);\n                var coreRunVersionInfo = FileVersionInfo.GetVersionInfo(coreRunDependency.FullName);\n\n                if (!Version.TryParse(publishedVersionInfo.FileVersion, out var publishedVersion) || !Version.TryParse(coreRunVersionInfo.FileVersion, out var coreRunVersion))\n                    continue;\n\n                if (publishedVersion > coreRunVersion)\n                {\n                    File.Copy(publishedDependency.FullName, coreRunDependency.FullName, overwrite: true); // we need to overwrite old things with their newer versions\n\n                    logger.WriteLineInfo($\"Copying {publishedDependency.FullName} to {coreRunDependency.FullName}\");\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/CoreRun/CoreRunToolchain.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing BenchmarkDotNet.Characteristics;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Toolchains.DotNetCli;\nusing BenchmarkDotNet.Validators;\n\nnamespace BenchmarkDotNet.Toolchains.CoreRun\n{\n    public class CoreRunToolchain : IToolchain\n    {\n        /// <summary>\n        /// creates a CoreRunToolchain which is using provided CoreRun to execute .NET Core apps\n        /// </summary>\n        /// <param name=\"coreRun\">the path to CoreRun</param>\n        /// /<param name=\"createCopy\">should a copy of CoreRun be performed? True by default. <remarks>The toolchain replaces old dependencies in CoreRun folder with newer versions if used by the benchmarks.</remarks></param>\n        /// <param name=\"targetFrameworkMoniker\">TFM, net8.0 is the default</param>\n        /// <param name=\"customDotNetCliPath\">path to dotnet cli, if not provided the one from PATH will be used</param>\n        /// <param name=\"displayName\">display name, CoreRun is the default value</param>\n        /// <param name=\"restorePath\">the directory to restore packages to</param>\n        public CoreRunToolchain(FileInfo coreRun, bool createCopy = true,\n            string targetFrameworkMoniker = \"net8.0\",\n            FileInfo? customDotNetCliPath = null,\n            DirectoryInfo? restorePath = null,\n            string displayName = \"CoreRun\")\n        {\n            if (!coreRun.Exists)\n                throw new FileNotFoundException(\"Provided CoreRun path does not exist. Please remember that BDN expects path to CoreRun.exe (corerun on Unix), not to Core_Root folder.\");\n\n            SourceCoreRun = coreRun;\n            CopyCoreRun = createCopy ? GetShadowCopyPath(coreRun) : coreRun;\n            CustomDotNetCliPath = customDotNetCliPath;\n            RestorePath = restorePath;\n\n            Name = displayName;\n            Generator = new CoreRunGenerator(SourceCoreRun, CopyCoreRun, targetFrameworkMoniker, customDotNetCliPath?.FullName ?? \"\", restorePath?.FullName ?? \"\");\n            Builder = new CoreRunPublisher(targetFrameworkMoniker, CopyCoreRun, customDotNetCliPath);\n            Executor = new DotNetCliExecutor(customDotNetCliPath: CopyCoreRun.FullName); // instead of executing \"dotnet $pathToDll\" we do \"CoreRun $pathToDll\"\n        }\n\n        public string Name { get; }\n\n        public IGenerator Generator { get; }\n\n        public IBuilder Builder { get; }\n\n        public IExecutor Executor { get; }\n\n        public bool IsInProcess => false;\n\n        public FileInfo SourceCoreRun { get; }\n\n        public FileInfo CopyCoreRun { get; }\n\n        public FileInfo? CustomDotNetCliPath { get; }\n\n        public DirectoryInfo? RestorePath { get; }\n\n        public override string ToString() => Name;\n\n        public IEnumerable<ValidationError> Validate(BenchmarkCase benchmark, IResolver resolver)\n        {\n            if (!SourceCoreRun.Exists)\n            {\n                yield return new ValidationError(true,\n                    $\"Provided CoreRun path does not exist, benchmark '{benchmark.DisplayInfo}' will not be executed. Please remember that BDN expects path to CoreRun.exe (corerun on Unix), not to Core_Root folder.\",\n                    benchmark);\n            }\n            else if (DotNetSdkValidator.IsCliPathInvalid(CustomDotNetCliPath?.FullName, benchmark, out var invalidCliError))\n            {\n                yield return invalidCliError;\n            }\n        }\n\n        private static FileInfo GetShadowCopyPath(FileInfo coreRunPath)\n        {\n            string randomSubfolderName = Guid.NewGuid().ToString();\n\n            FileInfo coreRunCopy = coreRunPath.Directory!.Parent != null\n                ? new FileInfo(Path.Combine(coreRunPath.Directory.Parent.FullName, randomSubfolderName, coreRunPath.Name))\n                : new FileInfo(Path.Combine(coreRunPath.Directory.FullName, randomSubfolderName, coreRunPath.Name)); // C:\\CoreRun.exe case\n\n            if (!TryToCreateSubfolder(coreRunCopy.Directory!))\n            {\n                // we are most likely missing permissions to write to given folder (it can be readonly etc)\n                // in such case, CoreRun copy is going to be stored in TEMP\n                coreRunCopy = new FileInfo(Path.Combine(Path.GetTempPath(), randomSubfolderName, coreRunPath.Name));\n\n                if (!TryToCreateSubfolder(coreRunCopy.Directory!))\n                {\n                    // if even that is impossible, we return the original path and nothing is going to be copied\n                    return coreRunPath;\n                }\n            }\n\n            return coreRunCopy;\n\n            static bool TryToCreateSubfolder(DirectoryInfo directory)\n            {\n                try\n                {\n                    if (!directory.Exists)\n                    {\n                        directory.Create();\n                    }\n\n                    return true;\n                }\n                catch\n                {\n                    return false;\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/CsProj/CsProjClassicNetToolchain.cs",
    "content": "﻿using System.Collections.Generic;\nusing BenchmarkDotNet.Characteristics;\nusing BenchmarkDotNet.Detectors;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Portability;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Toolchains.DotNetCli;\nusing BenchmarkDotNet.Validators;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Toolchains.CsProj\n{\n    /// <summary>\n    /// this toolchain is designed for the new .csprojs, to build .NET 4.x benchmarks from the context of .NET Core host process\n    /// it does not work with the old .csprojs or project.json!\n    /// </summary>\n    [PublicAPI]\n    public class CsProjClassicNetToolchain : Toolchain\n    {\n        [PublicAPI] public static readonly IToolchain Net461 = new CsProjClassicNetToolchain(\"net461\", \".NET Framework 4.6.1\");\n        [PublicAPI] public static readonly IToolchain Net462 = new CsProjClassicNetToolchain(\"net462\", \".NET Framework 4.6.2\");\n        [PublicAPI] public static readonly IToolchain Net47 = new CsProjClassicNetToolchain(\"net47\", \".NET Framework 4.7\");\n        [PublicAPI] public static readonly IToolchain Net471 = new CsProjClassicNetToolchain(\"net471\", \".NET Framework 4.7.1\");\n        [PublicAPI] public static readonly IToolchain Net472 = new CsProjClassicNetToolchain(\"net472\", \".NET Framework 4.7.2\");\n        [PublicAPI] public static readonly IToolchain Net48 = new CsProjClassicNetToolchain(\"net48\", \".NET Framework 4.8\");\n        [PublicAPI] public static readonly IToolchain Net481 = new CsProjClassicNetToolchain(\"net481\", \".NET Framework 4.8.1\");\n\n        internal string CustomDotNetCliPath { get; }\n\n        private CsProjClassicNetToolchain(string targetFrameworkMoniker, string name, string packagesPath = \"\", string customDotNetCliPath = \"\")\n            : base(name,\n                new CsProjGenerator(\n                    targetFrameworkMoniker,\n                    customDotNetCliPath,\n                    packagesPath,\n                    isNetCore: false),\n                new DotNetCliBuilder(targetFrameworkMoniker, customDotNetCliPath),\n                new Executor())\n        {\n            CustomDotNetCliPath = customDotNetCliPath;\n        }\n\n        public static IToolchain From(string targetFrameworkMoniker, string packagesPath = \"\", string customDotNetCliPath = \"\")\n            => new CsProjClassicNetToolchain(\n                targetFrameworkMoniker,\n                name: targetFrameworkMoniker,\n                packagesPath.EnsureNotNull(),\n                customDotNetCliPath.EnsureNotNull());\n\n        public override IEnumerable<ValidationError> Validate(BenchmarkCase benchmarkCase, IResolver resolver)\n        {\n            foreach (var validationError in base.Validate(benchmarkCase, resolver))\n            {\n                yield return validationError;\n            }\n\n            if (!OsDetector.IsWindows())\n            {\n                yield return new ValidationError(true,\n                    $\"Classic .NET toolchain is supported only for Windows, benchmark '{benchmarkCase.DisplayInfo}' will not be executed\",\n                    benchmarkCase);\n                yield break;\n            }\n            else if (DotNetSdkValidator.IsCliPathInvalid(CustomDotNetCliPath, benchmarkCase, out var invalidCliError))\n            {\n                yield return invalidCliError;\n            }\n\n            foreach (var validationError in DotNetSdkValidator.ValidateFrameworkSdks(benchmarkCase))\n            {\n                yield return validationError;\n            }\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/CsProj/CsProjCoreToolchain.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing BenchmarkDotNet.Characteristics;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Toolchains.DotNetCli;\nusing BenchmarkDotNet.Toolchains.InProcess.Emit;\nusing BenchmarkDotNet.Validators;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Toolchains.CsProj\n{\n    [PublicAPI]\n    public class CsProjCoreToolchain : Toolchain, IEquatable<CsProjCoreToolchain>\n    {\n        [PublicAPI] public static readonly IToolchain NetCoreApp20 = From(NetCoreAppSettings.NetCoreApp20);\n        [PublicAPI] public static readonly IToolchain NetCoreApp21 = From(NetCoreAppSettings.NetCoreApp21);\n        [PublicAPI] public static readonly IToolchain NetCoreApp22 = From(NetCoreAppSettings.NetCoreApp22);\n        [PublicAPI] public static readonly IToolchain NetCoreApp30 = From(NetCoreAppSettings.NetCoreApp30);\n        [PublicAPI] public static readonly IToolchain NetCoreApp31 = From(NetCoreAppSettings.NetCoreApp31);\n        [PublicAPI] public static readonly IToolchain NetCoreApp50 = From(NetCoreAppSettings.NetCoreApp50);\n        [PublicAPI] public static readonly IToolchain NetCoreApp60 = From(NetCoreAppSettings.NetCoreApp60);\n        [PublicAPI] public static readonly IToolchain NetCoreApp70 = From(NetCoreAppSettings.NetCoreApp70);\n        [PublicAPI] public static readonly IToolchain NetCoreApp80 = From(NetCoreAppSettings.NetCoreApp80);\n        [PublicAPI] public static readonly IToolchain NetCoreApp90 = From(NetCoreAppSettings.NetCoreApp90);\n        [PublicAPI] public static readonly IToolchain NetCoreApp10_0 = From(NetCoreAppSettings.NetCoreApp10_0);\n        [PublicAPI] public static readonly IToolchain NetCoreApp11_0 = From(NetCoreAppSettings.NetCoreApp11_0);\n\n        internal CsProjCoreToolchain(string name, IGenerator generator, IBuilder builder, IExecutor executor, string customDotNetCliPath)\n            : base(name, generator, builder, executor)\n        {\n            CustomDotNetCliPath = customDotNetCliPath;\n        }\n\n        internal string CustomDotNetCliPath { get; }\n\n        [PublicAPI]\n        public static IToolchain From(NetCoreAppSettings settings)\n            => new CsProjCoreToolchain(settings.Name,\n                new CsProjGenerator(settings.TargetFrameworkMoniker, settings.CustomDotNetCliPath, settings.PackagesPath, settings.RuntimeFrameworkVersion),\n                new DotNetCliBuilder(settings.TargetFrameworkMoniker, settings.CustomDotNetCliPath),\n                new DotNetCliExecutor(settings.CustomDotNetCliPath),\n                settings.CustomDotNetCliPath);\n\n        public override IEnumerable<ValidationError> Validate(BenchmarkCase benchmarkCase, IResolver resolver)\n        {\n            foreach (var validationError in base.Validate(benchmarkCase, resolver))\n            {\n                yield return validationError;\n            }\n\n            if (benchmarkCase.Job.HasValue(EnvironmentMode.JitCharacteristic) && benchmarkCase.Job.ResolveValue(EnvironmentMode.JitCharacteristic, resolver) == Jit.LegacyJit)\n            {\n                yield return new ValidationError(true,\n                    $\"Currently dotnet cli toolchain supports only RyuJit, benchmark '{benchmarkCase.DisplayInfo}' will not be executed\",\n                    benchmarkCase);\n            }\n            if (benchmarkCase.Job.ResolveValue(GcMode.CpuGroupsCharacteristic, resolver))\n            {\n                yield return new ValidationError(true,\n                    $\"Currently project.json does not support CpuGroups (app.config does), benchmark '{benchmarkCase.DisplayInfo}' will not be executed\",\n                    benchmarkCase);\n            }\n            if (benchmarkCase.Job.ResolveValue(GcMode.AllowVeryLargeObjectsCharacteristic, resolver))\n            {\n                yield return new ValidationError(true,\n                    $\"Currently project.json does not support gcAllowVeryLargeObjects (app.config does), benchmark '{benchmarkCase.DisplayInfo}' will not be executed\",\n                    benchmarkCase);\n            }\n\n            var benchmarkAssembly = benchmarkCase.Descriptor.Type.Assembly;\n            if (benchmarkAssembly.IsLinqPad())\n            {\n                yield return new ValidationError(true,\n                    $\"Currently CsProjCoreToolchain does not support LINQPad 6+. Please use {nameof(InProcessEmitToolchain)} instead.\",\n                    benchmarkCase);\n            }\n\n            foreach (var validationError in DotNetSdkValidator.ValidateCoreSdks(CustomDotNetCliPath, benchmarkCase))\n            {\n                yield return validationError;\n            }\n        }\n\n        public override bool Equals(object? obj) => obj is CsProjCoreToolchain typed && Equals(typed);\n\n        public bool Equals(CsProjCoreToolchain? other)\n        {\n            if (other == null)\n                return false;\n\n            return Generator.Equals(other.Generator);\n        }\n\n        public override int GetHashCode() => Generator.GetHashCode();\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/CsProj/CsProjGenerator.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Collections.Immutable;\nusing System.Diagnostics.CodeAnalysis;\nusing System.IO;\nusing System.Linq;\nusing System.Reflection;\nusing System.Text;\nusing System.Xml;\nusing BenchmarkDotNet.Characteristics;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Helpers;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Toolchains.DotNetCli;\nusing BenchmarkDotNet.Toolchains.Mono;\nusing BenchmarkDotNet.Toolchains.Results;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Toolchains.CsProj\n{\n    [PublicAPI]\n    public class CsProjGenerator : DotNetCliGenerator, IEquatable<CsProjGenerator>\n    {\n        private const string DefaultSdkName = \"Microsoft.NET.Sdk\";\n\n        private static readonly ImmutableArray<string> SettingsWeWantToCopy = new[]\n        {\n            \"NetCoreAppImplicitPackageVersion\",\n            \"RuntimeFrameworkVersion\",\n            \"PackageTargetFallback\",\n            \"LangVersion\",\n            \"UseWpf\",\n            \"UseWindowsForms\",\n            \"CopyLocalLockFileAssemblies\",\n            \"PreserveCompilationContext\",\n            \"UserSecretsId\",\n            \"EnablePreviewFeatures\",\n            \"RuntimeHostConfigurationOption\",\n            \"WarningsAsErrors\",\n        }.ToImmutableArray();\n\n        public string RuntimeFrameworkVersion { get; }\n\n        public CsProjGenerator(string targetFrameworkMoniker, string cliPath, string packagesPath, string runtimeFrameworkVersion = \"\", bool isNetCore = true)\n            : base(targetFrameworkMoniker, cliPath, packagesPath, isNetCore)\n        {\n            RuntimeFrameworkVersion = runtimeFrameworkVersion.EnsureNotNull();\n        }\n\n        protected override string GetBuildArtifactsDirectoryPath(BuildPartition buildPartition, string programName)\n        {\n            string assemblyLocation = buildPartition.RepresentativeBenchmarkCase.Descriptor.Type.Assembly.Location;\n\n            //Assembles loaded from a stream will have an empty location (https://docs.microsoft.com/en-us/dotnet/api/system.reflection.assembly.location).\n            string directoryName = assemblyLocation.IsEmpty() ?\n                Path.Combine(Directory.GetCurrentDirectory(), \"BenchmarkDotNet.Bin\") :\n                Path.GetDirectoryName(buildPartition.AssemblyLocation)!;\n\n            return Path.Combine(directoryName, programName);\n        }\n\n        protected override string GetProjectFilePath(string buildArtifactsDirectoryPath)\n            => Path.Combine(buildArtifactsDirectoryPath, \"BenchmarkDotNet.Autogenerated.csproj\");\n\n        protected override string GetBinariesDirectoryPath(string buildArtifactsDirectoryPath, string configuration)\n            => Path.Combine(buildArtifactsDirectoryPath, \"bin\", configuration, TargetFrameworkMoniker);\n\n        protected override void GenerateBuildScript(BuildPartition buildPartition, ArtifactsPaths artifactsPaths)\n        {\n            string projectFilePath = GetProjectFilePath(buildPartition.RepresentativeBenchmarkCase.Descriptor.Type, NullLogger.Instance).FullName;\n\n            var content = new StringBuilder(300)\n                .AppendLine($\"call {CliPath} {DotNetCliCommand.GetRestoreCommand(artifactsPaths, buildPartition, projectFilePath)}\")\n                .AppendLine($\"call {CliPath} {DotNetCliCommand.GetBuildCommand(artifactsPaths, buildPartition, projectFilePath, TargetFrameworkMoniker)}\")\n                .AppendLine($\"call {CliPath} {DotNetCliCommand.GetRestoreCommand(artifactsPaths, buildPartition, artifactsPaths.ProjectFilePath)}\")\n                .AppendLine($\"call {CliPath} {DotNetCliCommand.GetBuildCommand(artifactsPaths, buildPartition, artifactsPaths.ProjectFilePath, TargetFrameworkMoniker)}\")\n                .ToString();\n\n            File.WriteAllText(artifactsPaths.BuildScriptFilePath, content);\n        }\n\n        [SuppressMessage(\"ReSharper\", \"StringLiteralTypo\")] // R# complains about $variables$\n        protected override void GenerateProject(BuildPartition buildPartition, ArtifactsPaths artifactsPaths, ILogger logger)\n        {\n            File.WriteAllText(artifactsPaths.ProjectFilePath,\n                GenerateBuildProject(buildPartition, artifactsPaths, logger)\n            );\n\n            // Integration tests are built without dependencies, so we skip gathering dlls.\n            if (!buildPartition.ForcedNoDependenciesForIntegrationTests)\n            {\n                GatherReferences(buildPartition, artifactsPaths, logger);\n            }\n        }\n\n        private string GenerateBuildProject(BuildPartition buildPartition, ArtifactsPaths artifactsPaths, ILogger logger)\n        {\n            var benchmark = buildPartition.RepresentativeBenchmarkCase;\n            var projectFile = GetProjectFilePath(benchmark.Descriptor.Type, logger);\n\n            var xmlDoc = new XmlDocument();\n            xmlDoc.Load(projectFile.FullName);\n            var (customProperties, sdkName) = GetSettingsThatNeedToBeCopied(xmlDoc, projectFile);\n\n            return new StringBuilder(ResourceHelper.LoadTemplate(\"CsProj.txt\"))\n                .Replace(\"$PLATFORM$\", buildPartition.Platform.ToConfig())\n                .Replace(\"$CODEFILENAME$\", Path.GetFileName(artifactsPaths.ProgramCodePath))\n                .Replace(\"$CSPROJPATH$\", projectFile.FullName)\n                .Replace(\"$TFM$\", TargetFrameworkMoniker)\n                .Replace(\"$PROGRAMNAME$\", artifactsPaths.ProgramName)\n                .Replace(\"$RUNTIMESETTINGS$\", GetRuntimeSettings(benchmark.Job.Environment.Gc, buildPartition.Resolver))\n                .Replace(\"$COPIEDSETTINGS$\", customProperties)\n                .Replace(\"$SDKNAME$\", sdkName)\n                .ToString();\n        }\n\n        private static string GetDllGathererPath(string filePath)\n            => Path.Combine(Path.GetDirectoryName(filePath)!, $\"DllGatherer{Path.GetExtension(filePath)}\");\n\n        protected void GatherReferences(BuildPartition buildPartition, ArtifactsPaths artifactsPaths, ILogger logger)\n        {\n            // Create a project using the default template to build the original project for all necessary runtime dlls.\n            // We can't just build the original project directly because it could be a library project, so we need an exe project to reference it.\n            var xmlDoc = new XmlDocument();\n            xmlDoc.LoadXml(GenerateBuildProject(buildPartition, artifactsPaths, logger));\n            var projectElement = xmlDoc.DocumentElement!;\n\n            // Replace the default C# file with an empty Main method to satisfy the exe build.\n            var compileNode = projectElement.SelectSingleNode(\"ItemGroup/Compile\")!;\n            string emptyMainFile = GetDllGathererPath(artifactsPaths.ProgramCodePath);\n            compileNode.Attributes![\"Include\"]!.Value = emptyMainFile;\n            string gathererProject = GetDllGathererPath(artifactsPaths.ProjectFilePath);\n            xmlDoc.Save(gathererProject);\n\n            File.WriteAllText(emptyMainFile, \"\"\"\n                namespace BenchmarkDotNet.Autogenerated\n                {\n                    public class UniqueProgramName\n                    {\n                        public static int Main(string[] args)\n                        {\n                            return 0;\n                        }\n                    }\n                }\n                \"\"\");\n\n            // Build the original project then reference all of the built dlls.\n            BuildResult buildResult = new DotNetCliCommand(\n                CliPath,\n                gathererProject,\n                TargetFrameworkMoniker,\n                arguments: \"\",\n                GenerateResult.Success(artifactsPaths, []),\n                logger,\n                buildPartition,\n                [],\n                buildPartition.Timeout\n            ).RestoreThenBuild();\n\n            if (!buildResult.IsBuildSuccess)\n            {\n                if (!buildResult.TryToExplainFailureReason(out string? reason))\n                {\n                    reason = buildResult.ErrorMessage;\n                }\n                logger.WriteLineWarning($\"Failed to gather assembly references, reason:{Environment.NewLine}{reason}\");\n                return;\n            }\n\n            // Delete the dll from the gatherer project to prevent duplicate references.\n            File.Delete(Path.Combine(artifactsPaths.BinariesDirectoryPath, $\"{artifactsPaths.ProgramName}.dll\"));\n\n            xmlDoc = new XmlDocument();\n            xmlDoc.Load(artifactsPaths.ProjectFilePath);\n            projectElement = xmlDoc.DocumentElement!;\n            var itemGroup = xmlDoc.CreateElement(\"ItemGroup\");\n            projectElement.AppendChild(itemGroup);\n            foreach (var assemblyFile in Directory.GetFiles(artifactsPaths.BinariesDirectoryPath, \"*.dll\"))\n            {\n                var referenceElement = xmlDoc.CreateElement(\"Reference\");\n                itemGroup.AppendChild(referenceElement);\n                referenceElement.SetAttribute(\"Include\", Path.GetFileNameWithoutExtension(assemblyFile));\n                var hintPath = xmlDoc.CreateElement(\"HintPath\");\n                referenceElement.AppendChild(hintPath);\n                var locationNode = xmlDoc.CreateTextNode(assemblyFile);\n                hintPath.AppendChild(locationNode);\n                // TODO: Add Aliases here for extern alias #2289\n            }\n\n            xmlDoc.Save(artifactsPaths.ProjectFilePath);\n        }\n\n        /// <summary>\n        /// returns an MSBuild string that defines Runtime settings\n        /// </summary>\n        [PublicAPI]\n        protected virtual string GetRuntimeSettings(GcMode gcMode, IResolver resolver)\n        {\n            var builder = new StringBuilder(80)\n                .AppendLine($\"<PropertyGroup>\")\n                .AppendLine($\"    <ServerGarbageCollection>{gcMode.ResolveValue(GcMode.ServerCharacteristic, resolver).ToLowerCase()}</ServerGarbageCollection>\")\n                .AppendLine($\"    <ConcurrentGarbageCollection>{gcMode.ResolveValue(GcMode.ConcurrentCharacteristic, resolver).ToLowerCase()}</ConcurrentGarbageCollection>\");\n\n            if (gcMode.HasValue(GcMode.RetainVmCharacteristic))\n                builder.AppendLine($\"    <RetainVMGarbageCollection>{gcMode.ResolveValue(GcMode.RetainVmCharacteristic, resolver).ToLowerCase()}</RetainVMGarbageCollection>\");\n\n            return builder.AppendLine(\"  </PropertyGroup>\").ToString();\n        }\n\n        // the host project or one of the .props file that it imports might contain some custom settings that needs to be copied, sth like\n        // <NetCoreAppImplicitPackageVersion>2.0.0-beta-001607-00</NetCoreAppImplicitPackageVersion>\n        // <RuntimeFrameworkVersion>2.0.0-beta-001607-00</RuntimeFrameworkVersion>\n        internal (string customProperties, string sdkName) GetSettingsThatNeedToBeCopied(XmlDocument xmlDoc, FileInfo projectFile)\n        {\n            if (RuntimeFrameworkVersion.IsNotBlank()) // some power users knows what to configure, just do it and copy nothing more\n            {\n                return (@$\"<PropertyGroup>\n    <RuntimeFrameworkVersion>{RuntimeFrameworkVersion}</RuntimeFrameworkVersion>\n  </PropertyGroup>\", DefaultSdkName);\n            }\n\n            XmlElement projectElement = xmlDoc.DocumentElement!;\n            // custom SDKs are not added for non-netcoreapp apps (like net471), so when the TFM != netcoreapp we dont parse \"<Import Sdk=\"\n            // we don't allow for that mostly to prevent from edge cases like the following\n            // <Import Sdk=\"Microsoft.NET.Sdk.WindowsDesktop\" Project=\"Sdk.props\" Condition=\"'$(TargetFramework)'=='netcoreapp3.0'\"/>\n            string? sdkName = null;\n            if (TargetFrameworkMoniker.StartsWith(\"netcoreapp\", StringComparison.InvariantCultureIgnoreCase))\n            {\n                foreach (XmlElement importElement in projectElement.GetElementsByTagName(\"Import\"))\n                {\n                    sdkName = importElement.GetAttribute(\"Sdk\");\n                    if (sdkName.IsNotBlank())\n                    {\n                        break;\n                    }\n                }\n            }\n            if (sdkName.IsBlank())\n            {\n                sdkName = projectElement.GetAttribute(\"Sdk\");\n            }\n            // If Sdk isn't an attribute on the Project element, it could be a child element.\n            if (sdkName.IsBlank())\n            {\n                foreach (XmlElement sdkElement in projectElement.GetElementsByTagName(\"Sdk\"))\n                {\n                    sdkName = sdkElement.GetAttribute(\"Name\");\n                    if (sdkName.IsBlank())\n                    {\n                        continue;\n                    }\n                    string version = sdkElement.GetAttribute(\"Version\");\n                    // Version is optional\n                    if (version.IsNotBlank())\n                    {\n                        sdkName += $\"/{version}\";\n                    }\n                    break;\n                }\n            }\n            if (sdkName.IsBlank())\n            {\n                sdkName = DefaultSdkName;\n            }\n\n            XmlDocument? itemGroupsettings = null;\n            XmlDocument? propertyGroupSettings = null;\n\n            GetSettingsThatNeedToBeCopied(projectElement, ref itemGroupsettings, ref propertyGroupSettings, projectFile);\n\n            List<string> customSettings = new List<string>(2);\n            if (itemGroupsettings != null)\n            {\n                customSettings.Add(GetIndentedXmlString(itemGroupsettings));\n            }\n            if (propertyGroupSettings != null)\n            {\n                customSettings.Add(GetIndentedXmlString(propertyGroupSettings));\n            }\n\n            return (string.Join(Environment.NewLine + Environment.NewLine, customSettings), sdkName);\n        }\n\n        private static void GetSettingsThatNeedToBeCopied(XmlElement projectElement, ref XmlDocument? itemGroupsettings, ref XmlDocument? propertyGroupSettings, FileInfo projectFile)\n        {\n            CopyProperties(projectElement, ref itemGroupsettings, \"ItemGroup\");\n            CopyProperties(projectElement, ref propertyGroupSettings, \"PropertyGroup\");\n\n            foreach (XmlElement importElement in projectElement.GetElementsByTagName(\"Import\"))\n            {\n                string propsFilePath = importElement.GetAttribute(\"Project\");\n                var directoryName = projectFile.DirectoryName ?? throw new DirectoryNotFoundException(projectFile.DirectoryName);\n                string absolutePath = File.Exists(propsFilePath)\n                    ? propsFilePath // absolute path or relative to current dir\n                    : Path.Combine(directoryName, propsFilePath); // relative to csproj\n                if (File.Exists(absolutePath))\n                {\n                    var importXmlDoc = new XmlDocument();\n                    importXmlDoc.Load(absolutePath);\n                    GetSettingsThatNeedToBeCopied(importXmlDoc.DocumentElement!, ref itemGroupsettings, ref propertyGroupSettings, projectFile);\n                }\n            }\n        }\n\n        private static void CopyProperties(XmlElement projectElement, ref XmlDocument? copyToDocument, string groupName)\n        {\n            XmlElement? itemGroupElement = copyToDocument?.DocumentElement;\n            foreach (XmlElement groupElement in projectElement.GetElementsByTagName(groupName))\n            {\n                foreach (var node in groupElement.ChildNodes)\n                {\n                    if (node is XmlElement setting && SettingsWeWantToCopy.Contains(setting.Name))\n                    {\n                        if (copyToDocument is null)\n                        {\n                            copyToDocument = new XmlDocument();\n                            itemGroupElement = copyToDocument.CreateElement(groupName);\n                            copyToDocument.AppendChild(itemGroupElement);\n                        }\n                        XmlNode copiedNode = copyToDocument.ImportNode(setting, true);\n                        itemGroupElement!.AppendChild(copiedNode);\n                    }\n                }\n            }\n        }\n\n        private static string GetIndentedXmlString(XmlDocument doc)\n        {\n            StringBuilder sb = new StringBuilder();\n            XmlWriterSettings settings = new XmlWriterSettings\n            {\n                OmitXmlDeclaration = true,\n                Indent = true,\n                IndentChars = \"  \"\n            };\n            using (XmlWriter writer = XmlWriter.Create(sb, settings))\n            {\n                doc.Save(writer);\n            }\n            return sb.ToString();\n        }\n\n        /// <summary>\n        /// returns a path to the project file which defines the benchmarks\n        /// </summary>\n        [PublicAPI]\n        protected virtual FileInfo GetProjectFilePath(Type benchmarkTarget, ILogger logger)\n        {\n            if (!GetSolutionRootDirectory(out var rootDirectory) && !GetProjectRootDirectory(out rootDirectory))\n            {\n                logger.WriteLineError(\n                    $\"Unable to find .sln .slnx or .csproj file. Will use current directory {Directory.GetCurrentDirectory()} to search for project file. If you don't use .sln file on purpose it should not be a problem.\");\n                rootDirectory = new DirectoryInfo(Directory.GetCurrentDirectory());\n            }\n\n            // important assumption! project's file name === output dll name\n            string projectName = benchmarkTarget.GetTypeInfo().Assembly.GetName().Name!;\n\n            var projectFile = Helpers.FindProjectFile(rootDirectory, projectName);\n            return projectFile;\n        }\n\n        public override bool Equals(object? obj) => obj is CsProjGenerator other && Equals(other);\n\n        public bool Equals(CsProjGenerator? other)\n        {\n            if (ReferenceEquals(this, other))\n                return true;\n\n            if (other is null)\n                return false;\n\n            return TargetFrameworkMoniker == other.TargetFrameworkMoniker\n                && RuntimeFrameworkVersion == other.RuntimeFrameworkVersion\n                && CliPath == other.CliPath\n                && PackagesPath == other.PackagesPath;\n        }\n\n        public override int GetHashCode()\n            => HashCode.Combine(TargetFrameworkMoniker, RuntimeFrameworkVersion, CliPath, PackagesPath);\n    }\n\n    file static class Helpers\n    {\n        private static readonly HashSet<string> IgnoredDirectoryNames = new(StringComparer.Ordinal)\n        {\n            \".git\",\n            \".vs\",\n            \"bin\",\n            \"obj\",\n        };\n\n        private static readonly HashSet<string> ProjectExtensions = new(StringComparer.Ordinal)\n        {\n            \".csproj\",\n            \".fsproj\",\n            \".vbproj\"\n        };\n\n        public static FileInfo FindProjectFile(DirectoryInfo rootDirectory, string projectName)\n        {\n            var projectFiles = EnumerateProjectFiles(rootDirectory, projectName);\n\n            // Take first 2 items for performance reasons\n            var files = projectFiles.Take(2).ToArray();\n            return files.Length switch\n            {\n                1 => files[0],\n                0 => throw new NotSupportedException(\n                    $\"Unable to find {projectName} in {rootDirectory.FullName} and its subfolders. Most probably the name of output exe is different than the name of the .(c/f)sproj\"),\n                _ => throw new NotSupportedException(\n                    $\"Found more than one matching project file for {projectName} in {rootDirectory.FullName} and its subfolders: '{files[0].FullName}','{files[1].FullName}'. Benchmark project names needs to be unique.\"),\n            };\n        }\n\n        private static IEnumerable<FileInfo> EnumerateProjectFiles(DirectoryInfo rootDirectory, string projectName)\n        {\n            var stack = new Stack<DirectoryInfo>();\n            stack.Push(rootDirectory);\n\n            while (stack.Count > 0)\n            {\n                var currentDir = stack.Pop();\n\n                // 1. Search '*.proj' files in the current directory\n                IEnumerable<FileInfo> files = EnumerateProjectFiles(currentDir);\n\n                foreach (var file in files)\n                {\n                    if (!ProjectExtensions.Contains(file.Extension))\n                        continue;\n\n                    if (Path.GetFileNameWithoutExtension(file.Name) == projectName)\n                        yield return file;\n                }\n\n                var subDirectories = GetSubDirectories(currentDir);\n\n                // 2. Handle sub directories.\n                foreach (var dir in subDirectories)\n                {\n                    if (IgnoredDirectoryNames.Contains(dir.Name))\n                        continue;\n#if NETSTANDARD2_0\n                    // Ignore reparse point / symlink to avoid infinite loops\n                    if (dir.Attributes.HasFlag(FileAttributes.ReparsePoint))\n                        continue;\n#endif\n                    stack.Push(dir);\n                }\n            }\n        }\n\n#if NETSTANDARD2_0\n        private static IEnumerable<FileInfo> EnumerateProjectFiles(DirectoryInfo directory)\n        {\n            IEnumerable<FileInfo> projectFiles;\n            try\n            {\n                projectFiles = directory.EnumerateFiles(\"*proj\", SearchOption.TopDirectoryOnly);\n            }\n            catch\n            {\n                yield break;\n            }\n\n            foreach (var file in projectFiles)\n                yield return file;\n        }\n\n        private static IEnumerable<DirectoryInfo> GetSubDirectories(DirectoryInfo currentDir)\n        {\n            try\n            {\n                return currentDir.EnumerateDirectories();\n            }\n            catch\n            {\n                return [];\n            }\n        }\n#else\n        private static readonly EnumerationOptions DirectoryEnumerationOptions = new()\n        {\n            RecurseSubdirectories = false,\n            IgnoreInaccessible = true,\n            AttributesToSkip = FileAttributes.ReparsePoint\n        };\n\n        private static IEnumerable<FileInfo> EnumerateProjectFiles(DirectoryInfo directory)\n            => directory.EnumerateFiles(\"*proj\", DirectoryEnumerationOptions);\n\n        private static IEnumerable<DirectoryInfo> GetSubDirectories(DirectoryInfo currentDir)\n            => currentDir.EnumerateDirectories(\"*\", DirectoryEnumerationOptions);\n#endif\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/DotNetCli/CustomDotNetCliToolchainBuilder.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Diagnostics.CodeAnalysis;\nusing System.IO;\nusing BenchmarkDotNet.Detectors;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Portability;\nusing JetBrains.Annotations;\n#if NETSTANDARD\nusing Microsoft.DotNet.PlatformAbstractions;\n#endif\n\nnamespace BenchmarkDotNet.Toolchains.DotNetCli\n{\n    [SuppressMessage(\"ReSharper\", \"InconsistentNaming\")]\n    public abstract class CustomDotNetCliToolchainBuilder\n    {\n        protected readonly Dictionary<string, string> Feeds = [];\n\n        protected string? runtimeIdentifier;\n        protected string? customDotNetCliPath;\n        protected string? displayName;\n        protected string? runtimeFrameworkVersion;\n\n        protected bool useNuGetClearTag;\n        protected bool useTempFolderForRestore;\n        private string? targetFrameworkMoniker;\n\n        public abstract IToolchain ToToolchain();\n\n        /// <summary>it allows you to define an additional NuGet feed, you can seal the feeds list by using the UseNuGetClearTag() method</summary>\n        /// <param name=\"feedName\">the name of the feed, will be used in the auto-generated NuGet.config file</param>\n        /// <param name=\"feedAddress\">the address of the feed, will be used in the auto-generated NuGet.config file</param>\n        [PublicAPI]\n        public CustomDotNetCliToolchainBuilder AdditionalNuGetFeed(string feedName, string feedAddress)\n        {\n            if (string.IsNullOrEmpty(feedName)) throw new ArgumentException(\"Value cannot be null or empty.\", nameof(feedName));\n            if (string.IsNullOrEmpty(feedAddress)) throw new ArgumentException(\"Value cannot be null or empty.\", nameof(feedAddress));\n\n            Feeds[feedName] = feedAddress;\n\n            return this;\n        }\n\n        /// <summary>\n        /// emits clear tag in the auto-generated NuGet.config file\n        /// </summary>\n        public CustomDotNetCliToolchainBuilder UseNuGetClearTag(bool value)\n        {\n            useNuGetClearTag = value;\n\n            return this;\n        }\n\n        /// <param name=\"targetFrameworkMoniker\">TFM, example: net8.0</param>\n        [PublicAPI]\n        [SuppressMessage(\"ReSharper\", \"ParameterHidesMember\")]\n        public CustomDotNetCliToolchainBuilder TargetFrameworkMoniker(string targetFrameworkMoniker)\n        {\n            this.targetFrameworkMoniker = targetFrameworkMoniker ?? throw new ArgumentNullException(nameof(targetFrameworkMoniker));\n\n            return this;\n        }\n\n        protected string GetTargetFrameworkMoniker()\n        {\n            if (targetFrameworkMoniker.IsNotBlank())\n                return targetFrameworkMoniker;\n            if (!RuntimeInformation.IsNetCore)\n                throw new NotSupportedException(\"You must specify the target framework moniker in explicit way using builder.TargetFrameworkMoniker(tfm) method\");\n\n            return CoreRuntime.GetCurrentVersion().MsBuildMoniker;\n        }\n\n        /// <param name=\"newCustomDotNetCliPath\">if not provided, the one from PATH will be used</param>\n        [PublicAPI]\n        public CustomDotNetCliToolchainBuilder DotNetCli(string newCustomDotNetCliPath)\n        {\n            if (newCustomDotNetCliPath.IsNotBlank() && !File.Exists(newCustomDotNetCliPath))\n                throw new FileNotFoundException(\"Given file does not exist\", newCustomDotNetCliPath);\n\n            customDotNetCliPath = newCustomDotNetCliPath;\n\n            return this;\n        }\n\n        /// <param name=\"newRuntimeIdentifier\">if not provided, portable OS-arch will be used (example: \"win-x64\", \"linux-x86\")</param>\n        [PublicAPI]\n        public CustomDotNetCliToolchainBuilder RuntimeIdentifier(string newRuntimeIdentifier)\n        {\n            runtimeIdentifier = newRuntimeIdentifier;\n\n            return this;\n        }\n\n        /// <param name=\"newRuntimeFrameworkVersion\">optional, when set it's copied to the generated .csproj file</param>\n        [PublicAPI]\n        public CustomDotNetCliToolchainBuilder RuntimeFrameworkVersion(string newRuntimeFrameworkVersion)\n        {\n            runtimeFrameworkVersion = newRuntimeFrameworkVersion;\n\n            return this;\n        }\n\n        /// <param name=\"newDisplayName\">the name of the toolchain to be displayed in results</param>\n        [PublicAPI]\n        public CustomDotNetCliToolchainBuilder DisplayName(string newDisplayName)\n        {\n            if (string.IsNullOrEmpty(newDisplayName)) throw new ArgumentException(\"Value cannot be null or empty.\", nameof(newDisplayName));\n\n            displayName = newDisplayName;\n\n            return this;\n        }\n\n        /// <summary>\n        /// restore to temp folder to keep your CI clean or install same package many times (perhaps with different content but same version number), by default true for local builds\n        /// https://github.com/dotnet/corefx/blob/master/Documentation/project-docs/dogfooding.md#3---consuming-subsequent-code-changes-by-rebuilding-the-package-alternative-2\n        /// </summary>\n        [PublicAPI]\n        public CustomDotNetCliToolchainBuilder UseTempFolderForRestore(bool value)\n        {\n            useTempFolderForRestore = value;\n\n            return this;\n        }\n\n        internal static string GetPortableRuntimeIdentifier()\n        {\n            // Microsoft.DotNet.PlatformAbstractions.RuntimeEnvironment.GetRuntimeIdentifier()\n            // returns win10-x64, we want the simpler form win-x64\n            // the values taken from https://docs.microsoft.com/en-us/dotnet/core/rid-catalog#macos-rids\n            string osPart = OsDetector.IsWindows() ? \"win\" : (OsDetector.IsMacOS() ? \"osx\" : \"linux\");\n\n            string architecture =\n#if NETSTANDARD\n                RuntimeEnvironment.RuntimeArchitecture;\n#else\n                System.Runtime.InteropServices.RuntimeInformation.ProcessArchitecture.ToString().ToLowerInvariant();\n#endif\n\n            return $\"{osPart}-{architecture}\";\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/DotNetCli/DotNetCliBuilder.cs",
    "content": "using System;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Toolchains.Results;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Toolchains.DotNetCli\n{\n    [PublicAPI]\n    public class DotNetCliBuilder : IBuilder\n    {\n        private string TargetFrameworkMoniker { get; }\n\n        private string CustomDotNetCliPath { get; }\n        private bool LogOutput { get; }\n\n        [PublicAPI]\n        public DotNetCliBuilder(string targetFrameworkMoniker, string customDotNetCliPath = \"\", bool logOutput = false)\n        {\n            TargetFrameworkMoniker = targetFrameworkMoniker;\n            CustomDotNetCliPath = customDotNetCliPath;\n            LogOutput = logOutput;\n        }\n\n        public BuildResult Build(GenerateResult generateResult, BuildPartition buildPartition, ILogger logger)\n        {\n            var buildResult = new DotNetCliCommand(\n                CustomDotNetCliPath,\n                generateResult.ArtifactsPaths.ProjectFilePath,\n                TargetFrameworkMoniker,\n                string.Empty,\n                generateResult,\n                logger,\n                buildPartition,\n                [],\n                buildPartition.Timeout,\n                logOutput: LogOutput\n            ).RestoreThenBuild();\n            if (buildResult.IsBuildSuccess &&\n                buildPartition.RepresentativeBenchmarkCase.Job.Environment.LargeAddressAware)\n            {\n                LargeAddressAware.SetLargeAddressAware(generateResult.ArtifactsPaths.ExecutablePath);\n            }\n            return buildResult;\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/DotNetCli/DotNetCliCommand.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Text;\nusing BenchmarkDotNet.Characteristics;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Portability;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Toolchains.Results;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Toolchains.DotNetCli\n{\n    public class DotNetCliCommand\n    {\n        [PublicAPI] public string CliPath { get; }\n\n        [PublicAPI] public string FilePath { get; }\n\n        [PublicAPI] public string TargetFrameworkMoniker { get; }\n\n        [PublicAPI] public string Arguments { get; }\n\n        [PublicAPI] public GenerateResult GenerateResult { get; }\n\n        [PublicAPI] public ILogger Logger { get; }\n\n        [PublicAPI] public BuildPartition BuildPartition { get; }\n\n        [PublicAPI] public IReadOnlyList<EnvironmentVariable> EnvironmentVariables { get; }\n\n        [PublicAPI] public TimeSpan Timeout { get; }\n\n        [PublicAPI] public bool LogOutput { get; }\n\n        public DotNetCliCommand(string cliPath, string filePath, string tfm, string arguments, GenerateResult generateResult, ILogger logger,\n            BuildPartition buildPartition, IReadOnlyList<EnvironmentVariable> environmentVariables, TimeSpan timeout, bool logOutput = false)\n        {\n            CliPath = cliPath.IsBlank() ? DotNetCliCommandExecutor.DefaultDotNetCliPath.Value : cliPath;\n            Arguments = arguments;\n            FilePath = filePath;\n            TargetFrameworkMoniker = tfm;\n            GenerateResult = generateResult;\n            Logger = logger;\n            BuildPartition = buildPartition;\n            EnvironmentVariables = environmentVariables ?? [];\n            Timeout = timeout;\n            LogOutput = logOutput || buildPartition.LogBuildOutput;\n        }\n\n        public DotNetCliCommand WithArguments(string arguments)\n            => new(CliPath, FilePath, TargetFrameworkMoniker, arguments, GenerateResult, Logger, BuildPartition, EnvironmentVariables, Timeout, LogOutput);\n\n        public DotNetCliCommand WithCliPath(string cliPath)\n            => new(cliPath, FilePath, TargetFrameworkMoniker, Arguments, GenerateResult, Logger, BuildPartition, EnvironmentVariables, Timeout, LogOutput);\n\n        [PublicAPI]\n        public BuildResult RestoreThenBuild()\n        {\n            DotNetCliCommandExecutor.LogEnvVars(WithArguments(\"\"));\n\n            // there is no way to do tell dotnet restore which configuration to use (https://github.com/NuGet/Home/issues/5119)\n            // so when users go with custom build configuration, we must perform full build\n            // which will internally restore for the right configuration\n            if (BuildPartition.IsCustomBuildConfiguration)\n                return Build().ToBuildResult(GenerateResult);\n\n            // On our CI, Integration tests take too much time, because each benchmark run rebuilds BenchmarkDotNet itself.\n            // To reduce the total duration of the CI workflows, we build all the projects without dependencies\n            if (BuildPartition.ForcedNoDependenciesForIntegrationTests)\n            {\n                var restoreResult = DotNetCliCommandExecutor.Execute(WithArguments(\n                    GetRestoreCommand(GenerateResult.ArtifactsPaths, BuildPartition, FilePath, $\"{Arguments} --no-dependencies\", \"restore-no-deps\", excludeOutput: true)));\n                if (!restoreResult.IsSuccess)\n                    return BuildResult.Failure(GenerateResult, restoreResult.AllInformation);\n\n                return DotNetCliCommandExecutor.Execute(WithArguments(\n                    GetBuildCommand(GenerateResult.ArtifactsPaths, BuildPartition, FilePath, TargetFrameworkMoniker, $\"{Arguments} --no-restore --no-dependencies\", \"build-no-restore-no-deps\", excludeOutput: true)))\n                    .ToBuildResult(GenerateResult);\n            }\n            else\n            {\n                var restoreResult = Restore();\n                if (!restoreResult.IsSuccess)\n                    return BuildResult.Failure(GenerateResult, restoreResult.AllInformation);\n\n                // We no longer retry with --no-dependencies, because it fails with --output set at the same time,\n                // and the artifactsPaths.BinariesDirectoryPath is set before we try to build, so we cannot overwrite it.\n                return BuildNoRestore().ToBuildResult(GenerateResult);\n            }\n        }\n\n        [PublicAPI]\n        public BuildResult RestoreThenBuildThenPublish()\n        {\n            DotNetCliCommandExecutor.LogEnvVars(WithArguments(\"\"));\n\n            // there is no way to do tell dotnet restore which configuration to use (https://github.com/NuGet/Home/issues/5119)\n            // so when users go with custom build configuration, we must perform full publish\n            // which will internally restore and build for the right configuration\n            if (BuildPartition.IsCustomBuildConfiguration)\n                return Publish().ToBuildResult(GenerateResult);\n\n            var restoreResult = Restore();\n            if (!restoreResult.IsSuccess)\n                return BuildResult.Failure(GenerateResult, restoreResult.AllInformation);\n\n            // We use the implicit build in the publish command. We stopped doing a separate build step because we set the --output.\n            return PublishNoRestore().ToBuildResult(GenerateResult);\n        }\n\n        public DotNetCliCommandResult Restore()\n            => DotNetCliCommandExecutor.Execute(WithArguments(\n                GetRestoreCommand(GenerateResult.ArtifactsPaths, BuildPartition, FilePath, Arguments, \"restore\")));\n\n        public DotNetCliCommandResult Build()\n            => DotNetCliCommandExecutor.Execute(WithArguments(\n                GetBuildCommand(GenerateResult.ArtifactsPaths, BuildPartition, FilePath, TargetFrameworkMoniker, Arguments, \"build\")));\n\n        public DotNetCliCommandResult BuildNoRestore()\n            => DotNetCliCommandExecutor.Execute(WithArguments(\n                GetBuildCommand(GenerateResult.ArtifactsPaths, BuildPartition, FilePath, TargetFrameworkMoniker, $\"{Arguments} --no-restore\", \"build-no-restore\")));\n\n        public DotNetCliCommandResult Publish()\n            => DotNetCliCommandExecutor.Execute(WithArguments(\n                GetPublishCommand(GenerateResult.ArtifactsPaths, BuildPartition, FilePath, TargetFrameworkMoniker, Arguments, \"publish\")));\n\n        // PublishNoBuildAndNoRestore was removed because we set --output in the build step. We use the implicit build included in the publish command.\n        public DotNetCliCommandResult PublishNoRestore()\n            => DotNetCliCommandExecutor.Execute(WithArguments(\n                GetPublishCommand(GenerateResult.ArtifactsPaths, BuildPartition, FilePath, TargetFrameworkMoniker, $\"{Arguments} --no-restore\", \"publish-no-restore\")));\n\n        internal static string GetRestoreCommand(ArtifactsPaths artifactsPaths, BuildPartition buildPartition, string filePath, string? extraArguments = null, string? binLogSuffix = null, bool excludeOutput = false)\n            => new StringBuilder()\n                .AppendArgument(\"restore\")\n                .AppendArgument($\"\\\"{filePath}\\\"\")\n                // restore doesn't support -f argument.\n                .AppendArgument(artifactsPaths.PackagesDirectoryName.IsBlank() ? string.Empty : $\"--packages \\\"{artifactsPaths.PackagesDirectoryName}\\\"\")\n                .AppendArgument(GetCustomMsBuildArguments(buildPartition.RepresentativeBenchmarkCase, buildPartition.Resolver))\n                .AppendArgument(extraArguments)\n                .AppendArgument(GetMandatoryMsBuildSettings(buildPartition.BuildConfiguration))\n                .AppendArgument(GetMsBuildBinLogArgument(buildPartition, binLogSuffix))\n                .MaybeAppendOutputPaths(artifactsPaths, true, excludeOutput)\n                .ToString();\n\n        internal static string GetBuildCommand(ArtifactsPaths artifactsPaths, BuildPartition buildPartition, string filePath, string tfm, string? extraArguments = null, string? binLogSuffix = null, bool excludeOutput = false)\n            => new StringBuilder()\n                .AppendArgument(\"build\")\n                .AppendArgument($\"\\\"{filePath}\\\"\")\n                .AppendArgument($\"-f {tfm}\")\n                .AppendArgument($\"-c {buildPartition.BuildConfiguration}\")\n                .AppendArgument(GetCustomMsBuildArguments(buildPartition.RepresentativeBenchmarkCase, buildPartition.Resolver))\n                .AppendArgument(extraArguments)\n                .AppendArgument(GetMandatoryMsBuildSettings(buildPartition.BuildConfiguration))\n                .AppendArgument(artifactsPaths.PackagesDirectoryName.IsBlank() ? string.Empty : $\"/p:NuGetPackageRoot=\\\"{artifactsPaths.PackagesDirectoryName}\\\"\")\n                .AppendArgument(GetMsBuildBinLogArgument(buildPartition, binLogSuffix))\n                .MaybeAppendOutputPaths(artifactsPaths, excludeOutput: excludeOutput)\n                .ToString();\n\n        internal static string GetPublishCommand(ArtifactsPaths artifactsPaths, BuildPartition buildPartition, string filePath, string tfm, string? extraArguments = null, string? binLogSuffix = null)\n            => new StringBuilder()\n                .AppendArgument(\"publish\")\n                .AppendArgument($\"\\\"{filePath}\\\"\")\n                .AppendArgument($\"-f {tfm}\")\n                .AppendArgument($\"-c {buildPartition.BuildConfiguration}\")\n                .AppendArgument(GetCustomMsBuildArguments(buildPartition.RepresentativeBenchmarkCase, buildPartition.Resolver))\n                .AppendArgument(extraArguments)\n                .AppendArgument(GetMandatoryMsBuildSettings(buildPartition.BuildConfiguration))\n                .AppendArgument(artifactsPaths.PackagesDirectoryName.IsBlank() ? string.Empty : $\"/p:NuGetPackageRoot=\\\"{artifactsPaths.PackagesDirectoryName}\\\"\")\n                .AppendArgument(GetMsBuildBinLogArgument(buildPartition, binLogSuffix))\n                .MaybeAppendOutputPaths(artifactsPaths)\n                .ToString();\n\n        private static string GetMsBuildBinLogArgument(BuildPartition buildPartition, string? suffix)\n        {\n            if (!buildPartition.GenerateMSBuildBinLog || suffix.IsBlank())\n                return string.Empty;\n\n            return $\"\\\"-bl:{buildPartition.ProgramName}-{suffix}.binlog\\\"\";\n        }\n\n        private static string GetCustomMsBuildArguments(BenchmarkCase benchmarkCase, IResolver resolver)\n        {\n            if (!benchmarkCase.Job.HasValue(InfrastructureMode.ArgumentsCharacteristic))\n                return \"\";\n\n            var msBuildArguments = benchmarkCase.Job.ResolveValue(InfrastructureMode.ArgumentsCharacteristic, resolver)!.OfType<MsBuildArgument>();\n\n            return string.Join(\" \", msBuildArguments.Select(arg => arg.TextRepresentation));\n        }\n\n        private static string GetMandatoryMsBuildSettings(string buildConfiguration)\n        {\n            // we use these settings to make sure that MSBuild does the job and simply quits without spawning any long living processes\n            // we want to avoid \"file in use\" and \"zombie processes\" issues\n            const string NoMsBuildZombieProcesses = \"--nodeReuse:false /p:UseSharedCompilation=false /p:Deterministic=true\";\n            const string EnforceOptimizations = \"/p:Optimize=true\";\n\n            if (string.Equals(buildConfiguration, RuntimeInformation.DebugConfigurationName, StringComparison.OrdinalIgnoreCase))\n            {\n                return NoMsBuildZombieProcesses;\n            }\n\n            return $\"{NoMsBuildZombieProcesses} {EnforceOptimizations}\";\n        }\n    }\n\n    internal static class DotNetCliCommandExtensions\n    {\n        // Fix #1377 (see comments in #1773).\n        // We force the project to output binaries to a new directory.\n        // Specifying --output and --no-dependencies breaks the build (because the previous build was not done using the custom output path),\n        // so we don't include it if we're building no-deps (only supported for integration tests).\n        internal static StringBuilder MaybeAppendOutputPaths(this StringBuilder stringBuilder, ArtifactsPaths artifactsPaths, bool isRestore = false, bool excludeOutput = false)\n            => excludeOutput\n                ? stringBuilder\n                : stringBuilder\n                    // Use AltDirectorySeparatorChar so it's not interpreted as an escaped quote `\\\"`.\n                    // Use a subdirectory for ArtifactsPath so that DefaultItemExcludes (which the SDK\n                    // sets to $(ArtifactsPath)/**) doesn't cover project-level files like wwwroot/.\n                    .AppendArgument($\"/p:ArtifactsPath=\\\"{artifactsPaths.BuildArtifactsDirectoryPath}{Path.AltDirectorySeparatorChar}.artifacts{Path.AltDirectorySeparatorChar}\\\"\")\n                    .AppendArgument($\"/p:OutDir=\\\"{artifactsPaths.BinariesDirectoryPath}{Path.AltDirectorySeparatorChar}\\\"\")\n                    // OutputPath is legacy, per-project version of OutDir. We set both just in case. https://github.com/dotnet/msbuild/issues/87\n                    .AppendArgument($\"/p:OutputPath=\\\"{artifactsPaths.BinariesDirectoryPath}{Path.AltDirectorySeparatorChar}\\\"\")\n                    .AppendArgument($\"/p:PublishDir=\\\"{artifactsPaths.PublishDirectoryPath}{Path.AltDirectorySeparatorChar}\\\"\")\n                    .AppendArgument(isRestore ? string.Empty : $\"--output \\\"{artifactsPaths.BinariesDirectoryPath}{Path.AltDirectorySeparatorChar}\\\"\");\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/DotNetCli/DotNetCliCommandExecutor.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Text;\nusing System.Text.RegularExpressions;\nusing BenchmarkDotNet.Detectors;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Helpers;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Portability;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Toolchains.Results;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Toolchains.DotNetCli\n{\n    [PublicAPI]\n    public static class DotNetCliCommandExecutor\n    {\n        internal static readonly Lazy<string> DefaultDotNetCliPath = new Lazy<string>(GetDefaultDotNetCliPath);\n\n        [PublicAPI]\n        public static DotNetCliCommandResult Execute(DotNetCliCommand parameters)\n        {\n            using (var process = new Process { StartInfo = BuildStartInfo(parameters.CliPath, parameters.GenerateResult.ArtifactsPaths.BuildArtifactsDirectoryPath, parameters.Arguments, parameters.EnvironmentVariables) })\n            using (var outputReader = new AsyncProcessOutputReader(process, parameters.LogOutput, parameters.Logger))\n            using (new ConsoleExitHandler(process, parameters.Logger))\n            {\n                parameters.Logger.WriteLineInfo($\"// start {process.StartInfo.FileName} {process.StartInfo.Arguments} in {process.StartInfo.WorkingDirectory}\");\n\n                var stopwatch = Stopwatch.StartNew();\n\n                process.Start();\n                outputReader.BeginRead();\n\n                if (!process.WaitForExit((int)parameters.Timeout.TotalMilliseconds))\n                {\n                    parameters.Logger.WriteLineError($\"// command took longer than the timeout: {parameters.Timeout.TotalSeconds:0.##}s. Killing the process tree!\");\n\n                    outputReader.CancelRead();\n                    process.KillTree();\n\n                    return DotNetCliCommandResult.Failure(stopwatch.Elapsed, $\"The configured timeout {parameters.Timeout} was reached!\" + outputReader.GetErrorText(), outputReader.GetOutputText());\n                }\n\n                stopwatch.Stop();\n                outputReader.StopRead();\n\n                parameters.Logger.WriteLineInfo($\"// command took {stopwatch.Elapsed.TotalSeconds.ToInvariantString(\"0.##\")} sec and exited with {process.ExitCode}\");\n\n                return process.ExitCode <= 0\n                    ? DotNetCliCommandResult.Success(stopwatch.Elapsed, outputReader.GetOutputText())\n                    : DotNetCliCommandResult.Failure(stopwatch.Elapsed, outputReader.GetOutputText(), outputReader.GetErrorText());\n            }\n        }\n\n        internal static string GetDotNetSdkVersion()\n        {\n            using (var process = new Process { StartInfo = BuildStartInfo(customDotNetCliPath: null, workingDirectory: string.Empty, arguments: \"--version\", redirectStandardError: false) })\n            using (new ConsoleExitHandler(process, NullLogger.Instance))\n            {\n                try\n                {\n                    process.Start();\n                }\n                catch (Win32Exception) // dotnet cli is not installed\n                {\n                    return \"\";\n                }\n\n                string output = process.StandardOutput.ReadToEnd();\n\n                process.WaitForExit();\n\n                // first line contains something like \".NET Command Line Tools (1.0.0-beta-001603)\"\n                return Regex.Split(output, Environment.NewLine, RegexOptions.Compiled)\n                    .FirstOrDefault(line => line.IsNotBlank()) ?? \"\";\n            }\n        }\n\n        internal static void LogEnvVars(DotNetCliCommand command)\n        {\n            if (!command.LogOutput)\n            {\n                return;\n            }\n\n            ProcessStartInfo startInfo = BuildStartInfo(\n                command.CliPath, command.GenerateResult.ArtifactsPaths.BuildArtifactsDirectoryPath, command.Arguments, command.EnvironmentVariables);\n\n            if (startInfo.EnvironmentVariables.Keys.Count > 0)\n            {\n                command.Logger.WriteLineInfo(\"// Environment Variables:\");\n                foreach (string name in startInfo.EnvironmentVariables.Keys)\n                {\n                    command.Logger.WriteLine($\"\\t[{name}] = \\\"{startInfo.EnvironmentVariables[name]}\\\"\");\n                }\n            }\n        }\n\n        internal static ProcessStartInfo BuildStartInfo(string? customDotNetCliPath, string workingDirectory, string arguments,\n            IReadOnlyList<EnvironmentVariable>? environmentVariables = null, bool redirectStandardInput = false, bool redirectStandardError = true, bool redirectStandardOutput = true)\n        {\n            const string dotnetMultiLevelLookupEnvVarName = \"DOTNET_MULTILEVEL_LOOKUP\";\n\n            var startInfo = new ProcessStartInfo\n            {\n                FileName = customDotNetCliPath.IsBlank() ? DefaultDotNetCliPath.Value : customDotNetCliPath,\n                WorkingDirectory = workingDirectory,\n                Arguments = arguments,\n                UseShellExecute = false,\n                CreateNoWindow = true,\n                RedirectStandardOutput = redirectStandardOutput,\n                RedirectStandardError = redirectStandardError,\n                RedirectStandardInput = redirectStandardInput,\n            };\n\n            if (redirectStandardOutput)\n            {\n                startInfo.StandardOutputEncoding = Encoding.UTF8;\n            }\n\n            if (redirectStandardError) // StandardErrorEncoding is only supported when standard error is redirected\n            {\n                startInfo.StandardErrorEncoding = Encoding.UTF8;\n            }\n\n            if (environmentVariables != null)\n                foreach (var environmentVariable in environmentVariables)\n                    startInfo.EnvironmentVariables[environmentVariable.Key] = environmentVariable.Value;\n\n            if (customDotNetCliPath.IsNotBlank() && (environmentVariables == null || environmentVariables.All(envVar => envVar.Key != dotnetMultiLevelLookupEnvVarName)))\n                startInfo.EnvironmentVariables[dotnetMultiLevelLookupEnvVarName] = \"0\";\n\n            return startInfo;\n        }\n\n        private static string GetDefaultDotNetCliPath()\n        {\n            if (!OsDetector.IsLinux())\n                return \"dotnet\";\n\n            using (var parentProcess = Process.GetProcessById(libc.getppid()))\n            {\n                string parentPath = parentProcess.MainModule?.FileName ?? string.Empty;\n                // sth like /snap/dotnet-sdk/112/dotnet and we should use the exact path instead of just \"dotnet\"\n                if (parentPath.StartsWith(\"/snap/\", StringComparison.Ordinal) &&\n                    parentPath.EndsWith(\"/dotnet\", StringComparison.Ordinal))\n                {\n                    return parentPath;\n                }\n\n                return \"dotnet\";\n            }\n        }\n\n        internal static string GetSdkPath(string cliPath)\n        {\n            DotNetCliCommand cliCommand = new(\n                cliPath: cliPath,\n                filePath: string.Empty,\n                tfm: string.Empty,\n                arguments: \"--info\",\n                generateResult: GenerateResult.Success(ArtifactsPaths.Empty, []),\n                logger: NullLogger.Instance,\n                buildPartition: BuildPartition.Empty,\n                environmentVariables: [],\n                timeout: TimeSpan.FromMinutes(1),\n                logOutput: false);\n\n            string sdkPath = Execute(cliCommand)\n                .StandardOutput.Split([Environment.NewLine], StringSplitOptions.RemoveEmptyEntries)\n                .Where(line => line.EndsWith(\"/sdk]\")) // sth like \"  3.1.423 [/usr/share/dotnet/sdk]\n                .Select(line => line.Split('[')[1])\n                .Distinct()\n                .Single(); // I assume there will be only one such folder\n\n            return sdkPath.Substring(0, sdkPath.Length - 1); // remove trailing `]`\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/DotNetCli/DotNetCliCommandResult.cs",
    "content": "using System;\nusing System.IO;\nusing BenchmarkDotNet.Toolchains.Results;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Toolchains.DotNetCli\n{\n    public struct DotNetCliCommandResult\n    {\n        [PublicAPI] public bool IsSuccess { get; }\n\n        [PublicAPI] public TimeSpan ExecutionTime { get; }\n\n        [PublicAPI] public string StandardOutput { get; }\n\n        [PublicAPI] public string StandardError { get; }\n\n        public string AllInformation => $\"Standard output: {Environment.NewLine} {StandardOutput} {Environment.NewLine} Standard error: {Environment.NewLine} {StandardError}\";\n\n        [PublicAPI] public bool HasNonEmptyErrorMessage => !string.IsNullOrEmpty(StandardError);\n\n        private DotNetCliCommandResult(bool isSuccess, TimeSpan executionTime, string standardOutput, string standardError)\n        {\n            IsSuccess = isSuccess;\n            ExecutionTime = executionTime;\n            StandardOutput = standardOutput;\n            StandardError = standardError;\n        }\n\n        public static DotNetCliCommandResult Success(TimeSpan time, string standardOutput)\n            => new DotNetCliCommandResult(true, time, standardOutput, string.Empty);\n\n        public static DotNetCliCommandResult Failure(TimeSpan time, string standardError, string standardOutput)\n            => new DotNetCliCommandResult(false, time, standardOutput, standardError);\n\n        [PublicAPI]\n        public BuildResult ToBuildResult(GenerateResult generateResult)\n            => IsSuccess\n                ? BuildResult.Success(generateResult)\n                : BuildResult.Failure(generateResult, AllInformation);\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/DotNetCli/DotNetCliExecutor.cs",
    "content": "using System.Collections.Generic;\nusing System.Diagnostics;\nusing System.IO;\nusing System.IO.Pipes;\nusing BenchmarkDotNet.Characteristics;\nusing BenchmarkDotNet.Diagnosers;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Helpers;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Toolchains.Parameters;\nusing BenchmarkDotNet.Toolchains.Results;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Toolchains.DotNetCli\n{\n    [PublicAPI]\n    public class DotNetCliExecutor : IExecutor\n    {\n        public DotNetCliExecutor(string customDotNetCliPath) => CustomDotNetCliPath = customDotNetCliPath;\n\n        private string CustomDotNetCliPath { get; }\n\n        public ExecuteResult Execute(ExecuteParameters executeParameters)\n        {\n            if (!File.Exists(executeParameters.BuildResult.ArtifactsPaths.ExecutablePath))\n            {\n                executeParameters.Logger.WriteLineError($\"Did not find {executeParameters.BuildResult.ArtifactsPaths.ExecutablePath}, but the folder contained:\");\n                foreach (var file in new DirectoryInfo(executeParameters.BuildResult.ArtifactsPaths.BinariesDirectoryPath).GetFiles(\"*.*\"))\n                    executeParameters.Logger.WriteLineError(file.Name);\n\n                return ExecuteResult.CreateFailed();\n            }\n\n            try\n            {\n                return Execute(\n                    executeParameters.BenchmarkCase,\n                    executeParameters.BenchmarkId,\n                    executeParameters.Logger,\n                    executeParameters.BuildResult.ArtifactsPaths,\n                    executeParameters.Diagnoser,\n                    executeParameters.CompositeInProcessDiagnoser,\n                    Path.GetFileName(executeParameters.BuildResult.ArtifactsPaths.ExecutablePath),\n                    executeParameters.Resolver,\n                    executeParameters.LaunchIndex,\n                    executeParameters.DiagnoserRunMode);\n            }\n            finally\n            {\n                executeParameters.Diagnoser?.Handle(\n                    HostSignal.AfterProcessExit,\n                    new DiagnoserActionParameters(null, executeParameters.BenchmarkCase, executeParameters.BenchmarkId));\n            }\n        }\n\n        private ExecuteResult Execute(BenchmarkCase benchmarkCase,\n                                      BenchmarkId benchmarkId,\n                                      ILogger logger,\n                                      ArtifactsPaths artifactsPaths,\n                                      IDiagnoser? diagnoser,\n                                      CompositeInProcessDiagnoser compositeInProcessDiagnoser,\n                                      string executableName,\n                                      IResolver resolver,\n                                      int launchIndex,\n                                      Diagnosers.RunMode diagnoserRunMode)\n        {\n            using AnonymousPipeServerStream inputFromBenchmark = new AnonymousPipeServerStream(PipeDirection.In, HandleInheritability.Inheritable);\n            using AnonymousPipeServerStream acknowledgments = new AnonymousPipeServerStream(PipeDirection.Out, HandleInheritability.Inheritable);\n\n            var startInfo = DotNetCliCommandExecutor.BuildStartInfo(\n                CustomDotNetCliPath,\n                artifactsPaths.BinariesDirectoryPath,\n                $\"{executableName.EscapeCommandLine()} {benchmarkId.ToArguments(inputFromBenchmark.GetClientHandleAsString(), acknowledgments.GetClientHandleAsString(), diagnoserRunMode)}\",\n                redirectStandardOutput: true,\n                redirectStandardInput: false,\n                redirectStandardError: false); // #1629\n\n            startInfo.SetEnvironmentVariables(benchmarkCase, resolver);\n\n            using Process process = new() { StartInfo = startInfo };\n            using ConsoleExitHandler consoleExitHandler = new(process, logger);\n            using AsyncProcessOutputReader processOutputReader = new(process, logOutput: true, logger, readStandardError: false);\n\n            List<string> results;\n            List<string> prefixedOutput;\n            using (Broker broker = new(logger, process, diagnoser, compositeInProcessDiagnoser, benchmarkCase, benchmarkId, inputFromBenchmark, acknowledgments))\n            {\n                logger.WriteLineInfo($\"// Execute: {process.StartInfo.FileName} {process.StartInfo.Arguments} in {process.StartInfo.WorkingDirectory}\");\n\n                diagnoser?.Handle(HostSignal.BeforeProcessStart, broker.DiagnoserActionParameters);\n\n                process.Start();\n\n                diagnoser?.Handle(HostSignal.AfterProcessStart, broker.DiagnoserActionParameters);\n\n                processOutputReader.BeginRead();\n\n                process.EnsureHighPriority(logger);\n                if (benchmarkCase.Job.Environment.HasValue(EnvironmentMode.AffinityCharacteristic))\n                {\n                    process.TrySetAffinity(benchmarkCase.Job.Environment.Affinity, logger);\n                }\n\n                broker.ProcessData();\n\n                results = broker.Results;\n                prefixedOutput = broker.PrefixedOutput;\n            }\n\n            if (!process.WaitForExit(milliseconds: (int) ExecuteParameters.ProcessExitTimeout.TotalMilliseconds))\n            {\n                logger.WriteLineInfo($\"// The benchmarking process did not quit within {ExecuteParameters.ProcessExitTimeout.TotalSeconds} seconds, it's going to get force killed now.\");\n\n                processOutputReader.CancelRead();\n                consoleExitHandler.KillProcessTree();\n            }\n            else\n            {\n                processOutputReader.StopRead();\n            }\n\n            return new ExecuteResult(true,\n                process.HasExited ? process.ExitCode : null,\n                process.Id,\n                results,\n                prefixedOutput,\n                processOutputReader.GetOutputLines(),\n                launchIndex);\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/DotNetCli/DotNetCliGenerator.cs",
    "content": "﻿using System;\nusing System.Diagnostics.CodeAnalysis;\nusing System.IO;\nusing System.Linq;\nusing System.Text;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Running;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Toolchains.DotNetCli\n{\n    [PublicAPI]\n    public abstract class DotNetCliGenerator : GeneratorBase\n    {\n        private static readonly string[] ProjectExtensions = [\".csproj\", \".fsproj\", \".vbroj\"];\n\n        private static readonly string[] SolutionExtensions = [\".sln\", \".slnx\"];\n\n        [PublicAPI] public string TargetFrameworkMoniker { get; }\n\n        [PublicAPI] public string CliPath { get; }\n\n        [PublicAPI] public string PackagesPath { get; }\n\n        protected bool IsNetCore { get; }\n\n        [PublicAPI]\n        protected DotNetCliGenerator(string targetFrameworkMoniker, string cliPath, string packagesPath, bool isNetCore)\n        {\n            TargetFrameworkMoniker = targetFrameworkMoniker;\n            CliPath = cliPath.IsBlank() ? \"dotnet\" : cliPath;\n            PackagesPath = packagesPath.EnsureNotNull();\n            IsNetCore = isNetCore;\n        }\n\n        protected override string GetExecutableExtension() => IsNetCore ? \".dll\" : \".exe\";\n\n        /// <summary>\n        /// we need our folder to be on the same level as the project that we want to reference\n        /// we are limited by xprojs (by default compiles all .cs files in all subfolders, Program.cs could be doubled and fail the build)\n        /// and also by NuGet internal implementation like looking for global.json file in parent folders\n        /// </summary>\n        protected override string GetBuildArtifactsDirectoryPath(BuildPartition buildPartition, string programName)\n        {\n            if (GetSolutionRootDirectory(out var directoryInfo))\n            {\n                return Path.Combine(directoryInfo.FullName, programName);\n            }\n\n            // we did not find global.json or any Visual Studio solution file?\n            // let's return it in the old way and hope that it works ;)\n            var parent = new DirectoryInfo(Directory.GetCurrentDirectory()).Parent;\n            if (parent == null)\n                throw new DirectoryNotFoundException(\"Parent directory for current directory\");\n            return Path.Combine(parent.FullName, programName);\n        }\n\n        internal static bool GetSolutionRootDirectory([NotNullWhen(true)] out DirectoryInfo? directoryInfo)\n        {\n            return GetRootDirectory(IsRootSolutionFolder, out directoryInfo);\n        }\n\n        internal static bool GetProjectRootDirectory([NotNullWhen(true)] out DirectoryInfo? directoryInfo)\n        {\n            return GetRootDirectory(IsRootProjectFolder, out directoryInfo);\n        }\n\n        internal static bool GetRootDirectory(Func<DirectoryInfo, bool> condition, [NotNullWhen(true)] out DirectoryInfo? directoryInfo)\n        {\n            directoryInfo = null;\n            try\n            {\n                directoryInfo = new DirectoryInfo(Directory.GetCurrentDirectory());\n                while (directoryInfo != null)\n                {\n                    if (condition(directoryInfo))\n                    {\n                        return true;\n                    }\n\n                    directoryInfo = directoryInfo.Parent;\n                }\n            }\n            catch\n            {\n                return false;\n            }\n\n            return false;\n        }\n\n        protected override string[] GetArtifactsToCleanup(ArtifactsPaths artifactsPaths)\n            => [artifactsPaths.BuildArtifactsDirectoryPath];\n\n        protected override void CopyAllRequiredFiles(ArtifactsPaths artifactsPaths)\n        {\n            if (!Directory.Exists(artifactsPaths.BinariesDirectoryPath))\n            {\n                Directory.CreateDirectory(artifactsPaths.BinariesDirectoryPath);\n            }\n        }\n\n        protected override string GetPackagesDirectoryPath(string buildArtifactsDirectoryPath) => PackagesPath;\n\n        protected override void GenerateBuildScript(BuildPartition buildPartition, ArtifactsPaths artifactsPaths)\n        {\n            var content = new StringBuilder(300)\n                .AppendLine($\"call {CliPath} {DotNetCliCommand.GetRestoreCommand(artifactsPaths, buildPartition, artifactsPaths.ProjectFilePath)}\")\n                .AppendLine($\"call {CliPath} {DotNetCliCommand.GetBuildCommand(artifactsPaths, buildPartition, artifactsPaths.ProjectFilePath, TargetFrameworkMoniker)}\")\n                .ToString();\n\n            File.WriteAllText(artifactsPaths.BuildScriptFilePath, content);\n        }\n\n        private static bool IsRootSolutionFolder(DirectoryInfo directoryInfo)\n            => directoryInfo\n                .GetFileSystemInfos()\n                .Any(fileInfo => SolutionExtensions.Contains(fileInfo.Extension) || fileInfo.Name == \"global.json\");\n\n        private static bool IsRootProjectFolder(DirectoryInfo directoryInfo)\n            => directoryInfo\n                .GetFileSystemInfos()\n                .Any(fileInfo => ProjectExtensions.Contains(fileInfo.Extension));\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/DotNetCli/DotNetCliPublisher.cs",
    "content": "using System.Collections.Generic;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Toolchains.Results;\n\nnamespace BenchmarkDotNet.Toolchains.DotNetCli;\n\npublic class DotNetCliPublisher : IBuilder\n{\n    public string TargetFrameworkMoniker { get; }\n    public string CustomDotNetCliPath { get; }\n    public string ExtraArguments { get; }\n    public IReadOnlyList<EnvironmentVariable> EnvironmentVariables { get; }\n    public bool LogOutput{ get; }\n\n    public DotNetCliPublisher(\n        string tfm,\n        string customDotNetCliPath = \"\",\n        string extraArguments = \"\",\n        IReadOnlyList<EnvironmentVariable>? environmentVariables = null,\n        bool logOutput = false)\n    {\n        TargetFrameworkMoniker = tfm;\n        CustomDotNetCliPath = customDotNetCliPath.EnsureNotNull();\n        ExtraArguments = extraArguments.EnsureNotNull();\n        EnvironmentVariables = environmentVariables ?? [];\n        LogOutput = logOutput;\n    }\n\n    public virtual BuildResult Build(GenerateResult generateResult, BuildPartition buildPartition, ILogger logger)\n        => new DotNetCliCommand(\n            CustomDotNetCliPath,\n            generateResult.ArtifactsPaths.ProjectFilePath,\n            TargetFrameworkMoniker,\n            ExtraArguments,\n            generateResult,\n            logger,\n            buildPartition,\n            EnvironmentVariables,\n            buildPartition.Timeout,\n            logOutput: LogOutput\n        ).RestoreThenBuildThenPublish();\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/DotNetCli/MsBuildErrorMapper.cs",
    "content": "﻿using BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Toolchains.Results;\nusing System;\nusing System.Diagnostics.CodeAnalysis;\nusing System.Linq;\nusing System.Text.RegularExpressions;\n\nnamespace BenchmarkDotNet.Toolchains.DotNetCli\n{\n    internal static class MsBuildErrorMapper\n    {\n        private static readonly (Regex regex, Func<Match, string> translation)[] Rules =\n        [\n            (\n                new Regex(\"warning NU1702: ProjectReference '(.*)' was resolved using '(.*)' instead of the project target framework '(.*)'. This project may not be fully compatible with your project.\",\n                    RegexOptions.CultureInvariant | RegexOptions.Compiled),\n                match => $@\"The project which defines benchmarks does not target '{Map(match.Groups[3])}'.\" + Environment.NewLine +\n                    $\"You need to add '{Map(match.Groups[3])}' to <TargetFrameworks> in your project file ('{match.Groups[1]}').\" + Environment.NewLine +\n                    $\"Example: <TargetFrameworks>{Map(match.Groups[2])};{Map(match.Groups[3])}</TargetFrameworks>\"\n            ),\n            (\n                new Regex(\"error NU1201: Project (.*) is not compatible with (.*) ((.*)) / (.*). Project (.*) supports: (.*) ((.*))\",\n                    RegexOptions.CultureInvariant | RegexOptions.Compiled),\n                match => $@\"The project which defines benchmarks does not target '{Map(match.Groups[2])}'.\" + Environment.NewLine +\n                    $\"You need to add '{Map(match.Groups[2])}' to <TargetFrameworks> in your project file ('{match.Groups[1]}').\" + Environment.NewLine +\n                    $\"Example: <TargetFrameworks>{Map(match.Groups[7])};{Map(match.Groups[2])}</TargetFrameworks>\"\n            ),\n            (\n                new Regex(\"error NETSDK1045: The current .NET SDK does not support targeting (.*).  Either target (.*) or lower, or use a version of the .NET SDK that supports (.*).\",\n                    RegexOptions.CultureInvariant | RegexOptions.Compiled),\n                match => $\"The current .NET SDK does not support targeting {match.Groups[1]}. You need to install it or pass the path to dotnet cli via the `--cli` console line argument.\"\n            ),\n        ];\n\n        internal static bool TryToExplainFailureReason(BuildResult buildResult, [NotNullWhen(true)] out string? reason)\n        {\n            reason = null;\n\n            if (buildResult.IsBuildSuccess || buildResult.ErrorMessage.IsBlank())\n            {\n                return false;\n            }\n\n            foreach (var errorLine in buildResult.ErrorMessage.Split('\\r', '\\n').Where(line => line.IsNotBlank()))\n            foreach (var rule in Rules)\n            {\n                var match = rule.regex.Match(errorLine);\n                if (match.Success)\n                {\n                    reason = rule.translation(match);\n                    return true;\n                }\n            }\n\n            return false;\n        }\n\n        private static string Map(Capture capture)\n        {\n            switch (capture.Value)\n            {\n                case \".NETFramework,Version=v4.6.1\":\n                    return \"net461\";\n                case \".NETFramework,Version=v4.6.2\":\n                    return \"net462\";\n                case \".NETFramework,Version=v4.7\":\n                    return \"net47\";\n                case \".NETFramework,Version=v4.7.1\":\n                    return \"net471\";\n                case \".NETFramework,Version=v4.7.2\":\n                    return \"net472\";\n                case \".NETFramework,Version=v4.8\":\n                    return \"net48\";\n                case \".NETFramework,Version=v4.8.1\":\n                    return \"net481\";\n                case \".NETCoreApp,Version=v2.0\":\n                    return \"netcoreapp2.0\";\n                case \".NETCoreApp,Version=v2.1\":\n                    return \"netcoreapp2.1\";\n                case \".NETCoreApp,Version=v2.2\":\n                    return \"netcoreapp2.2\";\n                case \".NETCoreApp,Version=v3.0\":\n                    return \"netcoreapp3.0\";\n                case \".NETCoreApp,Version=v3.1\":\n                    return \"netcoreapp3.1\";\n                case \".NETCoreApp,Version=v5.0\":\n                    return \"net5.0\";\n                case \".NETCoreApp,Version=v6.0\":\n                    return \"net6.0\";\n                case \".NETCoreApp,Version=v7.0\":\n                    return \"net7.0\";\n                case \".NETCoreApp,Version=v8.0\":\n                    return \"net8.0\";\n                case \".NETCoreApp,Version=v9.0\":\n                    return \"net9.0\";\n                case \".NETCoreApp,Version=v10.0\":\n                    return \"net10.0\";\n                case \".NETCoreApp,Version=v11.0\":\n                    return \"net11.0\";\n                default:\n                    return capture.Value; // we don't want to throw for future versions of .NET\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/DotNetCli/NetCoreAppSettings.cs",
    "content": "using BenchmarkDotNet.ConsoleArguments;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Toolchains.MonoAotLLVM;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Toolchains.DotNetCli\n{\n    /// <summary>\n    /// custom settings used in the auto-generated project.json / .csproj file\n    /// </summary>\n    [PublicAPI]\n    public class NetCoreAppSettings\n    {\n        [PublicAPI] public static readonly NetCoreAppSettings NetCoreApp20 = new(\"netcoreapp2.0\", \".NET Core 2.0\");\n        [PublicAPI] public static readonly NetCoreAppSettings NetCoreApp21 = new(\"netcoreapp2.1\", \".NET Core 2.1\");\n        [PublicAPI] public static readonly NetCoreAppSettings NetCoreApp22 = new(\"netcoreapp2.2\", \".NET Core 2.2\");\n        [PublicAPI] public static readonly NetCoreAppSettings NetCoreApp30 = new(\"netcoreapp3.0\", \".NET Core 3.0\");\n        [PublicAPI] public static readonly NetCoreAppSettings NetCoreApp31 = new(\"netcoreapp3.1\", \".NET Core 3.1\");\n        [PublicAPI] public static readonly NetCoreAppSettings NetCoreApp50 = new(\"net5.0\", \".NET 5.0\");\n        [PublicAPI] public static readonly NetCoreAppSettings NetCoreApp60 = new(\"net6.0\", \".NET 6.0\");\n        [PublicAPI] public static readonly NetCoreAppSettings NetCoreApp70 = new(\"net7.0\", \".NET 7.0\");\n        [PublicAPI] public static readonly NetCoreAppSettings NetCoreApp80 = new(\"net8.0\", \".NET 8.0\");\n        [PublicAPI] public static readonly NetCoreAppSettings NetCoreApp90 = new(\"net9.0\", \".NET 9.0\");\n        [PublicAPI] public static readonly NetCoreAppSettings NetCoreApp10_0 = new(\"net10.0\", \".NET 10.0\");\n        [PublicAPI] public static readonly NetCoreAppSettings NetCoreApp11_0 = new(\"net11.0\", \".NET 11.0\");\n\n        /// <summary>\n        /// <param name=\"targetFrameworkMoniker\">\n        /// sample values: net6.0, net8.0\n        /// </param>\n        /// <param name=\"runtimeFrameworkVersion\">\n        /// used in the auto-generated .csproj file\n        /// simply ignored if null or empty\n        /// </param>\n        /// <param name=\"name\">\n        /// display name used for showing the results\n        /// </param>\n        /// <param name=\"customDotNetCliPath\">\n        /// customize dotnet cli path if default is not desired\n        /// simply ignored if null or empty\n        /// </param>\n        /// <param name=\"packagesPath\">the directory to restore packages to</param>\n        /// <param name=\"customRuntimePack\">path to a custom runtime pack</param>\n        /// <param name=\"aotCompilerPath\">path to Mono AOT compiler</param>\n        /// <param name=\"aotCompilerMode\">Mono AOT compiler moder</param>\n        /// </summary>\n        [PublicAPI]\n        public NetCoreAppSettings(\n            string targetFrameworkMoniker,\n            string runtimeFrameworkVersion,\n            string name,\n            string customDotNetCliPath = \"\",\n            string packagesPath = \"\",\n            string customRuntimePack = \"\",\n            string aotCompilerPath = \"\",\n            MonoAotCompilerMode aotCompilerMode = MonoAotCompilerMode.mini\n            )\n        {\n            TargetFrameworkMoniker = targetFrameworkMoniker;\n            RuntimeFrameworkVersion = runtimeFrameworkVersion.EnsureNotNull();\n            Name = name;\n\n            CustomDotNetCliPath = customDotNetCliPath.EnsureNotNull();\n            PackagesPath = packagesPath.EnsureNotNull();\n            CustomRuntimePack = customRuntimePack.EnsureNotNull();\n            AOTCompilerPath = aotCompilerPath.EnsureNotNull();\n            AOTCompilerMode = aotCompilerMode;\n        }\n\n        /// <summary>\n        /// Internal constructor that accept CommandLineOptions\n        /// </summary>\n        internal NetCoreAppSettings(\n            string targetFrameworkMoniker,\n            string runtimeFrameworkVersion,\n            string name,\n            CommandLineOptions options)\n            : this(\n                 targetFrameworkMoniker,\n                 runtimeFrameworkVersion: runtimeFrameworkVersion,\n                 name: name,\n                 customDotNetCliPath: options.CliPath?.FullName ?? \"\",\n                 packagesPath: options.RestorePath?.FullName ?? \"\",\n                 customRuntimePack: options.CustomRuntimePack ?? \"\",\n                 aotCompilerPath: options.AOTCompilerPath?.ToString() ?? \"\",\n                 aotCompilerMode: options.AOTCompilerMode)\n        {\n        }\n\n        internal NetCoreAppSettings(string targetFrameworkMoniker, string name)\n            : this(targetFrameworkMoniker, runtimeFrameworkVersion: \"\", name)\n        {\n        }\n\n        /// <summary>\n        /// sample values: net6.0, net8.0\n        /// </summary>\n        public string TargetFrameworkMoniker { get; }\n\n        public string RuntimeFrameworkVersion { get; }\n\n        /// <summary>\n        /// display name used for showing the results\n        /// </summary>\n        public string Name { get; }\n\n        public string CustomDotNetCliPath { get; }\n\n        /// <summary>\n        /// The directory to restore packages to.\n        /// </summary>\n        public string PackagesPath { get; }\n\n        /// <summary>\n        /// Path to a custom runtime pack.\n        /// </summary>\n        public string CustomRuntimePack { get; }\n\n        /// <summary>\n        /// Path to the Mono AOT Compiler\n        /// </summary>\n        public string AOTCompilerPath { get; }\n\n        /// <summary>\n        /// Mono AOT Compiler mode, either 'mini' or 'llvm'\n        /// </summary>\n        public MonoAotCompilerMode AOTCompilerMode { get; }\n\n        public NetCoreAppSettings WithCustomDotNetCliPath(string customDotNetCliPath, string? displayName = null)\n            => new NetCoreAppSettings(TargetFrameworkMoniker, RuntimeFrameworkVersion, displayName ?? Name, customDotNetCliPath, PackagesPath);\n\n        public NetCoreAppSettings WithCustomPackagesRestorePath(string packagesPath, string? displayName = null)\n            => new NetCoreAppSettings(TargetFrameworkMoniker, RuntimeFrameworkVersion, displayName ?? Name, CustomDotNetCliPath, packagesPath);\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/Executor.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Diagnostics;\nusing System.IO;\nusing System.IO.Pipes;\nusing System.Linq;\nusing System.Text;\nusing BenchmarkDotNet.Characteristics;\nusing BenchmarkDotNet.Diagnosers;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Helpers;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Toolchains.Parameters;\nusing BenchmarkDotNet.Toolchains.Results;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Toolchains\n{\n    [PublicAPI(\"Used by some of our Superusers that implement their own Toolchains (e.g. Kestrel team)\")]\n    public class Executor : IExecutor\n    {\n        public ExecuteResult Execute(ExecuteParameters executeParameters)\n        {\n            string exePath = executeParameters.BuildResult.ArtifactsPaths.ExecutablePath;\n\n            if (!File.Exists(exePath))\n            {\n                return ExecuteResult.CreateFailed();\n            }\n\n            return Execute(executeParameters.BenchmarkCase, executeParameters.BenchmarkId, executeParameters.Logger, executeParameters.BuildResult.ArtifactsPaths,\n                executeParameters.Diagnoser, executeParameters.CompositeInProcessDiagnoser, executeParameters.Resolver, executeParameters.LaunchIndex,\n                executeParameters.DiagnoserRunMode);\n        }\n\n        private static ExecuteResult Execute(BenchmarkCase benchmarkCase, BenchmarkId benchmarkId, ILogger logger, ArtifactsPaths artifactsPaths,\n            IDiagnoser? diagnoser, CompositeInProcessDiagnoser compositeInProcessDiagnoser, IResolver resolver, int launchIndex,\n            Diagnosers.RunMode diagnoserRunMode)\n        {\n            try\n            {\n                return ExecuteCore(benchmarkCase, benchmarkId, logger, artifactsPaths, diagnoser, compositeInProcessDiagnoser, resolver, launchIndex, diagnoserRunMode);\n            }\n            finally\n            {\n                diagnoser?.Handle(HostSignal.AfterProcessExit, new DiagnoserActionParameters(null, benchmarkCase, benchmarkId));\n            }\n        }\n\n        private static ExecuteResult ExecuteCore(BenchmarkCase benchmarkCase, BenchmarkId benchmarkId, ILogger logger, ArtifactsPaths artifactsPaths,\n            IDiagnoser? diagnoser, CompositeInProcessDiagnoser compositeInProcessDiagnoser, IResolver resolver, int launchIndex,\n            Diagnosers.RunMode diagnoserRunMode)\n        {\n            using AnonymousPipeServerStream inputFromBenchmark = new(PipeDirection.In, HandleInheritability.Inheritable);\n            using AnonymousPipeServerStream acknowledgments = new(PipeDirection.Out, HandleInheritability.Inheritable);\n\n            string args = benchmarkId.ToArguments(inputFromBenchmark.GetClientHandleAsString(), acknowledgments.GetClientHandleAsString(), diagnoserRunMode);\n\n            using Process process = new() { StartInfo = CreateStartInfo(benchmarkCase, artifactsPaths, args, resolver) };\n            using ConsoleExitHandler consoleExitHandler = new(process, logger);\n            using AsyncProcessOutputReader processOutputReader = new(process, logOutput: true, logger, readStandardError: false);\n\n            List<string> results;\n            List<string> prefixedOutput;\n            using (Broker broker = new(logger, process, diagnoser, compositeInProcessDiagnoser, benchmarkCase, benchmarkId, inputFromBenchmark, acknowledgments))\n            {\n                diagnoser?.Handle(HostSignal.BeforeProcessStart, new DiagnoserActionParameters(process, benchmarkCase, benchmarkId));\n\n                logger.WriteLineInfo($\"// Execute: {process.StartInfo.FileName} {process.StartInfo.Arguments} in {process.StartInfo.WorkingDirectory}\");\n\n                try\n                {\n                    process.Start();\n                }\n                catch (Win32Exception ex)\n                {\n                    logger.WriteLineError($\"// Failed to start the benchmark process: {ex}\");\n\n                    return new ExecuteResult(true, null, null, [], [], [], launchIndex);\n                }\n\n                broker.Diagnoser?.Handle(HostSignal.AfterProcessStart, broker.DiagnoserActionParameters);\n\n                processOutputReader.BeginRead();\n\n                process.EnsureHighPriority(logger);\n                if (benchmarkCase.Job.Environment.HasValue(EnvironmentMode.AffinityCharacteristic))\n                {\n                    process.TrySetAffinity(benchmarkCase.Job.Environment.Affinity, logger);\n                }\n\n                broker.ProcessData();\n\n                results = broker.Results;\n                prefixedOutput = broker.PrefixedOutput;\n            }\n\n            if (!process.WaitForExit(milliseconds: (int)ExecuteParameters.ProcessExitTimeout.TotalMilliseconds))\n            {\n                logger.WriteLineInfo(\"// The benchmarking process did not quit on time, it's going to get force killed now.\");\n\n                processOutputReader.CancelRead();\n                consoleExitHandler.KillProcessTree();\n            }\n            else\n            {\n                processOutputReader.StopRead();\n            }\n\n            if (results.Any(line => line.Contains(\"BadImageFormatException\")))\n                logger.WriteLineError(\"You are probably missing <PlatformTarget>AnyCPU</PlatformTarget> in your .csproj file.\");\n\n            return new ExecuteResult(true,\n                process.HasExited ? process.ExitCode : null,\n                process.Id,\n                results,\n                prefixedOutput,\n                processOutputReader.GetOutputLines(),\n                launchIndex);\n        }\n\n        private static ProcessStartInfo CreateStartInfo(BenchmarkCase benchmarkCase, ArtifactsPaths artifactsPaths, string args, IResolver resolver)\n        {\n            var start = new ProcessStartInfo\n            {\n                UseShellExecute = false,\n                RedirectStandardOutput = true,\n                RedirectStandardInput = false,\n                RedirectStandardError = false, // #1629\n                CreateNoWindow = true,\n                WorkingDirectory = null // by default it's null\n            };\n\n            start.SetEnvironmentVariables(benchmarkCase, resolver);\n\n            string exePath = artifactsPaths.ExecutablePath;\n\n            var runtime = benchmarkCase.GetRuntime();\n\n            switch (runtime)\n            {\n                case ClrRuntime _:\n                case CoreRuntime _:\n                case NativeAotRuntime _:\n                case R2RRuntime _:\n                    start.FileName = exePath;\n                    start.Arguments = args;\n                    break;\n                case MonoRuntime mono:\n                    start.FileName = mono.CustomPath.IsNotBlank() ? mono.CustomPath : \"mono\";\n                    start.Arguments = GetMonoArguments(benchmarkCase.Job, exePath, args, resolver);\n                    break;\n                case MonoAotLLVMRuntime _:\n                    start.FileName = exePath;\n                    start.Arguments = args;\n                    start.WorkingDirectory = Path.Combine(artifactsPaths.BinariesDirectoryPath, \"publish\");\n                    break;\n                case CustomRuntime _:\n                    start.FileName = exePath;\n                    start.Arguments = args;\n                    break;\n                default:\n                    throw new NotSupportedException(\"Runtime = \" + runtime);\n            }\n            return start;\n        }\n\n        private static string GetMonoArguments(Job job, string exePath, string args, IResolver resolver)\n        {\n            var arguments = job.HasValue(InfrastructureMode.ArgumentsCharacteristic)\n                ? job.ResolveValue(InfrastructureMode.ArgumentsCharacteristic, resolver)!.OfType<MonoArgument>().ToArray()\n                : [];\n\n            // from mono --help: \"Usage is: mono [options] program [program-options]\"\n            var builder = new StringBuilder(30);\n\n            builder.Append(job.ResolveValue(EnvironmentMode.JitCharacteristic, resolver) == Jit.Llvm ? \"--llvm\" : \"--nollvm\");\n\n            foreach (var argument in arguments)\n                builder.Append($\" {argument.TextRepresentation}\");\n\n            builder.Append($\" \\\"{exePath}\\\" \");\n            builder.Append(args);\n\n            return builder.ToString();\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/GeneratorBase.cs",
    "content": "﻿using System;\nusing System.IO;\nusing System.Text;\nusing BenchmarkDotNet.Code;\nusing BenchmarkDotNet.Detectors;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Toolchains.Results;\nusing JetBrains.Annotations;\nusing StreamWriter = System.IO.StreamWriter;\n\nnamespace BenchmarkDotNet.Toolchains\n{\n    [PublicAPI]\n    public abstract class GeneratorBase : IGenerator\n    {\n        /// <inheritdoc cref=\"CodeGenBenchmarkRunCallType\"/>\n        public CodeGenBenchmarkRunCallType BenchmarkRunCallType { get; init; }\n\n        public GenerateResult GenerateProject(BuildPartition buildPartition, ILogger logger, string rootArtifactsFolderPath)\n        {\n            var artifactsPaths = ArtifactsPaths.Empty;\n            try\n            {\n                artifactsPaths = GetArtifactsPaths(buildPartition, rootArtifactsFolderPath);\n\n                CopyAllRequiredFiles(artifactsPaths);\n\n                GenerateCode(buildPartition, artifactsPaths);\n                GenerateAppConfig(buildPartition, artifactsPaths);\n                GenerateNuGetConfig(artifactsPaths);\n                GenerateProject(buildPartition, artifactsPaths, logger);\n                GenerateBuildScript(buildPartition, artifactsPaths);\n\n                return GenerateResult.Success(artifactsPaths, GetArtifactsToCleanup(artifactsPaths));\n            }\n            catch (Exception ex)\n            {\n                return GenerateResult.Failure(artifactsPaths, GetArtifactsToCleanup(artifactsPaths), ex);\n            }\n        }\n\n        /// <summary>\n        /// returns a path to the folder where auto-generated project and code are going to be placed\n        /// </summary>\n        [PublicAPI] protected abstract string GetBuildArtifactsDirectoryPath(BuildPartition assemblyLocation, string programName);\n\n        /// <summary>\n        /// returns a path where executable should be found after the build (usually \\bin)\n        /// </summary>\n        [PublicAPI] protected virtual string GetBinariesDirectoryPath(string buildArtifactsDirectoryPath, string configuration)\n            => buildArtifactsDirectoryPath;\n\n        /// <summary>\n        /// returns a path where the publish directory should be found after the build (usually \\publish)\n        /// </summary>\n        [PublicAPI]\n        protected virtual string GetPublishDirectoryPath(string buildArtifactsDirectoryPath, string configuration)\n            => Path.Combine(buildArtifactsDirectoryPath, \"publish\");\n\n        /// <summary>\n        /// returns OS-specific executable extension\n        /// </summary>\n        [PublicAPI] protected virtual string GetExecutableExtension()\n            => OsDetector.ExecutableExtension;\n\n        /// <summary>\n        /// returns a path to the auto-generated .csproj file\n        /// </summary>\n        [PublicAPI] protected virtual string GetProjectFilePath(string buildArtifactsDirectoryPath)\n            => string.Empty;\n\n        /// <summary>\n        /// returns a list of artifacts that should be removed after running the benchmarks\n        /// </summary>\n        [PublicAPI] protected abstract string[] GetArtifactsToCleanup(ArtifactsPaths artifactsPaths);\n\n        /// <summary>\n        /// if you need to copy some extra files to make the benchmarks work you should override this method\n        /// </summary>\n        [PublicAPI] protected virtual void CopyAllRequiredFiles(ArtifactsPaths artifactsPaths) { }\n\n        /// <summary>\n        /// generates NuGet.Config file to make sure that BDN is using the right NuGet feeds\n        /// </summary>\n        [PublicAPI] protected virtual void GenerateNuGetConfig(ArtifactsPaths artifactsPaths) { }\n\n        /// <summary>\n        /// generates .csproj file with a reference to the project with benchmarks\n        /// </summary>\n        [PublicAPI] protected virtual void GenerateProject(BuildPartition buildPartition, ArtifactsPaths artifactsPaths, ILogger logger) { }\n\n        /// <summary>\n        /// generates a script can be used when debugging compilation issues\n        /// </summary>\n        [PublicAPI] protected abstract void GenerateBuildScript(BuildPartition buildPartition, ArtifactsPaths artifactsPaths);\n\n        /// <summary>\n        /// returns a path to the folder where NuGet packages should be restored\n        /// </summary>\n        [PublicAPI] protected virtual string GetPackagesDirectoryPath(string buildArtifactsDirectoryPath) => \"\";\n\n        /// <summary>\n        /// generates an app.config file next to the executable with benchmarks\n        /// </summary>\n        [PublicAPI] protected virtual void GenerateAppConfig(BuildPartition buildPartition, ArtifactsPaths artifactsPaths)\n        {\n            string sourcePath = buildPartition.AssemblyLocation + \".config\";\n            artifactsPaths.AppConfigPath.EnsureFolderExists();\n\n            using (var source = File.Exists(sourcePath) ? new StreamReader(File.OpenRead(sourcePath)) : TextReader.Null)\n            using (var destination = new StreamWriter(File.Create(artifactsPaths.AppConfigPath), Encoding.UTF8))\n            {\n                AppConfigGenerator.Generate(buildPartition.RepresentativeBenchmarkCase.Job, source, destination, buildPartition.Resolver);\n            }\n        }\n\n        /// <summary>\n        /// generates the C# source code with all required boilerplate.\n        /// <remarks>You most probably do NOT need to override this method!!</remarks>\n        /// </summary>\n        [PublicAPI] protected virtual void GenerateCode(BuildPartition buildPartition, ArtifactsPaths artifactsPaths)\n            => File.WriteAllText(artifactsPaths.ProgramCodePath, CodeGenerator.Generate(buildPartition, BenchmarkRunCallType));\n\n        protected virtual string GetExecutablePath(string binariesDirectoryPath, string programName) => Path.Combine(binariesDirectoryPath, $\"{programName}{GetExecutableExtension()}\");\n\n        private ArtifactsPaths GetArtifactsPaths(BuildPartition buildPartition, string rootArtifactsFolderPath)\n        {\n            // its not \".cs\" in order to avoid VS from displaying and compiling it with xprojs/csprojs that include all *.cs by default\n            const string codeFileExtension = \".notcs\";\n\n            string programName = buildPartition.ProgramName;\n            string buildArtifactsDirectoryPath = GetBuildArtifactsDirectoryPath(buildPartition, programName);\n            string binariesDirectoryPath = GetBinariesDirectoryPath(buildArtifactsDirectoryPath, buildPartition.BuildConfiguration);\n\n            string executablePath = GetExecutablePath(binariesDirectoryPath, programName);\n\n            return new ArtifactsPaths(\n                rootArtifactsFolderPath: rootArtifactsFolderPath,\n                buildArtifactsDirectoryPath: buildArtifactsDirectoryPath,\n                binariesDirectoryPath: binariesDirectoryPath,\n                publishDirectoryPath: GetPublishDirectoryPath(buildArtifactsDirectoryPath, buildPartition.BuildConfiguration),\n                programCodePath: Path.Combine(buildArtifactsDirectoryPath, $\"{programName}{codeFileExtension}\"),\n                appConfigPath: $\"{executablePath}.config\",\n                nuGetConfigPath: Path.Combine(buildArtifactsDirectoryPath, \"NuGet.config\"),\n                projectFilePath: GetProjectFilePath(buildArtifactsDirectoryPath),\n                buildScriptFilePath: Path.Combine(buildArtifactsDirectoryPath, $\"{programName}{OsDetector.ScriptFileExtension}\"),\n                executablePath: executablePath,\n                programName: programName,\n                packagesDirectoryName: GetPackagesDirectoryPath(buildArtifactsDirectoryPath));\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/IBuilder.cs",
    "content": "﻿using BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Toolchains.Results;\n\nnamespace BenchmarkDotNet.Toolchains\n{\n    public interface IBuilder\n    {\n        BuildResult Build(GenerateResult generateResult, BuildPartition buildPartition, ILogger logger);\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/IExecutor.cs",
    "content": "using BenchmarkDotNet.Toolchains.Parameters;\nusing BenchmarkDotNet.Toolchains.Results;\n\nnamespace BenchmarkDotNet.Toolchains\n{\n    public interface IExecutor\n    {\n        ExecuteResult Execute(ExecuteParameters executeParameters);\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/IGenerator.cs",
    "content": "using BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Toolchains.Results;\n\nnamespace BenchmarkDotNet.Toolchains\n{\n    public interface IGenerator\n    {\n        GenerateResult GenerateProject(BuildPartition buildPartition, ILogger logger, string rootArtifactsFolderPath);\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/IToolchain.cs",
    "content": "﻿using System.Collections.Generic;\nusing BenchmarkDotNet.Characteristics;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Validators;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Toolchains\n{\n    public interface IToolchain\n    {\n        [PublicAPI] string Name { get; }\n        IGenerator Generator { get; }\n        IBuilder Builder { get; }\n        IExecutor Executor { get; }\n        bool IsInProcess { get; }\n\n        IEnumerable<ValidationError> Validate(BenchmarkCase benchmarkCase, IResolver resolver);\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/InProcess/Emit/Implementation/ConsumableTypeInfo.cs",
    "content": "﻿using System;\nusing System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Threading.Tasks;\nusing static BenchmarkDotNet.Toolchains.InProcess.Emit.Implementation.RunnableReflectionHelpers;\n\nnamespace BenchmarkDotNet.Toolchains.InProcess.Emit.Implementation\n{\n    public class ConsumableTypeInfo\n    {\n        public ConsumableTypeInfo(Type methodReturnType)\n        {\n            OriginMethodReturnType = methodReturnType;\n\n            // Only support (Value)Task for parity with other toolchains (and so we can use AwaitHelper).\n            IsAwaitable = methodReturnType == typeof(Task) || methodReturnType == typeof(ValueTask)\n                || (methodReturnType.GetTypeInfo().IsGenericType\n                    && (methodReturnType.GetTypeInfo().GetGenericTypeDefinition() == typeof(Task<>)\n                    || methodReturnType.GetTypeInfo().GetGenericTypeDefinition() == typeof(ValueTask<>)));\n\n            if (!IsAwaitable)\n            {\n                WorkloadMethodReturnType = methodReturnType;\n            }\n            else\n            {\n                WorkloadMethodReturnType = methodReturnType\n                    .GetMethod(nameof(Task.GetAwaiter), BindingFlagsPublicInstance)!\n                    .ReturnType\n                    .GetMethod(nameof(TaskAwaiter.GetResult), BindingFlagsPublicInstance)!\n                    .ReturnType;\n                GetResultMethod = Helpers.AwaitHelper.GetGetResultMethod(methodReturnType);\n            }\n\n            if (WorkloadMethodReturnType == null)\n                throw new InvalidOperationException(\"Bug: (WorkloadMethodReturnType == null\");\n\n            if (WorkloadMethodReturnType == typeof(void))\n            {\n                IsVoid = true;\n            }\n            else if (WorkloadMethodReturnType.IsByRef)\n            {\n                IsByRef = true;\n            }\n        }\n\n        public Type OriginMethodReturnType { get; }\n        public Type WorkloadMethodReturnType { get; }\n\n        public MethodInfo? GetResultMethod { get; }\n\n        public bool IsVoid { get; }\n        public bool IsByRef { get; }\n\n        public bool IsAwaitable { get; }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/InProcess/Emit/Implementation/Emitters/EmitExtensions.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing System.Reflection;\nusing System.Reflection.Emit;\nusing System.Runtime.ExceptionServices;\n\nnamespace BenchmarkDotNet.Toolchains.InProcess.Emit.Implementation\n{\n    /// <summary>\n    /// this class is a set of hack extensions that allow us to target .NET Standard 2.0 only and keep some .NET Framework-specific logic\n    /// do not copy, it's a set of dirty hacks\n    /// </summary>\n    internal static class EmitExtensions\n    {\n        internal static void Save(this AssemblyBuilder assemblyBuilder, string assemblyFileName)\n            => ExecuteMethodUsingReflection(assemblyBuilder, nameof(Save), assemblyFileName);\n\n        internal static ModuleBuilder DefineDynamicModule(this AssemblyBuilder assemblyBuilder, string moduleName, string moduleFileName)\n            => (ModuleBuilder)ExecuteMethodUsingReflection(assemblyBuilder, nameof(AssemblyBuilder.DefineDynamicModule), moduleName, moduleFileName);\n\n        internal static AssemblyBuilder DefineDynamicAssembly(this AppDomain domain, AssemblyName assemblyName, AssemblyBuilderAccess assemblyMode, string assemblyDirectory)\n            => (AssemblyBuilder)ExecuteMethodUsingReflection(domain, nameof(AssemblyBuilder.DefineDynamicAssembly), assemblyName, assemblyMode, assemblyDirectory);\n\n        private static object ExecuteMethodUsingReflection<T>(T instance, string methodName, params object[] arguments)\n        {\n            var type = typeof(T);\n\n            var method = type.GetMethod(name: methodName, types: arguments.Select(argument => argument.GetType()).ToArray())!;\n\n            try\n            {\n                return method.Invoke(instance, parameters: arguments)!;\n            }\n            catch (TargetInvocationException wrappedByReflection)\n            {\n                var ex = wrappedByReflection.InnerException ?? wrappedByReflection;\n                ExceptionDispatchInfo.Capture(ex).Throw();\n                return default!;// It's required to suppress error CS0161.\n            }\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/InProcess/Emit/Implementation/Emitters/RunnableEmitter.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.IO;\nusing System.Linq;\nusing System.Reflection;\nusing System.Reflection.Emit;\nusing System.Runtime.CompilerServices;\nusing System.Security;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Helpers.Reflection.Emit;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Properties;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Toolchains.Results;\nusing static BenchmarkDotNet.Toolchains.InProcess.Emit.Implementation.RunnableConstants;\nusing static BenchmarkDotNet.Toolchains.InProcess.Emit.Implementation.RunnableReflectionHelpers;\n\nnamespace BenchmarkDotNet.Toolchains.InProcess.Emit.Implementation\n{\n    /// <summary>\n    /// A helper type that emits code that matches BenchmarkType.txt template.\n    /// IMPORTANT: this type IS NOT thread safe.\n    /// </summary>\n    internal class RunnableEmitter\n    {\n        /// <summary>\n        /// Maps action args to fields that store arg values.\n        /// </summary>\n        private class ArgFieldInfo\n        {\n            public ArgFieldInfo(FieldInfo field, Type argLocalsType, MethodInfo opImplicitMethod)\n            {\n                Field = field;\n                ArgLocalsType = argLocalsType;\n                OpImplicitMethod = opImplicitMethod;\n            }\n\n            public FieldInfo Field { get; }\n\n            public Type ArgLocalsType { get; }\n\n            public MethodInfo OpImplicitMethod { get; }\n        }\n\n        /// <summary>\n        /// Emits assembly with runnables from current build partition..\n        /// </summary>\n        public static Assembly EmitPartitionAssembly(\n            GenerateResult generateResult,\n            BuildPartition buildPartition,\n            ILogger logger)\n        {\n            var assemblyResultPath = generateResult.ArtifactsPaths.ExecutablePath;\n            var assemblyFileName = Path.GetFileName(assemblyResultPath);\n            var config = buildPartition.Benchmarks.First().Config;\n\n            var saveToDisk = ShouldSaveToDisk(config);\n            var assemblyBuilder = DefineAssemblyBuilder(assemblyResultPath, saveToDisk);\n            var moduleBuilder = DefineModuleBuilder(assemblyBuilder, assemblyFileName, saveToDisk);\n            foreach (var benchmark in buildPartition.Benchmarks)\n            {\n                var runnableEmitter = new RunnableEmitter(buildPartition, moduleBuilder);\n                runnableEmitter.EmitRunnableCore(benchmark);\n            }\n\n            if (saveToDisk)\n            {\n                assemblyBuilder.Save(assemblyFileName);\n                logger.WriteLineInfo($\"{assemblyFileName} assembly saved to {assemblyResultPath}\");\n            }\n\n            return assemblyBuilder;\n        }\n\n\n        private static bool ShouldSaveToDisk(IConfig config)\n        {\n            if (!BenchmarkDotNetInfo.Instance.IsRelease)\n            {\n                // we never want to do that in our official NuGet.org package, it's a hack\n                return config.Options.IsSet(ConfigOptions.KeepBenchmarkFiles) && Portability.RuntimeInformation.IsFullFramework;\n            }\n\n            return false;\n        }\n\n        private static string GetRunnableTypeName(BenchmarkBuildInfo benchmark)\n        {\n            return EmittedTypePrefix + benchmark.Id;\n        }\n\n        private static AssemblyBuilder DefineAssemblyBuilder(string assemblyResultPath, bool saveToDisk)\n        {\n            var assemblyName = new AssemblyName { Name = Path.GetFileNameWithoutExtension(assemblyResultPath) };\n\n            var assemblyMode = saveToDisk\n                ? (AssemblyBuilderAccess)3 // https://apisof.net/catalog/System.Reflection.Emit.AssemblyBuilderAccess.RunAndSave\n                : AssemblyBuilderAccess.RunAndCollect;\n\n            var assemblyBuilder = saveToDisk\n                ? AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, assemblyMode, Path.GetDirectoryName(assemblyResultPath)!)\n                : AssemblyBuilder.DefineDynamicAssembly(assemblyName, assemblyMode);\n\n            DefineAssemblyAttributes(assemblyBuilder);\n\n            return assemblyBuilder;\n        }\n\n        private static void DefineAssemblyAttributes(AssemblyBuilder assemblyBuilder)\n        {\n            // [assembly: CompilationRelaxations(8)]\n            var attributeCtor = typeof(CompilationRelaxationsAttribute)\n                .GetConstructor([typeof(int)])\n                ?? throw new MissingMemberException(nameof(CompilationRelaxationsAttribute));\n\n            var attBuilder = new CustomAttributeBuilder(\n                attributeCtor,\n                [(int)CompilationRelaxations.NoStringInterning]);\n            assemblyBuilder.SetCustomAttribute(attBuilder);\n\n            // [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]\n            attributeCtor = typeof(RuntimeCompatibilityAttribute)\n                .GetConstructor([])\n                ?? throw new MissingMemberException(nameof(RuntimeCompatibilityAttribute));\n\n            var attributeProp = typeof(RuntimeCompatibilityAttribute)\n                .GetProperty(nameof(RuntimeCompatibilityAttribute.WrapNonExceptionThrows))!;\n            attBuilder = new CustomAttributeBuilder(\n                attributeCtor,\n                constructorArgs: [],\n                namedProperties: [attributeProp],\n                propertyValues: [true]);\n            assemblyBuilder.SetCustomAttribute(attBuilder);\n\n            // [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]\n            attributeCtor = typeof(DebuggableAttribute)\n                .GetConstructor([typeof(DebuggableAttribute.DebuggingModes)])\n                ?? throw new MissingMemberException(nameof(DebuggableAttribute));\n            attBuilder = new CustomAttributeBuilder(\n                attributeCtor,\n                [DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints]);\n            assemblyBuilder.SetCustomAttribute(attBuilder);\n        }\n\n        private static ModuleBuilder DefineModuleBuilder(AssemblyBuilder assemblyBuilder, string moduleFileName, bool saveToDisk)\n        {\n            var moduleName = Path.GetFileNameWithoutExtension(moduleFileName)\n               ?? throw new ArgumentNullException(nameof(moduleFileName));\n\n            var moduleBuilder = saveToDisk\n                ? assemblyBuilder.DefineDynamicModule(moduleName, moduleFileName)\n                : assemblyBuilder.DefineDynamicModule(moduleName);\n\n            // [module:UnverifiableCodeAttribute()]\n            var attributeCtor = typeof(UnverifiableCodeAttribute)\n                .GetConstructor([])\n                ?? throw new MissingMemberException(nameof(UnverifiableCodeAttribute));\n            var attBuilder = new CustomAttributeBuilder(\n                attributeCtor,\n                []);\n            moduleBuilder.SetCustomAttribute(attBuilder);\n\n            return moduleBuilder;\n        }\n\n        private static TypeBuilder DefineRunnableTypeBuilder(\n            BenchmarkBuildInfo benchmark,\n            ModuleBuilder moduleBuilder)\n        {\n            // .class public auto ansi sealed beforefieldinit BenchmarkDotNet.Autogenerated.Runnable_0\n            //    extends [BenchmarkDotNet]BenchmarkDotNet.Samples.SampleBenchmark\n            var benchmarkDescriptor = benchmark.BenchmarkCase.Descriptor;\n\n            var workloadType = benchmarkDescriptor.Type.GetTypeInfo();\n            var workloadTypeAttributes = workloadType.Attributes;\n            if (workloadTypeAttributes.HasFlag(TypeAttributes.NestedPublic))\n            {\n                workloadTypeAttributes =\n                    (workloadTypeAttributes & ~TypeAttributes.NestedPublic)\n                    | TypeAttributes.Public;\n            }\n            var result = moduleBuilder.DefineType(\n                GetRunnableTypeName(benchmark),\n                workloadTypeAttributes | TypeAttributes.Sealed,\n                workloadType);\n\n            return result;\n        }\n\n        private static void EmitNoArgsMethodCallPopReturn(\n            MethodBuilder methodBuilder,\n            MethodInfo targetMethod,\n            ILGenerator ilBuilder,\n            bool forceDirectCall)\n        {\n            /*\n                // call for instance void\n                // GlobalSetup();\n                IL_0000: ldarg.0\n                IL_0001: call instance void [BenchmarkDotNet]BenchmarkDotNet.Samples.SampleBenchmark::GlobalSetup()\n            */\n            /*\n                // call for static with return value\n                // GlobalSetup();\n                IL_0000: call string [BenchmarkDotNet]BenchmarkDotNet.Samples.SampleBenchmark::GlobalCleanup()\n                IL_0005: pop\n            */\n            if (targetMethod.IsStatic)\n            {\n                ilBuilder.EmitStaticCall(targetMethod, []);\n            }\n            else if (methodBuilder.IsStatic)\n            {\n                throw new InvalidOperationException(\n                    $\"[BUG] Static method {methodBuilder.Name} tries to call instance member {targetMethod.Name}\");\n            }\n            else\n            {\n                ilBuilder.Emit(OpCodes.Ldarg_0);\n                ilBuilder.EmitInstanceCallThisValueOnStack(\n                    null,\n                    targetMethod,\n                    [],\n                    forceDirectCall);\n            }\n\n            if (targetMethod.ReturnType != typeof(void))\n                ilBuilder.Emit(OpCodes.Pop);\n        }\n\n        private readonly BuildPartition buildPartition;\n        private readonly ModuleBuilder moduleBuilder;\n\n        private BenchmarkBuildInfo benchmark = default!;\n        private List<ArgFieldInfo> argFields = default!;\n        private int jobUnrollFactor;\n\n        private TypeBuilder runnableBuilder = default!;\n        private ConsumableTypeInfo consumableInfo = default!;\n        private ConsumableTypeInfo? globalSetupReturnInfo;\n        private ConsumableTypeInfo? globalCleanupReturnInfo;\n        private ConsumableTypeInfo? iterationSetupReturnInfo;\n        private ConsumableTypeInfo? iterationCleanupReturnInfo;\n\n        private FieldBuilder globalSetupActionField = default!;\n        private FieldBuilder globalCleanupActionField = default!;\n        private FieldBuilder iterationSetupActionField = default!;\n        private FieldBuilder iterationCleanupActionField = default!;\n        private FieldBuilder notElevenField = default!;\n\n        // ReSharper disable NotAccessedField.Local\n        private ConstructorBuilder ctorMethod = default!;\n        private MethodBuilder trickTheJitMethod = default!;\n        private MethodBuilder overheadImplementationMethod = default!;\n        private MethodBuilder overheadActionUnrollMethod = default!;\n        private MethodBuilder overheadActionNoUnrollMethod = default!;\n        private MethodBuilder workloadActionUnrollMethod = default!;\n        private MethodBuilder workloadActionNoUnrollMethod = default!;\n        private MethodBuilder forDisassemblyDiagnoserMethod = default!;\n\n        private MethodBuilder globalSetupMethod = default!;\n        private MethodBuilder globalCleanupMethod = default!;\n        private MethodBuilder iterationSetupMethod = default!;\n        private MethodBuilder iterationCleanupMethod = default!;\n\n        private MethodBuilder runMethod = default!;\n        // ReSharper restore NotAccessedField.Local\n\n        private RunnableEmitter(BuildPartition buildPartition, ModuleBuilder moduleBuilder)\n        {\n            this.buildPartition = buildPartition;\n            this.moduleBuilder = moduleBuilder;\n        }\n\n        private Descriptor Descriptor => benchmark.BenchmarkCase.Descriptor;\n\n        // ReSharper disable once UnusedMethodReturnValue.Local\n        private Type EmitRunnableCore(BenchmarkBuildInfo newBenchmark)\n        {\n            InitForEmitRunnable(newBenchmark);\n\n            // 1. Emit fields\n            DefineFields();\n\n            // 2. Define members\n            ctorMethod = DefineCtor();\n            trickTheJitMethod = DefineTrickTheJitMethod();\n\n            // Overhead impl\n            overheadImplementationMethod = EmitOverheadImplementation(OverheadImplementationMethodName);\n            overheadActionUnrollMethod = EmitOverheadAction(OverheadActionUnrollMethodName, jobUnrollFactor);\n            overheadActionNoUnrollMethod = EmitOverheadAction(OverheadActionNoUnrollMethodName, 1);\n\n            // Workload impl\n            workloadActionUnrollMethod = EmitWorkloadAction(WorkloadActionUnrollMethodName, jobUnrollFactor);\n            workloadActionNoUnrollMethod = EmitWorkloadAction(WorkloadActionNoUnrollMethodName, 1);\n\n            // __ForDisassemblyDiagnoser__ impl\n            forDisassemblyDiagnoserMethod = EmitForDisassemblyDiagnoser(ForDisassemblyDiagnoserMethodName);\n\n            // 4. Instance completion\n            // Emit wrappers for setup/cleanup callbacks\n            EmitSetupCleanupMethods();\n\n            // Emit methods that depend on others\n            EmitTrickTheJitBody();\n            EmitCtorBody();\n\n            // 5. Emit Run() logic\n            runMethod = EmitRunMethod();\n\n#if NETFRAMEWORK\n            return runnableBuilder.CreateType();\n#else\n            return runnableBuilder.CreateTypeInfo()!;\n#endif\n        }\n\n        private void InitForEmitRunnable(BenchmarkBuildInfo newBenchmark)\n        {\n            // Init current state\n            argFields = [];\n            benchmark = newBenchmark;\n            jobUnrollFactor = benchmark.BenchmarkCase.Job.ResolveValue(\n                RunMode.UnrollFactorCharacteristic,\n                buildPartition.Resolver);\n\n            consumableInfo = new ConsumableTypeInfo(benchmark.BenchmarkCase.Descriptor.WorkloadMethod.ReturnType);\n            globalSetupReturnInfo = GetConsumableTypeInfo(benchmark.BenchmarkCase.Descriptor.GlobalSetupMethod?.ReturnType);\n            globalCleanupReturnInfo = GetConsumableTypeInfo(benchmark.BenchmarkCase.Descriptor.GlobalCleanupMethod?.ReturnType);\n            iterationSetupReturnInfo = GetConsumableTypeInfo(benchmark.BenchmarkCase.Descriptor.IterationSetupMethod?.ReturnType);\n            iterationCleanupReturnInfo = GetConsumableTypeInfo(benchmark.BenchmarkCase.Descriptor.IterationCleanupMethod?.ReturnType);\n\n            // Init type\n            runnableBuilder = DefineRunnableTypeBuilder(benchmark, moduleBuilder);\n        }\n\n        private static ConsumableTypeInfo? GetConsumableTypeInfo(Type? methodReturnType)\n        {\n            return methodReturnType == null ? null : new ConsumableTypeInfo(methodReturnType);\n        }\n\n        private void DefineFields()\n        {\n            globalSetupActionField =\n                runnableBuilder.DefineField(GlobalSetupActionFieldName, typeof(Action), FieldAttributes.Private);\n            globalCleanupActionField =\n                runnableBuilder.DefineField(GlobalCleanupActionFieldName, typeof(Action), FieldAttributes.Private);\n            iterationSetupActionField =\n                runnableBuilder.DefineField(IterationSetupActionFieldName, typeof(Action), FieldAttributes.Private);\n            iterationCleanupActionField =\n                runnableBuilder.DefineField(IterationCleanupActionFieldName, typeof(Action), FieldAttributes.Private);\n\n            // Define arg fields\n            foreach (var parameter in Descriptor.WorkloadMethod.GetParameters())\n            {\n                var argValue = benchmark.BenchmarkCase.Parameters.GetArgument(parameter.Name!);\n                var parameterType = parameter.ParameterType;\n\n                Type argLocalsType;\n                Type argFieldType;\n                MethodInfo? opConversion = null;\n                if (parameterType.IsByRef)\n                {\n                    argLocalsType = parameterType;\n                    argFieldType = argLocalsType.GetElementType()\n                        ?? throw new InvalidOperationException($\"Bug: cannot get field type from {argLocalsType}\");\n                }\n                else if (IsRefLikeType(parameterType) && argValue.Value != null)\n                {\n                    argLocalsType = parameterType;\n\n                    // Use conversion on load; store passed value\n                    var passedArgType = argValue.Value.GetType();\n                    opConversion = GetImplicitConversionOpFromTo(passedArgType, argLocalsType) ??\n                        throw new InvalidOperationException($\"Bug: No conversion from {passedArgType} to {argLocalsType}.\");\n                    argFieldType = passedArgType;\n                }\n                else\n                {\n                    // No conversion; load ref to arg field;\n                    argLocalsType = parameterType;\n                    argFieldType = parameterType;\n                }\n\n                if (IsRefLikeType(argFieldType))\n                    throw new NotSupportedException(\n                        $\"Passing ref readonly structs by ref is not supported (cannot store {argFieldType} as a class field).\");\n\n                var argField = runnableBuilder.DefineField(\n                    ArgFieldPrefix + parameter.Position,\n                    argFieldType,\n                    FieldAttributes.Private);\n\n                argFields.Add(new ArgFieldInfo(argField, argLocalsType, opConversion!));\n            }\n\n            notElevenField = runnableBuilder.DefineField(NotElevenFieldName, typeof(int), FieldAttributes.Public);\n        }\n\n        private ConstructorBuilder DefineCtor()\n        {\n            // .method public hidebysig specialname rtspecialname\n            //    instance void.ctor() cil managed\n            return runnableBuilder.DefinePublicInstanceCtor();\n        }\n\n        private MethodBuilder DefineTrickTheJitMethod()\n        {\n            // .method public hidebysig\n            //    instance void __TrickTheJIT__() cil managed noinlining nooptimization\n            var result = runnableBuilder\n                .DefinePublicNonVirtualVoidInstanceMethod(TrickTheJitCoreMethodName)\n                .SetNoInliningImplementationFlag()\n                .SetNoOptimizationImplementationFlag();\n\n            return result;\n        }\n\n        private MethodBuilder EmitOverheadImplementation(string methodName)\n        {\n            //.method private hidebysig\n            //    instance void __Overhead(int64 arg0) cil managed\n\n            // Replace arg names\n            var parameters = Descriptor.WorkloadMethod.GetParameters()\n                .Select(p =>\n                    (ParameterInfo)new EmitParameterInfo(\n                        p.Position,\n                        ArgParamPrefix + p.Position,\n                        p.ParameterType,\n                        p.Attributes,\n                        null))\n                .ToArray();\n\n            var methodBuilder = runnableBuilder.DefineNonVirtualInstanceMethod(\n                methodName,\n                MethodAttributes.Private,\n                EmitParameterInfo.CreateReturnVoidParameter(),\n                parameters)\n                .SetNoInliningImplementationFlag();\n\n            var ilBuilder = methodBuilder.GetILGenerator();\n            /*\n                // return;\n                IL_0001: ret\n             */\n            ilBuilder.EmitVoidReturn(methodBuilder);\n\n            return methodBuilder;\n        }\n\n        private MethodBuilder EmitOverheadAction(string methodName, int unrollFactor)\n            => EmitActionImpl(methodName, overheadImplementationMethod, EmitCallOverhead, unrollFactor);\n\n        private MethodBuilder EmitWorkloadAction(string methodName, int unrollFactor)\n            => EmitActionImpl(methodName, Descriptor.WorkloadMethod, EmitCallWorkload, unrollFactor);\n\n        private void EmitCallOverhead(ILGenerator ilBuilder, IReadOnlyList<LocalBuilder> argLocals)\n        {\n            /*\n                // __Overhead();\n                IL_0008: ldarg.0\n                IL_0009: call instance void BenchmarkDotNet.Autogenerated.Runnable_0::__Overhead()\n             */\n            ilBuilder.Emit(OpCodes.Ldarg_0);\n            ilBuilder.EmitLdLocals(argLocals);\n            ilBuilder.Emit(OpCodes.Call, overheadImplementationMethod);\n        }\n\n        private void EmitCallWorkload(ILGenerator ilBuilder, IReadOnlyList<LocalBuilder> argLocals)\n        {\n            /*\n                // InvokeOnceVoid();\n                IL_0008: ldarg.0\n                IL_0009: call instance void [BenchmarkDotNet.IntegrationTests]BenchmarkDotNet.IntegrationTests.InProcessEmitTest/BenchmarkAllCases::InvokeOnceVoid()\n             */\n            MethodInfo invokeMethod = Descriptor.WorkloadMethod;\n            if (!invokeMethod.IsStatic)\n            {\n                ilBuilder.Emit(OpCodes.Ldarg_0);\n            }\n            ilBuilder.EmitLdLocals(argLocals);\n            ilBuilder.Emit(OpCodes.Call, invokeMethod);\n\n            if (consumableInfo.IsAwaitable)\n            {\n                /*\n                    // BenchmarkDotNet.Helpers.AwaitHelper.GetResult(...);\n                    IL_000e: call !!0 BenchmarkDotNet.Helpers.AwaitHelper::GetResult<int32>(valuetype [System.Runtime]System.Threading.Tasks.ValueTask`1<!!0>)\n                */\n                ilBuilder.Emit(OpCodes.Call, consumableInfo.GetResultMethod!);\n            }\n\n            if (consumableInfo.WorkloadMethodReturnType != typeof(void))\n            {\n                // IL_000b: pop\n                ilBuilder.Emit(OpCodes.Pop);\n            }\n        }\n\n        private MethodBuilder EmitActionImpl(string methodName, MethodInfo invokeMethod, Action<ILGenerator, IReadOnlyList<LocalBuilder>> callMethodEmitter, int unrollFactor)\n        {\n            // .method private hidebysig\n            //    instance void OverheadActionUnroll(int64 invokeCount) cil managed aggressiveoptimization\n            var invokeCountArg = new EmitParameterInfo(0, InvokeCountParamName, typeof(long));\n            var actionMethodBuilder = runnableBuilder.DefineNonVirtualInstanceMethod(\n                methodName,\n                MethodAttributes.Private,\n                EmitParameterInfo.CreateReturnVoidParameter(),\n                invokeCountArg)\n                .SetAggressiveOptimizationImplementationFlag();\n            invokeCountArg.SetMember(actionMethodBuilder);\n\n            // Emit impl\n            var ilBuilder = actionMethodBuilder.GetILGenerator();\n\n            // init locals\n            var argLocals = EmitDeclareArgLocals(ilBuilder);\n\n            // load fields\n            EmitLoadArgFieldsToLocals(ilBuilder, argLocals);\n\n            // loop\n            ilBuilder.EmitLoopBeginFromArgToZero(out var loopStartLabel, out var loopHeadLabel);\n            {\n                for (int u = 0; u < unrollFactor; u++)\n                {\n                    callMethodEmitter(ilBuilder, argLocals);\n                }\n            }\n            ilBuilder.EmitLoopEndFromArgToZero(loopStartLabel, loopHeadLabel, invokeCountArg);\n\n            // IL_003a: ret\n            ilBuilder.EmitVoidReturn(actionMethodBuilder);\n\n            return actionMethodBuilder;\n        }\n\n        private IReadOnlyList<LocalBuilder> EmitDeclareArgLocals(ILGenerator ilBuilder, bool skipFirst = false)\n        {\n            // NB: c# compiler does not store first arg in locals for static calls\n            /*\n                .locals init (\n                    [0] int64, // argFields[0]\n                    [1] int32, // argFields[1]\n                )\n                // -or- (static calls)\n                .locals init (\n                    [0] int32, // argFields[1]\n                )\n             */\n            bool first = true;\n            var argLocals = new List<LocalBuilder>(argFields.Count);\n            foreach (var argField in argFields)\n            {\n                if (!first || !skipFirst)\n                {\n                    argLocals.Add(ilBuilder.DeclareLocal(argField.ArgLocalsType));\n                }\n\n                first = false;\n            }\n\n            return argLocals;\n        }\n\n        private void EmitLoadArgFieldsToLocals(ILGenerator ilBuilder, IReadOnlyList<LocalBuilder> argLocals, bool skipFirstArg = false)\n        {\n            // NB: c# compiler does not store first arg in locals for static calls\n            int localsOffset = argFields.Count > 0 && skipFirstArg ? -1 : 0;\n\n            if (argLocals.Count != argFields.Count + localsOffset)\n                throw new InvalidOperationException(\"Bug: argLocals.Count != _argFields.Count + localsOffset\");\n\n            /*\n                // long _argField = __argField0;\n                IL_0000: ldarg.0\n                IL_0001: ldfld int64 BenchmarkDotNet.Autogenerated.Runnable_0::__argField0\n                IL_0006: stloc.0\n                IL_0007: ldarg.1\n                IL_0008: ldfld int32 BenchmarkDotNet.Autogenerated.Runnable_0::__argField1\n                IL_000c: stloc.1\n                // -or-\n                // ref int _argField = ref __argField0;\n                IL_0000: ldarg.0\n                IL_0001: ldflda int64 BenchmarkDotNet.Autogenerated.Runnable_0::__argField0\n                IL_0006: stloc.0\n                IL_0007: ldarg.1\n                IL_000b: ldflda int32 BenchmarkDotNet.Autogenerated.Runnable_0::__argField1\n                IL_000c: stloc.1\n                // -or- (static call)\n                // long _argField = __argField0;\n                IL_0000: ldarg.0\n                IL_0001: ldfld int64 BenchmarkDotNet.Autogenerated.Runnable_0::__argField0\n                IL_0006: ldarg.1\n                IL_0007: ldfld int32 BenchmarkDotNet.Autogenerated.Runnable_0::__argField1\n                IL_000b: stloc.0 // offset by -1\n                // -or- (ref struct arg call)\n                IL_0000: ldarg.0\n                IL_0001: ldfld int32[] BenchmarkDotNet.Autogenerated.Runnable_0::__argField0\n                IL_0006: call valuetype [System.Memory]System.Span`1<!0> valuetype [System.Memory]System.Span`1<int32>::op_Implicit(!0[])\n                IL_000b: stloc.0\n                IL_000c: ldarg.1\n                IL_000d: ldfld int32 BenchmarkDotNet.Autogenerated.Runnable_0::__argField1\n                IL_0012: stloc.1\n             */\n            for (int i = 0; i < argFields.Count; i++)\n            {\n                ilBuilder.Emit(OpCodes.Ldarg_0);\n                var argFieldInfo = argFields[i];\n\n                if (argFieldInfo.ArgLocalsType.IsByRef)\n                    ilBuilder.Emit(OpCodes.Ldflda, argFieldInfo.Field);\n                else\n                    ilBuilder.Emit(OpCodes.Ldfld, argFieldInfo.Field);\n\n                if (argFieldInfo.OpImplicitMethod != null)\n                    ilBuilder.Emit(OpCodes.Call, argFieldInfo.OpImplicitMethod);\n\n                var localsIndex = i + localsOffset;\n                if (localsIndex >= 0)\n                    ilBuilder.EmitStloc(argLocals[localsIndex]);\n            }\n        }\n\n        private MethodBuilder EmitForDisassemblyDiagnoser(string methodName)\n        {\n            // .method public hidebysig\n            //    instance void __ForDisassemblyDiagnoser__() cil managed noinlining nooptimization\n            var workloadMethod = Descriptor.WorkloadMethod;\n            var workloadReturnParameter = EmitParameterInfo.CreateReturnParameter(typeof(void));\n            var methodBuilder = runnableBuilder\n                .DefineNonVirtualInstanceMethod(\n                    methodName,\n                    MethodAttributes.Public,\n                    workloadReturnParameter)\n                .SetNoInliningImplementationFlag()\n                .SetNoOptimizationImplementationFlag();\n\n            var ilBuilder = methodBuilder.GetILGenerator();\n\n            /*\n                .locals init (\n                    [0] int64,\n                )\n             */\n            // NB: c# compiler does not store first arg in locals for static calls\n            var skipFirstArg = workloadMethod.IsStatic;\n            var argLocals = EmitDeclareArgLocals(ilBuilder, skipFirstArg);\n\n            var notElevenLabel = ilBuilder.DefineLabel();\n            /*\n                // if (NotEleven == 11)\n                IL_0000: ldarg.0\n                IL_0001: ldfld int32 BenchmarkDotNet.Autogenerated.Runnable_0::NotEleven\n                IL_0006: ldc.i4.s 11\n                IL_0008: bne.un.s IL_0019  // we use long jump\n             */\n            ilBuilder.Emit(OpCodes.Ldarg_0);\n            ilBuilder.Emit(OpCodes.Ldfld, notElevenField);\n            ilBuilder.Emit(OpCodes.Ldc_I4_S, (byte)11);\n            ilBuilder.Emit(OpCodes.Bne_Un, notElevenLabel);\n            {\n                /*\n                    // long _argField = __argField0;\n                    IL_000a: ldarg.0\n                    IL_000b: ldfld int32 BenchmarkDotNet.Autogenerated.Runnable_0::__argField0\n                    IL_0010: stloc.0\n                 */\n                EmitLoadArgFieldsToLocals(ilBuilder, argLocals, skipFirstArg);\n\n                /*\n                    IL_0026: ldarg.0\n                    IL_0027: ldloc.0\n                    IL_0028: ldloc.1\n                    IL_0029: ldloc.2\n                    IL_002a: ldloc.3\n                    IL_002b: call instance class [System.Private.CoreLib]System.Threading.Tasks.Task`1<object> BenchmarkDotNet.Helpers.Runnable_0::WorkloadMethod(string, string, string, string)\n                */\n                if (!workloadMethod.IsStatic)\n                {\n                    ilBuilder.Emit(OpCodes.Ldarg_0);\n                }\n                ilBuilder.EmitLdLocals(argLocals);\n                ilBuilder.Emit(OpCodes.Call, workloadMethod);\n\n                if (consumableInfo.IsAwaitable)\n                {\n                    /*\n                        // BenchmarkDotNet.Helpers.AwaitHelper.GetResult(...);\n                        IL_000e: call !!0 BenchmarkDotNet.Helpers.AwaitHelper::GetResult<int32>(valuetype [System.Runtime]System.Threading.Tasks.ValueTask`1<!!0>)\n                    */\n                    ilBuilder.Emit(OpCodes.Call, consumableInfo.GetResultMethod!);\n                }\n\n                if (consumableInfo.WorkloadMethodReturnType != typeof(void))\n                {\n                    ilBuilder.Emit(OpCodes.Pop);\n                }\n            }\n            ilBuilder.MarkLabel(notElevenLabel);\n            /*\n                IL_0018: ret\n            */\n            ilBuilder.Emit(OpCodes.Ret);\n\n            return methodBuilder;\n        }\n\n        private void EmitSetupCleanupMethods()\n        {\n            // Emit Setup/Cleanup methods\n            // We emit empty method instead of EmptyAction = \"() => { }\"\n            globalSetupMethod = EmitWrapperMethod(GlobalSetupMethodName, Descriptor.GlobalSetupMethod, globalSetupReturnInfo);\n            globalCleanupMethod = EmitWrapperMethod(GlobalCleanupMethodName, Descriptor.GlobalCleanupMethod, globalCleanupReturnInfo);\n            iterationSetupMethod = EmitWrapperMethod(IterationSetupMethodName, Descriptor.IterationSetupMethod, iterationSetupReturnInfo);\n            iterationCleanupMethod = EmitWrapperMethod(IterationCleanupMethodName, Descriptor.IterationCleanupMethod, iterationCleanupReturnInfo);\n        }\n\n        private MethodBuilder EmitWrapperMethod(string methodName, MethodInfo? optionalTargetMethod, ConsumableTypeInfo? returnTypeInfo)\n        {\n            var methodBuilder = runnableBuilder.DefinePrivateVoidInstanceMethod(methodName);\n\n            var ilBuilder = methodBuilder.GetILGenerator();\n\n            if (optionalTargetMethod != null)\n            {\n                if (returnTypeInfo?.IsAwaitable == true)\n                {\n                    EmitAwaitableSetupTeardown(methodBuilder, optionalTargetMethod, ilBuilder, returnTypeInfo);\n                }\n                else\n                {\n                    EmitNoArgsMethodCallPopReturn(methodBuilder, optionalTargetMethod, ilBuilder, forceDirectCall: true);\n                }\n            }\n\n            ilBuilder.EmitVoidReturn(methodBuilder);\n\n            return methodBuilder;\n        }\n\n        private void EmitAwaitableSetupTeardown(\n            MethodBuilder methodBuilder,\n            MethodInfo targetMethod,\n            ILGenerator ilBuilder,\n            ConsumableTypeInfo returnTypeInfo)\n        {\n            if (returnTypeInfo.WorkloadMethodReturnType == typeof(void))\n            {\n                ilBuilder.Emit(OpCodes.Ldarg_0);\n            }\n            /*\n                // call for instance\n                // GlobalSetup();\n                IL_0006: ldarg.0\n                IL_0007: call instance void [BenchmarkDotNet]BenchmarkDotNet.Samples.SampleBenchmark::GlobalSetup()\n            */\n            /*\n                // call for static\n                // GlobalSetup();\n                IL_0006: call string [BenchmarkDotNet]BenchmarkDotNet.Samples.SampleBenchmark::GlobalCleanup()\n            */\n            if (targetMethod.IsStatic)\n            {\n                ilBuilder.Emit(OpCodes.Call, targetMethod);\n\n            }\n            else if (methodBuilder.IsStatic)\n            {\n                throw new InvalidOperationException(\n                    $\"[BUG] Static method {methodBuilder.Name} tries to call instance member {targetMethod.Name}\");\n            }\n            else\n            {\n                ilBuilder.Emit(OpCodes.Ldarg_0);\n                ilBuilder.Emit(OpCodes.Call, targetMethod);\n            }\n\n            /*\n                // BenchmarkDotNet.Helpers.AwaitHelper.GetResult(...);\n                IL_000e: call !!0 BenchmarkDotNet.Helpers.AwaitHelper::GetResult<int32>(valuetype [System.Runtime]System.Threading.Tasks.ValueTask`1<!!0>)\n            */\n\n            ilBuilder.Emit(OpCodes.Call, returnTypeInfo.GetResultMethod!);\n            ilBuilder.Emit(OpCodes.Pop);\n        }\n\n        private void EmitCtorBody()\n        {\n            var ilBuilder = ctorMethod.GetILGenerator();\n\n            ilBuilder.EmitCallBaseParameterlessCtor(ctorMethod);\n\n            ilBuilder.EmitSetDelegateToThisField(globalSetupActionField, globalSetupMethod);\n            ilBuilder.EmitSetDelegateToThisField(globalCleanupActionField, globalCleanupMethod);\n            ilBuilder.EmitSetDelegateToThisField(iterationSetupActionField, iterationSetupMethod);\n            ilBuilder.EmitSetDelegateToThisField(iterationCleanupActionField, iterationCleanupMethod);\n\n            ilBuilder.EmitCtorReturn(ctorMethod);\n        }\n\n        private void EmitTrickTheJitBody()\n        {\n            var ilBuilder = trickTheJitMethod.GetILGenerator();\n\n            /*\n                // NotEleven = new Random(123).Next(0, 10);\n                IL_0000: ldarg.0\n                IL_0001: ldc.i4.s 123\n                IL_0003: newobj instance void [mscorlib]System.Random::.ctor(int32)\n                IL_0008: ldc.i4.0\n                IL_0009: ldc.i4.s 10\n                IL_000b: callvirt instance int32 [mscorlib]System.Random::Next(int32, int32)\n                IL_0010: stfld int32 BenchmarkDotNet.Autogenerated.Runnable_0::NotEleven\n             */\n            var randomCtor = typeof(Random).GetConstructor([typeof(int)])\n                ?? throw new MissingMemberException(nameof(Random));\n            var randomNextMethod = typeof(Random).GetMethod(nameof(Random.Next), [typeof(int), typeof(int)])\n                ?? throw new MissingMemberException(nameof(Random.Next));\n\n            ilBuilder.Emit(OpCodes.Ldarg_0);\n            ilBuilder.Emit(OpCodes.Ldc_I4_S, (byte)123);\n            ilBuilder.Emit(OpCodes.Newobj, randomCtor);\n            ilBuilder.Emit(OpCodes.Ldc_I4_0);\n            ilBuilder.Emit(OpCodes.Ldc_I4_S, (byte)10);\n            ilBuilder.Emit(OpCodes.Callvirt, randomNextMethod);\n            ilBuilder.Emit(OpCodes.Stfld, notElevenField);\n\n            /*\n                // __ForDisassemblyDiagnoser__();\n                IL_0015: ldarg.0\n                IL_0016: call instance int32 BenchmarkDotNet.Autogenerated.Runnable_0::__ForDisassemblyDiagnoser__()\n                IL_001b: pop\n            */\n            EmitNoArgsMethodCallPopReturn(trickTheJitMethod, forDisassemblyDiagnoserMethod, ilBuilder, forceDirectCall: true);\n\n            // IL_001b: ret\n            ilBuilder.EmitVoidReturn(trickTheJitMethod);\n        }\n\n        private MethodBuilder EmitRunMethod()\n        {\n            var prepareForRunMethodTemplate = typeof(RunnableReuse).GetMethod(nameof(RunnableReuse.PrepareForRun))\n                ?? throw new MissingMemberException(nameof(RunnableReuse.PrepareForRun));\n            (Job, EngineParameters, IEngineFactory) resultTuple = new();\n\n            /*\n                .method public hidebysig static\n                    void Run (\n                        class [BenchmarkDotNet]BenchmarkDotNet.Engines.IHost host,\n                        class [BenchmarkDotNet]BenchmarkDotNet.Toolchains.Parameters.ExecuteParameters parameters,\n                    ) cil managed\n             */\n            var argsExceptInstance = prepareForRunMethodTemplate\n                .GetParameters()\n                .Skip(1)\n                .Select(p => (ParameterInfo)new EmitParameterInfo(p.Position - 1, p.Name, p.ParameterType, p.Attributes, null))\n                .ToArray();\n            var methodBuilder = runnableBuilder.DefineStaticMethod(\n                RunMethodName,\n                MethodAttributes.Public,\n                EmitParameterInfo.CreateReturnVoidParameter(),\n                argsExceptInstance);\n            argsExceptInstance = methodBuilder.GetEmitParameters(argsExceptInstance);\n            var hostArg = argsExceptInstance[0];\n            var parametersArg = argsExceptInstance[1];\n\n            var ilBuilder = methodBuilder.GetILGenerator();\n\n            /*\n                .locals init (\n                    [0] class BenchmarkDotNet.Autogenerated.Runnable_0,\n                    [1] class [BenchmarkDotNet]BenchmarkDotNet.Jobs.Job,\n                    [2] class [BenchmarkDotNet]BenchmarkDotNet.Engines.EngineParameters,\n                    [3] class [BenchmarkDotNet]BenchmarkDotNet.Engines.IEngineFactory,\n                    [4] valuetype [BenchmarkDotNet]BenchmarkDotNet.Engines.RunResults\n                )\n             */\n            var instanceLocal = ilBuilder.DeclareLocal(runnableBuilder);\n            var jobLocal = ilBuilder.DeclareLocal(typeof(Job));\n            var engineParametersLocal = ilBuilder.DeclareLocal(typeof(EngineParameters));\n            var engineFactoryLocal = ilBuilder.DeclareLocal(typeof(IEngineFactory));\n            var runResultsLocal = ilBuilder.DeclareLocal(typeof(RunResults));\n\n            /*\n                // Runnable_0 instance = new Runnable_0();\n                IL_0000: newobj instance void BenchmarkDotNet.Autogenerated.Runnable_0::.ctor()\n                IL_0005: stloc.0\n             */\n            ilBuilder.Emit(OpCodes.Newobj, ctorMethod);\n            ilBuilder.EmitStloc(instanceLocal);\n\n            /*\n                // (Job, EngineParameters, IEngineFactory) valueTuple = RunnableReuse.PrepareForRun(instance, host, parameters);\n                IL_0006: ldloc.0\n                IL_0007: ldarg.0\n                IL_0008: ldarg.1\n                IL_0009: call valuetype [mscorlib]System.ValueTuple`3<class [BenchmarkDotNet]BenchmarkDotNet.Jobs.Job, class [BenchmarkDotNet]BenchmarkDotNet.Engines.EngineParameters, class [BenchmarkDotNet]BenchmarkDotNet.Engines.IEngineFactory> [BenchmarkDotNet]BenchmarkDotNet.Toolchains.InProcess.Emit.Implementation.RunnableReuse::PrepareForRun<class BenchmarkDotNet.Autogenerated.Runnable_0>(!!0, class [BenchmarkDotNet]BenchmarkDotNet.Engines.IHost, class [BenchmarkDotNet]BenchmarkDotNet.Toolchains.Parameters.ExecuteParameters)\n             */\n            ilBuilder.EmitLdloc(instanceLocal);\n            ilBuilder.EmitLdarg(hostArg);\n            ilBuilder.EmitLdarg(parametersArg);\n            ilBuilder.Emit(OpCodes.Call, prepareForRunMethodTemplate.MakeGenericMethod(runnableBuilder));\n\n            /*\n                // Job job = valueTuple.Item1;\n                IL_000e: dup\n                IL_000f: ldfld !0 valuetype [mscorlib]System.ValueTuple`3<class [BenchmarkDotNet]BenchmarkDotNet.Jobs.Job, class [BenchmarkDotNet]BenchmarkDotNet.Engines.EngineParameters, class [BenchmarkDotNet]BenchmarkDotNet.Engines.IEngineFactory>::Item1\n                IL_0014: stloc.1\n             */\n            ilBuilder.Emit(OpCodes.Dup);\n            ilBuilder.Emit(OpCodes.Ldfld, resultTuple.GetType().GetField(nameof(resultTuple.Item1))!);\n            ilBuilder.EmitStloc(jobLocal);\n            /*\n                // EngineParameters engineParameters = valueTuple.Item2;\n                IL_0015: dup\n                IL_0016: ldfld !1 valuetype [mscorlib]System.ValueTuple`3<class [BenchmarkDotNet]BenchmarkDotNet.Jobs.Job, class [BenchmarkDotNet]BenchmarkDotNet.Engines.EngineParameters, class [BenchmarkDotNet]BenchmarkDotNet.Engines.IEngineFactory>::Item2\n                IL_001b: stloc.2\n             */\n            ilBuilder.Emit(OpCodes.Dup);\n            ilBuilder.Emit(OpCodes.Ldfld, resultTuple.GetType().GetField(nameof(resultTuple.Item2))!);\n            ilBuilder.EmitStloc(engineParametersLocal);\n            /*\n                // IEngineFactory engineFactory = valueTuple.Item3;\n                IL_001c: ldfld !2 valuetype [mscorlib]System.ValueTuple`3<class [BenchmarkDotNet]BenchmarkDotNet.Jobs.Job, class [BenchmarkDotNet]BenchmarkDotNet.Engines.EngineParameters, class [BenchmarkDotNet]BenchmarkDotNet.Engines.IEngineFactory>::Item3\n                IL_0021: stloc.3\n             */\n            ilBuilder.Emit(OpCodes.Ldfld, resultTuple.GetType().GetField(nameof(resultTuple.Item3))!);\n            ilBuilder.EmitStloc(engineFactoryLocal);\n\n            var notNullLabel = ilBuilder.DefineLabel();\n            /*\n                // if (job != null) { ... } // translates to \"if null: return; else: ...\"\n                IL_0022: ldloc.1\n                IL_0023: brtrue.s IL_0026\n                IL_0025: ret\n             */\n            ilBuilder.EmitLdloc(jobLocal);\n            ilBuilder.Emit(OpCodes.Brtrue_S, notNullLabel);\n            ilBuilder.EmitVoidReturn(methodBuilder);\n\n            /*\n                // RunResults results = engineFactory.Create(engineParameters).Run();\n                IL_0026: ldloc.3\n                IL_0027: ldloc.2\n                IL_0028: callvirt instance class [BenchmarkDotNet]BenchmarkDotNet.Engines.IEngine [BenchmarkDotNet]BenchmarkDotNet.Engines.IEngineFactory::Create(class [BenchmarkDotNet]BenchmarkDotNet.Engines.EngineParameters)\n                IL_002d: callvirt instance valuetype [BenchmarkDotNet]BenchmarkDotNet.Engines.RunResults [BenchmarkDotNet]BenchmarkDotNet.Engines.IEngine::Run()\n                IL_0032: stloc.s 4\n             */\n            var createReadyToRunMethod = typeof(IEngineFactory).GetMethod(nameof(IEngineFactory.Create))\n                ?? throw new MissingMemberException(nameof(IEngineFactory.Create));\n            var runMethodImpl = typeof(IEngine).GetMethod(nameof(IEngine.Run))\n                ?? throw new MissingMemberException(nameof(IEngine.Run));\n            ilBuilder.MarkLabel(notNullLabel);\n            ilBuilder.EmitLdloc(engineFactoryLocal);\n            ilBuilder.EmitLdloc(engineParametersLocal);\n            ilBuilder.Emit(OpCodes.Callvirt, createReadyToRunMethod);\n            ilBuilder.Emit(OpCodes.Callvirt, runMethodImpl);\n            ilBuilder.EmitStloc(runResultsLocal);\n            /*\n                // host.ReportResults(runResults);\n                IL_0034: ldarg.0\n                IL_0035: ldloc.s 4\n                IL_0037: callvirt instance void [BenchmarkDotNet]BenchmarkDotNet.Engines.IHost::ReportResults(valuetype [BenchmarkDotNet]BenchmarkDotNet.Engines.RunResults)\n            */\n\n            var reportResultsMethod = typeof(IHost).GetMethod(nameof(IHost.ReportResults))\n                ?? throw new MissingMemberException(nameof(IHost.ReportResults));\n            ilBuilder.EmitLdarg(hostArg);\n            ilBuilder.EmitLdloc(runResultsLocal);\n            ilBuilder.Emit(OpCodes.Callvirt, reportResultsMethod);\n            /*\n                // runnable_.__TrickTheJIT__();\n                IL_003c: ldloc.0\n                IL_003d: callvirt instance void BenchmarkDotNet.Autogenerated.ReplaceMe.Runnable_0::__TrickTheJIT__()\n             */\n            ilBuilder.Emit(OpCodes.Ldloc_0);\n            ilBuilder.Emit(OpCodes.Callvirt, trickTheJitMethod);\n            /*\n                // engineParameters.InProcessDiagnoserHandler.Handle(BenchmarkSignal.AfterEngine);\n                IL_0042: ldloc.2\n                IL_0043: callvirt instance class [BenchmarkDotNet]BenchmarkDotNet.Diagnosers.CompositeInProcessDiagnoserHandler [BenchmarkDotNet]BenchmarkDotNet.Engines.EngineParameters::get_InProcessDiagnoserHandler()\n                IL_0048: ldc.i4.5\n                IL_0049: callvirt instance void [BenchmarkDotNet]BenchmarkDotNet.Diagnosers.CompositeInProcessDiagnoserHandler::Handle(valuetype [BenchmarkDotNet]BenchmarkDotNet.Engines.BenchmarkSignal)\n            */\n            ilBuilder.EmitLdloc(engineParametersLocal);\n            ilBuilder.Emit(OpCodes.Callvirt, typeof(EngineParameters).GetProperty(nameof(EngineParameters.InProcessDiagnoserHandler))!.GetGetMethod()!);\n            ilBuilder.Emit(OpCodes.Ldc_I4_5);\n            ilBuilder.Emit(OpCodes.Callvirt, typeof(Diagnosers.CompositeInProcessDiagnoserHandler).GetMethod(nameof(Diagnosers.CompositeInProcessDiagnoserHandler.Handle))!);\n\n            ilBuilder.EmitVoidReturn(methodBuilder);\n\n            return methodBuilder;\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/InProcess/Emit/Implementation/Runnable/RunnableConstants.cs",
    "content": "﻿namespace BenchmarkDotNet.Toolchains.InProcess.Emit.Implementation\n{\n    /// <summary>\n    /// A helper type that emits code that matches BenchmarkType.txt template.\n    /// IMPORTANT: this type IS NOT thread safe.\n    /// </summary>\n    public class RunnableConstants\n    {\n        public const string IsByRefLikeAttributeTypeName = \"System.Runtime.CompilerServices.IsByRefLikeAttribute\";\n        public const string OpImplicitMethodName = \"op_Implicit\";\n\n        public const string DynamicAssemblySuffix = \"Emitted\";\n        public const string EmittedTypePrefix = \"BenchmarkDotNet.Autogenerated.Runnable_\";\n        public const string ArgFieldPrefix = \"__argField\";\n        public const string ArgParamPrefix = \"arg\";\n\n        public const string GlobalSetupActionFieldName = \"globalSetupAction\";\n        public const string GlobalCleanupActionFieldName = \"globalCleanupAction\";\n        public const string IterationSetupActionFieldName = \"iterationSetupAction\";\n        public const string IterationCleanupActionFieldName = \"iterationCleanupAction\";\n        public const string NotElevenFieldName = \"NotEleven\";\n\n        public const string TrickTheJitCoreMethodName = \"__TrickTheJIT__\";\n        public const string WorkloadImplementationMethodName = \"__Workload\";\n        public const string OverheadImplementationMethodName = \"__Overhead\";\n        public const string OverheadActionUnrollMethodName = \"OverheadActionUnroll\";\n        public const string OverheadActionNoUnrollMethodName = \"OverheadActionNoUnroll\";\n        public const string WorkloadActionUnrollMethodName = \"WorkloadActionUnroll\";\n        public const string WorkloadActionNoUnrollMethodName = \"WorkloadActionNoUnroll\";\n        public const string ForDisassemblyDiagnoserMethodName = \"__ForDisassemblyDiagnoser__\";\n        public const string InvokeCountParamName = \"invokeCount\";\n\n        public const string DummyParamName = \"_\";\n\n        public const string GlobalSetupMethodName = \"GlobalSetup\";\n        public const string GlobalCleanupMethodName = \"GlobalCleanup\";\n        public const string IterationSetupMethodName = \"IterationSetup\";\n        public const string IterationCleanupMethodName = \"IterationCleanup\";\n\n        public const string RunMethodName = \"Run\";\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/InProcess/Emit/Implementation/Runnable/RunnableProgram.cs",
    "content": "﻿using System;\nusing System.Reflection;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Toolchains.Parameters;\nusing static BenchmarkDotNet.Toolchains.InProcess.Emit.Implementation.RunnableConstants;\nusing static BenchmarkDotNet.Toolchains.InProcess.Emit.Implementation.RunnableReflectionHelpers;\n\nnamespace BenchmarkDotNet.Toolchains.InProcess.Emit.Implementation\n{\n    internal class RunnableProgram\n    {\n        internal static int Run(Assembly partitionAssembly, IHost host, ExecuteParameters parameters)\n        {\n            // the first thing to do is to let diagnosers hook in before anything happens\n            // so all jit-related diagnosers can catch first jit compilation!\n            host.BeforeAnythingElse();\n\n            try\n            {\n                // we are not using Runnable here in any direct way in order to avoid strong dependency Main<=>Runnable\n                // which could cause the jitting/assembly loading to happen before we do anything\n                // we have some jitting diagnosers and we want them to catch all the informations!!\n\n                var runCallback = GetRunCallback(parameters.BenchmarkId, partitionAssembly);\n\n                runCallback.Invoke(null, [host, parameters]);\n                return 0;\n            }\n            catch (Exception oom) when (\n                oom is OutOfMemoryException ||\n                oom is TargetInvocationException reflection && reflection.InnerException is OutOfMemoryException)\n            {\n                DumpOutOfMemory(host, oom);\n                return -1;\n            }\n            catch (Exception ex)\n            {\n                DumpError(host, ex);\n                return -1;\n            }\n            finally\n            {\n                host.AfterAll();\n            }\n        }\n\n        private static MethodInfo GetRunCallback(\n            BenchmarkId benchmarkId, Assembly partitionAssembly)\n        {\n            var runnableType = partitionAssembly.GetType(GetRunnableTypeName(benchmarkId))!;\n\n            var runnableMethod = runnableType.GetMethod(RunMethodName, BindingFlagsPublicStatic)!;\n\n            return runnableMethod;\n        }\n\n        private static string GetRunnableTypeName(BenchmarkId benchmarkId)\n        {\n            return EmittedTypePrefix + benchmarkId;\n        }\n\n        private static void DumpOutOfMemory(IHost host, Exception oom)\n        {\n            host.WriteLine();\n            host.WriteLine(\"OutOfMemoryException!\");\n            host.WriteLine(\n                \"BenchmarkDotNet continues to run additional iterations until desired accuracy level is achieved. It's possible only if the benchmark method doesn't have any side-effects.\");\n            host.WriteLine(\n                \"If your benchmark allocates memory and keeps it alive, you are creating a memory leak.\");\n            host.WriteLine(\n                \"You should redesign your benchmark and remove the side-effects. You can use `OperationsPerInvoke`, `IterationSetup` and `IterationCleanup` to do that.\");\n            host.WriteLine();\n            host.WriteLine(oom.ToString());\n        }\n\n        private static void DumpError(IHost host, Exception ex)\n        {\n            host.WriteLine();\n            host.WriteLine(ex.ToString());\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/InProcess/Emit/Implementation/Runnable/RunnableReflectionHelpers.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing System.Reflection;\nusing BenchmarkDotNet.Parameters;\nusing BenchmarkDotNet.Running;\nusing static BenchmarkDotNet.Toolchains.InProcess.Emit.Implementation.RunnableConstants;\n\nnamespace BenchmarkDotNet.Toolchains.InProcess.Emit.Implementation\n{\n    internal static class RunnableReflectionHelpers\n    {\n        public const BindingFlags BindingFlagsNonPublicInstance = BindingFlags.NonPublic | BindingFlags.Instance;\n        public const BindingFlags BindingFlagsPublicInstance = BindingFlags.Public | BindingFlags.Instance;\n        public const BindingFlags BindingFlagsPublicStatic = BindingFlags.Public | BindingFlags.Static;\n        public const BindingFlags BindingFlagsAllStatic = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static;\n        public const BindingFlags BindingFlagsAllInstance = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;\n\n        private static object? TryChangeType(object? value, Type targetType)\n        {\n            try\n            {\n                return targetType.IsInstanceOfType(value)\n                    ? value\n                    : Convert.ChangeType(value, targetType);\n            }\n            catch (InvalidCastException)\n            {\n            }\n\n            if (value != null)\n            {\n                var implicitOp = GetImplicitConversionOpFromTo(value.GetType(), targetType);\n                if (implicitOp != null)\n                    return implicitOp.Invoke(null, [value])!;\n            }\n\n            return value;\n        }\n\n        public static bool IsRefLikeType(Type t)\n        {\n            return t.IsValueType\n                && t.GetCustomAttributes().Any(a => a.GetType().FullName == IsByRefLikeAttributeTypeName);\n        }\n\n        public static MethodInfo? GetImplicitConversionOpFromTo(Type from, Type to)\n        {\n            return GetImplicitConversionOpCore(to, from, to)\n                ?? GetImplicitConversionOpCore(from, from, to);\n        }\n\n        private static MethodInfo? GetImplicitConversionOpCore(Type owner, Type from, Type to)\n        {\n            return owner.GetMethods(BindingFlagsPublicStatic)\n                .FirstOrDefault(m =>\n                    m.Name == OpImplicitMethodName\n                    && m.ReturnType == to\n                    && m.GetParameters().Single().ParameterType == from);\n        }\n\n        public static void SetArgumentField<T>(\n            T instance,\n            BenchmarkCase benchmarkCase,\n            ParameterInfo argInfo,\n            int argIndex\n        )\n            where T : notnull\n        {\n            var argValue = benchmarkCase.Parameters.GetArgument(argInfo.Name!);\n            var type = instance.GetType();\n            var argName = ArgFieldPrefix + argIndex;\n            if (type.GetField(argName, BindingFlagsNonPublicInstance) is var f && f != null)\n            {\n                f.SetValue(instance, TryChangeType(argValue.Value, f.FieldType));\n            }\n            else\n            {\n                throw new InvalidOperationException($\"Can't find arg member for {argInfo.Name}.\");\n            }\n        }\n\n        public static void SetParameter<T>(\n            T instance,\n            ParameterInstance paramInfo\n        )\n            where T : notnull\n        {\n            var instanceArg = paramInfo.IsStatic ? null : (object)instance;\n            var bindingFlags = paramInfo.IsStatic ? BindingFlagsAllStatic : BindingFlagsAllInstance;\n            var type = instance.GetType();\n\n            if (type.GetProperty(paramInfo.Name, bindingFlags) is var p && p != null)\n            {\n                p.SetValue(instanceArg, TryChangeType(paramInfo.Value, p.PropertyType));\n            }\n            else if (type.GetField(paramInfo.Name, bindingFlags) is var f && f != null)\n            {\n                f.SetValue(instanceArg, TryChangeType(paramInfo.Value, f.FieldType));\n            }\n            else\n            {\n                throw new InvalidOperationException($\"Can't find a member {paramInfo.ToDisplayText()}.\");\n            }\n        }\n\n        public static Action CallbackFromField<T>(T instance, string memberName)\n            where T : notnull\n        {\n            return GetFieldValueCore<T, Action>(instance, memberName);\n        }\n\n        public static Action<long> LoopCallbackFromMethod<T>(T instance, string memberName)\n            where T : notnull\n        {\n            return GetDelegateCore<T, Action<long>>(instance, memberName);\n        }\n\n        private static TResult GetFieldValueCore<T, TResult>(T instance, string memberName)\n            where T : notnull\n        {\n            var result = instance.GetType().GetField(\n                memberName,\n                BindingFlagsAllInstance);\n            if (result == null)\n                throw new InvalidOperationException($\"Can't find a member {memberName}.\");\n\n            return (TResult)result.GetValue(instance)!; // TODO: Currently this method is used to get Action field and assume it's not null.\n        }\n\n        private static TDelegate GetDelegateCore<T, TDelegate>(T instance, string memberName)\n            where T : notnull\n        {\n            var result = instance.GetType().GetMethod(\n                memberName,\n                BindingFlagsAllInstance);\n            if (result == null)\n                throw new InvalidOperationException($\"Can't find a member {memberName}.\");\n\n            return (TDelegate)(object)Delegate.CreateDelegate(typeof(TDelegate), instance, result);\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/InProcess/Emit/Implementation/Runnable/RunnableReuse.cs",
    "content": "﻿using System.Linq;\nusing BenchmarkDotNet.Diagnosers;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Exporters;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Toolchains.Parameters;\nusing BenchmarkDotNet.Validators;\nusing static BenchmarkDotNet.Toolchains.InProcess.Emit.Implementation.RunnableConstants;\nusing static BenchmarkDotNet.Toolchains.InProcess.Emit.Implementation.RunnableReflectionHelpers;\n\nnamespace BenchmarkDotNet.Toolchains.InProcess.Emit.Implementation\n{\n    public static class RunnableReuse\n    {\n        public static (Job, EngineParameters, IEngineFactory) PrepareForRun<T>(T instance, IHost host, ExecuteParameters parameters)\n            where T : notnull\n        {\n            var benchmarkCase = parameters.BenchmarkCase;\n            FillObjectMembers(instance, benchmarkCase);\n\n            DumpEnvironment(host);\n\n            var job = CreateJob(benchmarkCase);\n            DumpJob(host, job);\n\n            var errors = BenchmarkProcessValidator.Validate(job, instance);\n            if (ValidationErrorReporter.ReportIfAny(errors, host))\n                return default;\n\n            var compositeInProcessDiagnoserHandler = new CompositeInProcessDiagnoserHandler(\n                parameters.CompositeInProcessDiagnoser.InProcessDiagnosers\n                    .Select((d, i) => InProcessDiagnoserRouter.Create(d, benchmarkCase, i))\n                    .Where(r => r.handler != null)\n                    .ToArray(),\n                host,\n                parameters.DiagnoserRunMode,\n                new InProcessDiagnoserActionArgs(instance)\n            );\n            if (parameters.DiagnoserRunMode == Diagnosers.RunMode.SeparateLogic)\n            {\n                compositeInProcessDiagnoserHandler.Handle(BenchmarkSignal.SeparateLogic);\n                return default;\n            }\n            compositeInProcessDiagnoserHandler.Handle(BenchmarkSignal.BeforeEngine);\n\n            var engineParameters = CreateEngineParameters(instance, benchmarkCase, host, compositeInProcessDiagnoserHandler);\n            var engineFactory = GetEngineFactory(benchmarkCase);\n\n            return (job, engineParameters, engineFactory);\n        }\n\n        public static void FillObjectMembers<T>(T instance, BenchmarkCase benchmarkCase)\n            where T : notnull\n        {\n            var argIndex = 0;\n            foreach (var argInfo in benchmarkCase.Descriptor.WorkloadMethod.GetParameters())\n            {\n                SetArgumentField(instance, benchmarkCase, argInfo, argIndex);\n                argIndex++;\n            }\n\n            foreach (var paramInfo in benchmarkCase.Parameters.Items\n                .Where(parameter => !parameter.IsArgument))\n            {\n                SetParameter(instance, paramInfo);\n            }\n        }\n\n        private static void DumpEnvironment(IHost host)\n        {\n            host.WriteLine();\n            foreach (var infoLine in BenchmarkEnvironmentInfo.GetCurrent().ToFormattedString())\n            {\n                host.WriteLine(\"// {0}\", infoLine);\n            }\n        }\n\n        private static Job CreateJob(BenchmarkCase benchmarkCase)\n        {\n            var job = new Job();\n            job.Apply(benchmarkCase.Job);\n            job.Freeze();\n            return job;\n        }\n\n        private static void DumpJob(IHost host, Job job)\n        {\n            host.WriteLine(\"// Job: {0}\", job.DisplayInfo);\n            host.WriteLine();\n        }\n\n        private static IEngineFactory GetEngineFactory(BenchmarkCase benchmarkCase)\n        {\n            return benchmarkCase.Job.ResolveValue(\n                InfrastructureMode.EngineFactoryCharacteristic,\n                InfrastructureResolver.Instance)!;\n        }\n\n        private static EngineParameters CreateEngineParameters<T>(T instance, BenchmarkCase benchmarkCase, IHost host, CompositeInProcessDiagnoserHandler inProcessDiagnoserHandler)\n            where T : notnull\n            => new()\n            {\n                Host = host,\n                WorkloadActionUnroll = LoopCallbackFromMethod(instance, WorkloadActionUnrollMethodName),\n                WorkloadActionNoUnroll = LoopCallbackFromMethod(instance, WorkloadActionNoUnrollMethodName),\n                OverheadActionNoUnroll = LoopCallbackFromMethod(instance, OverheadActionNoUnrollMethodName),\n                OverheadActionUnroll = LoopCallbackFromMethod(instance, OverheadActionUnrollMethodName),\n                GlobalSetupAction = CallbackFromField(instance, GlobalSetupActionFieldName),\n                GlobalCleanupAction = CallbackFromField(instance, GlobalCleanupActionFieldName),\n                IterationSetupAction = CallbackFromField(instance, IterationSetupActionFieldName),\n                IterationCleanupAction = CallbackFromField(instance, IterationCleanupActionFieldName),\n                TargetJob = benchmarkCase.Job,\n                OperationsPerInvoke = benchmarkCase.Descriptor.OperationsPerInvoke,\n                RunExtraIteration = benchmarkCase.Config.HasExtraIterationDiagnoser(benchmarkCase),\n                BenchmarkName = FullNameProvider.GetBenchmarkName(benchmarkCase),\n                InProcessDiagnoserHandler = inProcessDiagnoserHandler\n            };\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/InProcess/Emit/InProcessEmitArtifactsPath.cs",
    "content": "﻿using System.Reflection;\n\nnamespace BenchmarkDotNet.Toolchains.InProcess.Emit\n{\n    public class InProcessEmitArtifactsPath : ArtifactsPaths\n    {\n        public Assembly GeneratedAssembly { get; }\n\n        public InProcessEmitArtifactsPath(\n            Assembly generatedAssembly,\n            ArtifactsPaths baseArtifacts) : base(\n            baseArtifacts.RootArtifactsFolderPath,\n            baseArtifacts.BuildArtifactsDirectoryPath,\n            baseArtifacts.BinariesDirectoryPath,\n            baseArtifacts.PublishDirectoryPath,\n            baseArtifacts.ProgramCodePath,\n            baseArtifacts.AppConfigPath,\n            baseArtifacts.NuGetConfigPath,\n            baseArtifacts.ProjectFilePath,\n            baseArtifacts.BuildScriptFilePath,\n            baseArtifacts.ExecutablePath,\n            baseArtifacts.ProgramName,\n            baseArtifacts.PackagesDirectoryName)\n        {\n            GeneratedAssembly = generatedAssembly;\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/InProcess/Emit/InProcessEmitBuilder.cs",
    "content": "﻿using System;\nusing System.Reflection;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Toolchains.InProcess.Emit.Implementation;\nusing BenchmarkDotNet.Toolchains.Results;\n\nnamespace BenchmarkDotNet.Toolchains.InProcess.Emit\n{\n    public class InProcessEmitBuilder : IBuilder\n    {\n        public BuildResult Build(GenerateResult generateResult, BuildPartition buildPartition, ILogger logger)\n        {\n            Assembly? assembly = null;\n            Exception? buildError = null;\n            try\n            {\n                assembly = RunnableEmitter.EmitPartitionAssembly(generateResult, buildPartition, logger);\n            }\n            catch (Exception ex)\n            {\n                buildError = ex;\n            }\n\n            if (buildError != null)\n                return BuildResult.Failure(generateResult, buildError);\n\n            // HACK: use custom artifacts path class to pass the generated assembly.\n            return BuildResult.Success(\n                GenerateResult.Success(\n                    new InProcessEmitArtifactsPath(assembly!, generateResult.ArtifactsPaths),\n                    generateResult.ArtifactsToCleanup));\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/InProcess/Emit/InProcessEmitExecutor.cs",
    "content": "﻿using System;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Reflection;\nusing System.Threading;\nusing BenchmarkDotNet.Detectors;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Toolchains.InProcess.Emit.Implementation;\nusing BenchmarkDotNet.Toolchains.Parameters;\nusing BenchmarkDotNet.Toolchains.Results;\n\nnamespace BenchmarkDotNet.Toolchains.InProcess.Emit\n{\n    internal class InProcessEmitExecutor(bool executeOnSeparateThread) : IExecutor\n    {\n        public ExecuteResult Execute(ExecuteParameters executeParameters)\n        {\n            var host = new InProcessHost(executeParameters.BenchmarkCase, executeParameters.Logger, executeParameters.Diagnoser);\n\n            int exitCode = -1;\n            if (executeOnSeparateThread)\n            {\n                var runThread = new Thread(() => exitCode = ExecuteCore(host, executeParameters));\n\n                if (executeParameters.BenchmarkCase.Descriptor.WorkloadMethod.GetCustomAttributes<STAThreadAttribute>(false).Any()\n                    && OsDetector.IsWindows())\n                {\n                    runThread.SetApartmentState(ApartmentState.STA);\n                }\n\n                runThread.IsBackground = true;\n\n                runThread.Start();\n                runThread.Join();\n            }\n            else\n            {\n                exitCode = ExecuteCore(host, executeParameters);\n            }\n            host.HandleInProcessDiagnoserResults(executeParameters.BenchmarkCase, executeParameters.CompositeInProcessDiagnoser);\n\n            return ExecuteResult.FromRunResults(host.RunResults, exitCode);\n        }\n\n        private int ExecuteCore(IHost host, ExecuteParameters parameters)\n        {\n            int exitCode = -1;\n            var process = Process.GetCurrentProcess();\n            var oldPriority = process.PriorityClass;\n            var oldAffinity = process.TryGetAffinity();\n            var thread = Thread.CurrentThread;\n            var oldThreadPriority = thread.Priority;\n\n            var affinity = parameters.BenchmarkCase.Job.ResolveValueAsNullable(EnvironmentMode.AffinityCharacteristic);\n            try\n            {\n                process.TrySetPriority(ProcessPriorityClass.High, parameters.Logger);\n                thread.TrySetPriority(ThreadPriority.Highest, parameters.Logger);\n\n                if (affinity != null)\n                {\n                    process.TrySetAffinity(affinity.Value, parameters.Logger);\n                }\n\n                var generatedAssembly = ((InProcessEmitArtifactsPath)parameters.BuildResult.ArtifactsPaths)\n                    .GeneratedAssembly;\n\n                exitCode = RunnableProgram.Run(generatedAssembly, host, parameters);\n            }\n            catch (Exception ex)\n            {\n                parameters.Logger.WriteLineError($\"// ! {GetType().Name}, exception: {ex}\");\n            }\n            finally\n            {\n                process.TrySetPriority(oldPriority, parameters.Logger);\n                thread.TrySetPriority(oldThreadPriority, parameters.Logger);\n\n                if (affinity != null && oldAffinity != null)\n                {\n                    process.TrySetAffinity(oldAffinity.Value, parameters.Logger);\n                }\n            }\n\n            return exitCode;\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/InProcess/Emit/InProcessEmitGenerator.cs",
    "content": "﻿using BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Toolchains.InProcess.Emit.Implementation;\nusing BenchmarkDotNet.Toolchains.Results;\nusing System;\nusing System.Collections.Generic;\nusing System.IO;\n\nnamespace BenchmarkDotNet.Toolchains.InProcess.Emit\n{\n    public class InProcessEmitGenerator : IGenerator\n    {\n        public GenerateResult GenerateProject(\n            BuildPartition buildPartition,\n            ILogger logger,\n            string rootArtifactsFolderPath)\n        {\n            var artifactsPaths = ArtifactsPaths.Empty;\n            try\n            {\n                artifactsPaths = GetArtifactsPaths(buildPartition, rootArtifactsFolderPath);\n\n                return GenerateResult.Success(artifactsPaths, []);\n            }\n            catch (Exception ex)\n            {\n                logger.WriteLineError($\"Failed to generate partition: {ex}\");\n                return GenerateResult.Failure(artifactsPaths, []);\n            }\n        }\n\n        private string GetBinariesDirectoryPath(string buildArtifactsDirectoryPath) => buildArtifactsDirectoryPath;\n\n        private string GetExecutableExtension() => \".dll\";\n\n        private string GetBuildArtifactsDirectoryPath(BuildPartition buildPartition) => Path.GetDirectoryName(buildPartition.AssemblyLocation)!;\n\n        private ArtifactsPaths GetArtifactsPaths(BuildPartition buildPartition, string rootArtifactsFolderPath)\n        {\n            string programName = buildPartition.ProgramName + RunnableConstants.DynamicAssemblySuffix;\n            string buildArtifactsDirectoryPath = GetBuildArtifactsDirectoryPath(buildPartition);\n            string binariesDirectoryPath =\n                GetBinariesDirectoryPath(buildArtifactsDirectoryPath);\n            string executablePath = Path.Combine(binariesDirectoryPath, $\"{programName}{GetExecutableExtension()}\");\n\n            return new ArtifactsPaths(\n                rootArtifactsFolderPath: rootArtifactsFolderPath,\n                buildArtifactsDirectoryPath: buildArtifactsDirectoryPath,\n                binariesDirectoryPath: binariesDirectoryPath,\n                publishDirectoryPath: \"\",\n                programCodePath: \"\",\n                appConfigPath: \"\",\n                nuGetConfigPath: \"\",\n                projectFilePath: \"\",\n                buildScriptFilePath: \"\",\n                executablePath: executablePath,\n                programName: programName,\n                packagesDirectoryName: \"\");\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/InProcess/Emit/InProcessEmitSettings.cs",
    "content": "﻿namespace BenchmarkDotNet.Toolchains.InProcess.Emit;\n\npublic class InProcessEmitSettings : InProcessSettings\n{\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/InProcess/Emit/InProcessEmitToolchain.cs",
    "content": "﻿using JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Toolchains.InProcess.Emit\n{\n    /// <summary>\n    /// An <see cref=\"IToolchain\"/> to run the benchmarks in-process by emitting IL.\n    /// </summary>\n    [PublicAPI]\n    public class InProcessEmitToolchain : Toolchain\n    {\n        /// <summary>A toolchain instance with default settings.</summary>\n        public static readonly IToolchain Default = new InProcessEmitToolchain(new() { ExecuteOnSeparateThread = true });\n\n        /// <summary>Initializes a new instance of the <see cref=\"InProcessEmitToolchain\" /> class.</summary>\n        /// <param name=\"settings\">The settings to use for the toolchain.</param>\n        public InProcessEmitToolchain(InProcessEmitSettings settings) : base(\n            nameof(InProcessEmitToolchain),\n            new InProcessEmitGenerator(),\n            new InProcessEmitBuilder(),\n            new InProcessEmitExecutor(settings.ExecuteOnSeparateThread))\n        {\n        }\n\n        public override bool IsInProcess => true;\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/InProcess/InProcessHost.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.IO;\nusing System.Runtime.CompilerServices;\nusing System.Text;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Diagnosers;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Portability;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Validators;\n\nnamespace BenchmarkDotNet.Toolchains.InProcess\n{\n    /// <summary>Host API for in-process benchmarks.</summary>\n    /// <seealso cref=\"IHost\"/>\n    internal sealed class InProcessHost : IHost\n    {\n        private readonly ILogger logger;\n        private readonly IDiagnoser? diagnoser;\n        private readonly DiagnoserActionParameters? diagnoserActionParameters;\n        private readonly List<string> inProcessDiagnoserLines = [];\n\n        /// <summary>Creates a new instance of <see cref=\"InProcessHost\"/>.</summary>\n        /// <param name=\"benchmarkCase\">Current benchmark.</param>\n        /// <param name=\"logger\">Logger for informational output.</param>\n        /// <param name=\"diagnoser\">Diagnosers, if attached.</param>\n        public InProcessHost(BenchmarkCase benchmarkCase, ILogger logger, IDiagnoser? diagnoser)\n        {\n            this.logger = logger;\n            this.diagnoser = diagnoser;\n            Config = benchmarkCase.Config;\n\n            if (diagnoser != null)\n                diagnoserActionParameters = new DiagnoserActionParameters(\n                    Process.GetCurrentProcess(),\n                    benchmarkCase,\n                    default);\n        }\n\n        /// <summary>Results of the run.</summary>\n        /// <value>Results of the run.</value>\n        public RunResults RunResults { get; private set; }\n\n        /// <summary>Current config</summary>\n        public IConfig Config { get; set; }\n\n        /// <summary>Passes text to the host.</summary>\n        /// <param name=\"message\">Text to write.</param>\n        public void Write(string message) => logger.Write(message);\n\n        /// <summary>Passes new line to the host.</summary>\n        public void WriteLine() => logger.WriteLine();\n\n        /// <summary>Passes text (new line appended) to the host.</summary>\n        /// <param name=\"message\">Text to write.</param>\n        [MethodImpl(CodeGenHelper.AggressiveOptimizationOption)]\n        public void WriteLine(string message)\n        {\n            logger.WriteLine(message);\n            if (message.StartsWith(CompositeInProcessDiagnoser.HeaderKey)) // Captures both header and results\n            {\n                inProcessDiagnoserLines.Add(message);\n            }\n        }\n\n        /// <summary>Sends notification signal to the host.</summary>\n        /// <param name=\"hostSignal\">The signal to send.</param>\n        [MethodImpl(CodeGenHelper.AggressiveOptimizationOption)]\n        public void SendSignal(HostSignal hostSignal) => diagnoser?.Handle(hostSignal, diagnoserActionParameters!);\n\n        public void SendError(string message) => logger.WriteLine(LogKind.Error, $\"{ValidationErrorReporter.ConsoleErrorPrefix} {message}\");\n\n        /// <summary>Submits run results to the host.</summary>\n        /// <param name=\"runResults\">The run results.</param>\n        public void ReportResults(RunResults runResults)\n        {\n            RunResults = runResults;\n\n            using (var w = new StringWriter())\n            {\n                runResults.Print(w);\n                logger.Write(w.GetStringBuilder().ToString());\n            }\n        }\n\n        // Keep in sync with Broker and WasmExecutor.\n        internal void HandleInProcessDiagnoserResults(BenchmarkCase benchmarkCase, CompositeInProcessDiagnoser compositeInProcessDiagnoser)\n        {\n            var linesEnumerator = inProcessDiagnoserLines.GetEnumerator();\n            while (linesEnumerator.MoveNext())\n            {\n                // Something like \"// InProcessDiagnoser 0 1\"\n                var line = linesEnumerator.Current;\n                string[] lineItems = line.Split(' ');\n                int diagnoserIndex = int.Parse(lineItems[2]);\n                int resultsLinesCount = int.Parse(lineItems[3]);\n                var resultsStringBuilder = new StringBuilder();\n                for (int i = 0; i < resultsLinesCount;)\n                {\n                    // Strip the prepended \"// InProcessDiagnoserResults \".\n                    bool movedNext = linesEnumerator.MoveNext();\n                    Debug.Assert(movedNext);\n                    line = linesEnumerator.Current.Substring(CompositeInProcessDiagnoser.ResultsKey.Length + 1);\n                    resultsStringBuilder.Append(line);\n                    if (++i < resultsLinesCount)\n                    {\n                        resultsStringBuilder.AppendLine();\n                    }\n                }\n                compositeInProcessDiagnoser.DeserializeResults(diagnoserIndex, benchmarkCase, resultsStringBuilder.ToString());\n            }\n        }\n\n        public void Dispose()\n        {\n            // do nothing on purpose\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/InProcess/InProcessSettings.cs",
    "content": "﻿namespace BenchmarkDotNet.Toolchains.InProcess;\n\npublic abstract class InProcessSettings\n{\n    public bool ExecuteOnSeparateThread { get; set; } = true;\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/InProcess/InProcessValidator.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing BenchmarkDotNet.Characteristics;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Toolchains.InProcess.Emit;\nusing BenchmarkDotNet.Toolchains.InProcess.NoEmit;\nusing BenchmarkDotNet.Validators;\n\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Toolchains.InProcess\n{\n    /// <summary>\n    ///     Validator to be used together with <see cref=\"InProcessNoEmitToolchain\" /> or <see cref=\"InProcessEmitToolchain\"/>\n    ///     to proof that the config matches the environment.\n    /// </summary>\n    /// <seealso cref=\"IValidator\" />\n    [PublicAPI]\n    public class InProcessValidator : IValidator\n    {\n        // ReSharper disable HeapView.DelegateAllocation\n        private static readonly IReadOnlyDictionary<Characteristic, Func<Job, Characteristic, string>> ValidationRules =\n            new Dictionary<Characteristic, Func<Job, Characteristic, string>>\n            {\n                { EnvironmentMode.AffinityCharacteristic, DontValidate },\n                { EnvironmentMode.JitCharacteristic, ValidateEnvironment },\n                { EnvironmentMode.PlatformCharacteristic, ValidatePlatform },\n                { EnvironmentMode.RuntimeCharacteristic, ValidateEnvironment },\n                { GcMode.ServerCharacteristic, ValidateEnvironment },\n                { GcMode.ConcurrentCharacteristic, ValidateEnvironment },\n                { GcMode.CpuGroupsCharacteristic, ValidateEnvironment },\n                { GcMode.NoAffinitizeCharacteristic, ValidateEnvironment },\n                { GcMode.HeapAffinitizeMaskCharacteristic, DontValidate },\n                { GcMode.HeapCountCharacteristic, DontValidate },\n                { GcMode.ForceCharacteristic, DontValidate },\n                { GcMode.AllowVeryLargeObjectsCharacteristic, DontValidate },\n                { RunMode.LaunchCountCharacteristic, DontValidate },\n                { RunMode.RunStrategyCharacteristic, DontValidate },\n                { RunMode.WarmupCountCharacteristic, DontValidate },\n                { RunMode.IterationCountCharacteristic, DontValidate },\n                { RunMode.IterationTimeCharacteristic, DontValidate },\n                { RunMode.InvocationCountCharacteristic, DontValidate },\n                { RunMode.UnrollFactorCharacteristic, DontValidate },\n                { AccuracyMode.AnalyzeLaunchVarianceCharacteristic, DontValidate },\n                { AccuracyMode.EvaluateOverheadCharacteristic, DontValidate },\n                { AccuracyMode.MaxRelativeErrorCharacteristic, DontValidate },\n                { AccuracyMode.MaxAbsoluteErrorCharacteristic, DontValidate },\n                { AccuracyMode.MinInvokeCountCharacteristic, DontValidate },\n                { AccuracyMode.MinIterationTimeCharacteristic, DontValidate },\n                { AccuracyMode.OutlierModeCharacteristic, DontValidate },\n                { InfrastructureMode.ClockCharacteristic, DontValidate },\n                { InfrastructureMode.EngineFactoryCharacteristic, DontValidate },\n                { InfrastructureMode.ToolchainCharacteristic, ValidateToolchain }\n            };\n\n        // ReSharper restore HeapView.DelegateAllocation\n\n        private static string DontValidate(Job job, Characteristic characteristic) => \"\";\n\n        private static string ValidateEnvironment(Job job, Characteristic characteristic)\n        {\n            var resolver = EnvironmentResolver.Instance;\n            var actual = resolver.Resolve(Job.Default, characteristic);\n            var expected = resolver.Resolve(job, characteristic);\n            return Equals(actual, expected)\n                ? \"\"\n                : $\"was run as {actual} ({expected} expected). Fix your test runner options.\";\n        }\n\n        private static string ValidatePlatform(Job job, Characteristic characteristic)\n        {\n            if (job.Environment.Platform == Platform.AnyCpu)\n                return \"\";\n\n            return ValidateEnvironment(job, characteristic);\n        }\n\n        private static string ValidateToolchain(Job job, Characteristic characteristic) =>\n            job.Infrastructure.Toolchain is InProcessEmitToolchain\n            || job.Infrastructure.Toolchain is InProcessNoEmitToolchain\n                ? \"\"\n                : $\"should be instance of {nameof(InProcessEmitToolchain)} or {nameof(InProcessNoEmitToolchain)}.\";\n\n        /// <summary>The instance of validator that does NOT fail on error.</summary>\n        public static readonly IValidator DontFailOnError = new InProcessValidator(false);\n\n        /// <summary>The instance of validator that DOES fail on error.</summary>\n        public static readonly IValidator FailOnError = new InProcessValidator(true);\n\n        public static IEnumerable<ValidationError> Validate(BenchmarkCase benchmarkCase)\n        {\n            foreach (var validationError in ValidateJob(benchmarkCase.Job, true))\n            {\n                yield return new ValidationError(\n                    validationError.IsCritical,\n                    validationError.Message,\n                    benchmarkCase);\n            }\n\n            if (benchmarkCase.HasArguments)\n                yield return new ValidationError(true, \"Arguments are not supported by the InProcessToolchain yet, see #687 for more details\", benchmarkCase);\n        }\n\n        private static IEnumerable<ValidationError> ValidateJob(Job job, bool isCritical)\n        {\n            foreach (var characteristic in job.GetCharacteristicsWithValues())\n            {\n                if (ValidationRules.TryGetValue(characteristic, out var validationRule))\n                {\n                    string message = validationRule(job, characteristic);\n                    if (message.IsNotBlank())\n                        yield return new ValidationError(\n                                isCritical,\n                                $\"Job {job}, {characteristic.FullId} {message}\");\n                }\n#if DEBUG\n                else if (characteristic.IsPresentableCharacteristic())\n                {\n                    yield return new ValidationError(\n                        false,\n                        $\"Job {job}, {characteristic.FullId}: no validation rule specified.\");\n                }\n#endif\n            }\n        }\n\n        private InProcessValidator(bool failOnErrors)\n        {\n            TreatsWarningsAsErrors = failOnErrors;\n        }\n\n        /// <summary>Gets a value indicating whether warnings are treated as errors.</summary>\n        /// <value>\n        ///     <c>true</c> if the validator should treat warnings as errors; otherwise, <c>false</c>.\n        /// </value>\n        public bool TreatsWarningsAsErrors { get; }\n\n        /// <summary>Proofs that benchmarks' jobs match the environment.</summary>\n        /// <param name=\"validationParameters\">The validation parameters.</param>\n        /// <returns>Enumerable of validation errors.</returns>\n        public IEnumerable<ValidationError> Validate(ValidationParameters validationParameters)\n        {\n            foreach (var benchmarkWithArguments in validationParameters.Benchmarks.Where(benchmark => benchmark.HasArguments && benchmark.GetToolchain() is InProcessNoEmitToolchain))\n                yield return new ValidationError(true, \"Arguments are not supported by the InProcessNoEmitToolchain, see #687 for more details\", benchmarkWithArguments);\n\n            foreach (var validationError in validationParameters.Config.GetJobs().SelectMany(job => ValidateJob(job, TreatsWarningsAsErrors)))\n                yield return validationError;\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/InProcess/NoEmit/BenchmarkAction.cs",
    "content": "﻿using System;\n\nnamespace BenchmarkDotNet.Toolchains.InProcess.NoEmit\n{\n    /// <summary>Common API to run the Setup/Clean/Idle/Run methods</summary>\n    internal abstract class BenchmarkAction\n    {\n        /// <summary>Gets or sets invoke single callback.</summary>\n        /// <value>Invoke single callback.</value>\n        public Action InvokeSingle { get; protected set; } = default!;\n\n        /// <summary>Gets or sets invoke multiple times callback.</summary>\n        /// <value>Invoke multiple times callback.</value>\n        public Action<long> InvokeUnroll { get; protected set; } = default!;\n        \n        public Action<long> InvokeNoUnroll { get; protected set; } = default!;\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/InProcess/NoEmit/BenchmarkActionFactory.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Threading.Tasks;\n\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Running;\n\nnamespace BenchmarkDotNet.Toolchains.InProcess.NoEmit\n{\n    /// <summary>Helper class that creates <see cref=\"BenchmarkAction\"/> instances. </summary>\n    internal static partial class BenchmarkActionFactory\n    {\n        /// <summary>\n        /// Dispatch method that creates <see cref=\"BenchmarkAction\"/> using\n        /// <paramref name=\"targetMethod\"/> or <paramref name=\"fallbackIdleSignature\"/> to find correct implementation.\n        /// Either <paramref name=\"targetMethod\"/> or <paramref name=\"fallbackIdleSignature\"/> should be not <c>null</c>.\n        /// </summary>\n        private static BenchmarkAction CreateCore(object instance, MethodInfo? targetMethod, MethodInfo? fallbackIdleSignature, int unrollFactor)\n        {\n            PrepareInstanceAndResultType(instance, targetMethod, fallbackIdleSignature, out var resultInstance, out var resultType);\n\n            if (resultType == typeof(void))\n                return new BenchmarkActionVoid(resultInstance, targetMethod, unrollFactor);\n\n            // targetMethod must not be null here. Because it's checked by PrepareInstanceAndResultType.\n            // Following null check is added to suppress nullable annotation errors.\n            ArgumentNullException.ThrowIfNull(targetMethod);\n\n            if (resultType == typeof(void*))\n                return new BenchmarkActionVoidPointer(resultInstance, targetMethod, unrollFactor);\n\n            if (resultType.IsByRef)\n            {\n                var returnParameter = targetMethod.ReturnParameter;\n                // IsReadOnlyAttribute is not part of netstandard2.0, so we need to check the attribute name as usual.\n                if (returnParameter.GetCustomAttributes().Any(attribute => attribute.GetType().FullName == \"System.Runtime.CompilerServices.IsReadOnlyAttribute\"))\n                    return Create(\n                        typeof(BenchmarkActionByRefReadonly<>).MakeGenericType(resultType.GetElementType()!),\n                        resultInstance,\n                        targetMethod,\n                        unrollFactor);\n\n                return Create(\n                    typeof(BenchmarkActionByRef<>).MakeGenericType(resultType.GetElementType()!),\n                    resultInstance,\n                    targetMethod,\n                    unrollFactor);\n            }\n\n            if (resultType == typeof(Task))\n                return new BenchmarkActionTask(resultInstance, targetMethod, unrollFactor);\n\n            if (resultType == typeof(ValueTask))\n                return new BenchmarkActionValueTask(resultInstance, targetMethod, unrollFactor);\n\n            if (resultType.GetTypeInfo().IsGenericType)\n            {\n                var genericType = resultType.GetGenericTypeDefinition();\n                var argType = resultType.GenericTypeArguments[0];\n                if (typeof(Task<>) == genericType)\n                    return Create(\n                        typeof(BenchmarkActionTask<>).MakeGenericType(argType),\n                        resultInstance,\n                        targetMethod,\n                        unrollFactor);\n\n                if (typeof(ValueTask<>).IsAssignableFrom(genericType))\n                    return Create(\n                        typeof(BenchmarkActionValueTask<>).MakeGenericType(argType),\n                        resultInstance,\n                        targetMethod,\n                        unrollFactor);\n            }\n\n            return Create(\n                typeof(BenchmarkAction<>).MakeGenericType(resultType),\n                resultInstance,\n                targetMethod,\n                unrollFactor);\n        }\n\n        private static void PrepareInstanceAndResultType(\n            object? instance,\n            MethodInfo? targetMethod,\n            MethodInfo? fallbackIdleSignature,\n            out object? resultInstance,\n            out Type resultType)\n        {\n            var signature = targetMethod ?? fallbackIdleSignature;\n            if (signature == null)\n                throw new ArgumentNullException(\n                    nameof(fallbackIdleSignature),\n                    $\"Either {nameof(targetMethod)} or  {nameof(fallbackIdleSignature)} should be not null.\");\n\n            if (!signature.IsStatic && instance == null)\n                throw new ArgumentNullException(\n                    nameof(instance),\n                    $\"The {nameof(instance)} parameter should be not null as invocation method is instance method.\");\n\n            resultInstance = signature.IsStatic ? null : instance!;\n            resultType = signature.ReturnType;\n\n            if (resultType == typeof(void))\n            {\n                // DONTTOUCH: async should be checked for target method\n                // as fallbackIdleSignature used for result type detection only.\n                bool isUsingAsyncKeyword = targetMethod?.HasAttribute<AsyncStateMachineAttribute>() ?? false;\n                if (isUsingAsyncKeyword)\n                    throw new NotSupportedException(\"Async void is not supported by design.\");\n            }\n            else if (resultType.IsPointer && resultType != typeof(void*))\n            {\n                throw new NotSupportedException(\"InProcessNoEmitToolchain only supports void* return, not T*\");\n            }\n        }\n\n        /// <summary>Helper to enforce .ctor signature.</summary>\n        private static BenchmarkActionBase Create(Type actionType, object? instance, MethodInfo? method, int unrollFactor) =>\n            (BenchmarkActionBase)Activator.CreateInstance(actionType, instance, method, unrollFactor)!;\n\n        private static void FallbackMethod() { }\n        private static readonly MethodInfo FallbackSignature = new Action(FallbackMethod).GetMethodInfo();\n\n        /// <summary>Creates run benchmark action.</summary>\n        /// <param name=\"descriptor\">Descriptor info.</param>\n        /// <param name=\"instance\">Instance of target.</param>\n        /// <param name=\"unrollFactor\">Unroll factor.</param>\n        /// <returns>Run benchmark action.</returns>\n        public static BenchmarkAction CreateWorkload(Descriptor descriptor, object instance, int unrollFactor) =>\n            CreateCore(instance, descriptor.WorkloadMethod, null, unrollFactor);\n\n        /// <summary>Creates idle benchmark action.</summary>\n        /// <param name=\"descriptor\">Descriptor info.</param>\n        /// <param name=\"instance\">Instance of target.</param>\n        /// <param name=\"unrollFactor\">Unroll factor.</param>\n        /// <returns>Idle benchmark action.</returns>\n        public static BenchmarkAction CreateOverhead(Descriptor descriptor, object instance, int unrollFactor) =>\n            CreateCore(instance, null, FallbackSignature, unrollFactor);\n\n        /// <summary>Creates global setup benchmark action.</summary>\n        /// <param name=\"descriptor\">Descriptor info.</param>\n        /// <param name=\"instance\">Instance of target.</param>\n        /// <returns>Setup benchmark action.</returns>\n        public static BenchmarkAction CreateGlobalSetup(Descriptor descriptor, object instance) =>\n            CreateCore(instance, descriptor.GlobalSetupMethod, FallbackSignature, 1);\n\n        /// <summary>Creates global cleanup benchmark action.</summary>\n        /// <param name=\"descriptor\">Descriptor info.</param>\n        /// <param name=\"instance\">Instance of target.</param>\n        /// <returns>Cleanup benchmark action.</returns>\n        public static BenchmarkAction CreateGlobalCleanup(Descriptor descriptor, object instance) =>\n            CreateCore(instance, descriptor.GlobalCleanupMethod, FallbackSignature, 1);\n\n        /// <summary>Creates global setup benchmark action.</summary>\n        /// <param name=\"descriptor\">Descriptor info.</param>\n        /// <param name=\"instance\">Instance of target.</param>\n        /// <returns>Setup benchmark action.</returns>\n        public static BenchmarkAction CreateIterationSetup(Descriptor descriptor, object instance) =>\n            CreateCore(instance, descriptor.IterationSetupMethod, FallbackSignature, 1);\n\n        /// <summary>Creates global cleanup benchmark action.</summary>\n        /// <param name=\"descriptor\">Descriptor info.</param>\n        /// <param name=\"instance\">Instance of target.</param>\n        /// <returns>Cleanup benchmark action.</returns>\n        public static BenchmarkAction CreateIterationCleanup(Descriptor descriptor, object instance) =>\n            CreateCore(instance, descriptor.IterationCleanupMethod, FallbackSignature, 1);\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/InProcess/NoEmit/BenchmarkActionFactory_Base.cs",
    "content": "﻿using BenchmarkDotNet.Extensions;\nusing System;\nusing System.Reflection;\n\nnamespace BenchmarkDotNet.Toolchains.InProcess.NoEmit\n{\n    /*\n        Design goals of the whole stuff:\n        0. Reusable API to call Setup/Clean/Overhead/Workload actions with arbitrary return value and store the result.\n            Supported ones are: void, T, Task, Task<T>, ValueTask<T>. No input args.\n        1. Overhead signature should match to the benchmark method signature (including static/instance modifier).\n        2. Should work under .Net native. Uses Delegate.Combine instead of emitting the code.\n        3. High data locality and no additional allocations / JIT where possible.\n            This means NO closures allowed, no allocations but in .ctor and for LastCallResult boxing,\n            all state should be stored explicitly as BenchmarkAction's fields.\n        4. There can be multiple benchmark actions per single target instance (workload, globalSetup, globalCleanup methods),\n            so target instantiation is not a responsibility of the benchmark action.\n        5. Implementation should match to the code in BenchmarkProgram.txt.\n     */\n\n    // DONTTOUCH: Be VERY CAREFUL when changing the code.\n    // Please, ensure that the implementation is in sync with content of BenchmarkProgram.txt\n    internal static partial class BenchmarkActionFactory\n    {\n        /// <summary>Base class that provides reusable API for final implementations.</summary>\n        internal abstract class BenchmarkActionBase : BenchmarkAction\n        {\n            protected static TDelegate CreateWorkload<TDelegate>(object? targetInstance, MethodInfo workloadMethod)\n            {\n                if (workloadMethod.IsStatic)\n                    return (TDelegate)(object)workloadMethod.CreateDelegate(typeof(TDelegate));\n\n                return (TDelegate)(object)workloadMethod.CreateDelegate(typeof(TDelegate), targetInstance);\n            }\n\n            protected Action CreateWorkloadOrOverhead(object? instance, MethodInfo? method)\n            {\n                if (method == null)\n                {\n                    return instance == null ? OverheadStatic : OverheadInstance;\n                }\n                return method.IsStatic\n                    ? method.CreateDelegate<Action>()\n                    : method.CreateDelegate<Action>(instance);\n            }\n\n            protected static TDelegate Unroll<TDelegate>(TDelegate callback, int unrollFactor)\n                 where TDelegate : notnull, Delegate\n            {\n                if (unrollFactor <= 1)\n                    return callback;\n\n                var delegates = new Delegate[unrollFactor];\n                for (int i = 0; i < unrollFactor; i++)\n                    delegates[i] = callback;\n\n                return (TDelegate)Delegate.Combine(delegates)!;\n            }\n\n            // must be kept in sync with VoidDeclarationsProvider.IdleImplementation\n            private static void OverheadStatic() { }\n\n            private void OverheadInstance() { }\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/InProcess/NoEmit/BenchmarkActionFactory_Implementations.cs",
    "content": "﻿using BenchmarkDotNet.Portability;\nusing System;\nusing System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Threading.Tasks;\n\nnamespace BenchmarkDotNet.Toolchains.InProcess.NoEmit\n{\n    /*\n        Design goals of the whole stuff: check the comments for BenchmarkActionBase.\n     */\n\n    // DONTTOUCH: Be VERY CAREFUL when changing the code.\n    // Please, ensure that the implementation is in sync with content of BenchmarkProgram.txt\n    internal static partial class BenchmarkActionFactory\n    {\n        internal sealed class BenchmarkActionVoid : BenchmarkActionBase\n        {\n            private readonly Action callback;\n            private readonly Action unrolledCallback;\n\n            public BenchmarkActionVoid(object? instance, MethodInfo? method, int unrollFactor)\n            {\n                callback = CreateWorkloadOrOverhead(instance, method);\n                unrolledCallback = Unroll(callback, unrollFactor);\n                InvokeSingle = callback;\n                InvokeUnroll = WorkloadActionUnroll;\n                InvokeNoUnroll = WorkloadActionNoUnroll;\n            }\n\n            [MethodImpl(CodeGenHelper.AggressiveOptimizationOption)]\n            private void WorkloadActionUnroll(long repeatCount)\n            {\n                for (long i = 0; i < repeatCount; i++)\n                {\n                    unrolledCallback();\n                }\n            }\n\n            [MethodImpl(CodeGenHelper.AggressiveOptimizationOption)]\n            private void WorkloadActionNoUnroll(long repeatCount)\n            {\n                for (long i = 0; i < repeatCount; i++)\n                {\n                    callback();\n                }\n            }\n        }\n\n        internal unsafe class BenchmarkActionVoidPointer : BenchmarkActionBase\n        {\n            private delegate void* PointerFunc();\n\n            private readonly PointerFunc callback;\n            private readonly PointerFunc unrolledCallback;\n\n            public BenchmarkActionVoidPointer(object? instance, MethodInfo method, int unrollFactor)\n            {\n                callback = CreateWorkload<PointerFunc>(instance, method);\n                unrolledCallback = Unroll(callback, unrollFactor);\n                InvokeSingle = () => callback();\n                InvokeUnroll = WorkloadActionUnroll;\n                InvokeNoUnroll = WorkloadActionNoUnroll;\n            }\n\n            [MethodImpl(CodeGenHelper.AggressiveOptimizationOption)]\n            private void WorkloadActionUnroll(long repeatCount)\n            {\n                for (long i = 0; i < repeatCount; i++)\n                {\n                    unrolledCallback();\n                }\n            }\n\n            [MethodImpl(CodeGenHelper.AggressiveOptimizationOption)]\n            private void WorkloadActionNoUnroll(long repeatCount)\n            {\n                for (long i = 0; i < repeatCount; i++)\n                {\n                    callback();\n                }\n            }\n        }\n\n        internal unsafe class BenchmarkActionByRef<T> : BenchmarkActionBase\n#if NET9_0_OR_GREATER\n            where T : allows ref struct\n#endif\n        {\n            private delegate ref T ByRefFunc();\n\n            private readonly ByRefFunc callback;\n            private readonly ByRefFunc unrolledCallback;\n\n            public BenchmarkActionByRef(object? instance, MethodInfo method, int unrollFactor)\n            {\n                callback = CreateWorkload<ByRefFunc>(instance, method);\n                unrolledCallback = Unroll(callback, unrollFactor);\n                InvokeSingle = () => callback();\n                InvokeUnroll = WorkloadActionUnroll;\n                InvokeNoUnroll = WorkloadActionNoUnroll;\n            }\n\n            [MethodImpl(CodeGenHelper.AggressiveOptimizationOption)]\n            private void WorkloadActionUnroll(long repeatCount)\n            {\n                for (long i = 0; i < repeatCount; i++)\n                {\n                    unrolledCallback();\n                }\n            }\n\n            [MethodImpl(CodeGenHelper.AggressiveOptimizationOption)]\n            private void WorkloadActionNoUnroll(long repeatCount)\n            {\n                for (long i = 0; i < repeatCount; i++)\n                {\n                    callback();\n                }\n            }\n        }\n\n        internal unsafe class BenchmarkActionByRefReadonly<T> : BenchmarkActionBase\n#if NET9_0_OR_GREATER\n            where T : allows ref struct\n#endif\n        {\n            private delegate ref readonly T ByRefReadonlyFunc();\n\n            private readonly ByRefReadonlyFunc callback;\n            private readonly ByRefReadonlyFunc unrolledCallback;\n\n            public BenchmarkActionByRefReadonly(object? instance, MethodInfo method, int unrollFactor)\n            {\n                callback = CreateWorkload<ByRefReadonlyFunc>(instance, method);\n                unrolledCallback = Unroll(callback, unrollFactor);\n                InvokeSingle = () => callback();\n                InvokeUnroll = WorkloadActionUnroll;\n                InvokeNoUnroll = WorkloadActionNoUnroll;\n            }\n\n            [MethodImpl(CodeGenHelper.AggressiveOptimizationOption)]\n            private void WorkloadActionUnroll(long repeatCount)\n            {\n                for (long i = 0; i < repeatCount; i++)\n                {\n                    unrolledCallback();\n                }\n            }\n\n            [MethodImpl(CodeGenHelper.AggressiveOptimizationOption)]\n            private void WorkloadActionNoUnroll(long repeatCount)\n            {\n                for (long i = 0; i < repeatCount; i++)\n                {\n                    callback();\n                }\n            }\n        }\n\n        internal class BenchmarkAction<T> : BenchmarkActionBase\n#if NET9_0_OR_GREATER\n            where T : allows ref struct\n#endif\n        {\n            private readonly Func<T> callback;\n            private readonly Func<T> unrolledCallback;\n\n            public BenchmarkAction(object? instance, MethodInfo method, int unrollFactor)\n            {\n                callback = CreateWorkload<Func<T>>(instance, method);\n                unrolledCallback = Unroll(callback, unrollFactor);\n                InvokeSingle = () => callback();\n                InvokeUnroll = WorkloadActionUnroll;\n                InvokeNoUnroll = WorkloadActionNoUnroll;\n            }\n\n            [MethodImpl(CodeGenHelper.AggressiveOptimizationOption)]\n            private void WorkloadActionUnroll(long repeatCount)\n            {\n                for (long i = 0; i < repeatCount; i++)\n                {\n                    unrolledCallback();\n                }\n            }\n\n            [MethodImpl(CodeGenHelper.AggressiveOptimizationOption)]\n            private void WorkloadActionNoUnroll(long repeatCount)\n            {\n                for (long i = 0; i < repeatCount; i++)\n                {\n                    callback();\n                }\n            }\n        }\n\n        internal class BenchmarkActionTask : BenchmarkActionBase\n        {\n            private readonly Func<Task> startTaskCallback;\n            private readonly Action callback;\n            private readonly Action unrolledCallback;\n\n            public BenchmarkActionTask(object? instance, MethodInfo method, int unrollFactor)\n            {\n                if (method == null)\n                {\n                    startTaskCallback = default!;\n                    callback = CreateWorkloadOrOverhead(instance, method);\n                }\n                else\n                {\n                    startTaskCallback = CreateWorkload<Func<Task>>(instance, method);\n                    callback = ExecuteBlocking;\n                }\n                unrolledCallback = Unroll(callback, unrollFactor);\n                InvokeSingle = callback;\n                InvokeUnroll = WorkloadActionUnroll;\n                InvokeNoUnroll = WorkloadActionNoUnroll;\n            }\n\n            // must be kept in sync with TaskDeclarationsProvider.TargetMethodDelegate\n            private void ExecuteBlocking() => Helpers.AwaitHelper.GetResult(startTaskCallback.Invoke());\n\n            [MethodImpl(CodeGenHelper.AggressiveOptimizationOption)]\n            private void WorkloadActionUnroll(long repeatCount)\n            {\n                for (long i = 0; i < repeatCount; i++)\n                {\n                    unrolledCallback();\n                }\n            }\n\n            [MethodImpl(CodeGenHelper.AggressiveOptimizationOption)]\n            private void WorkloadActionNoUnroll(long repeatCount)\n            {\n                for (long i = 0; i < repeatCount; i++)\n                {\n                    callback();\n                }\n            }\n        }\n\n        internal class BenchmarkActionTask<T> : BenchmarkActionBase\n        {\n            private readonly Func<Task<T>> startTaskCallback;\n            private readonly Action callback;\n            private readonly Action unrolledCallback;\n\n            public BenchmarkActionTask(object? instance, MethodInfo method, int unrollFactor)\n            {\n                if (method == null)\n                {\n                    startTaskCallback = default!;\n                    callback = CreateWorkloadOrOverhead(instance, method);\n                }\n                else\n                {\n                    startTaskCallback = CreateWorkload<Func<Task<T>>>(instance, method);\n                    callback = ExecuteBlocking;\n                }\n                unrolledCallback = Unroll(callback, unrollFactor);\n                InvokeSingle = callback;\n                InvokeUnroll = WorkloadActionUnroll;\n                InvokeNoUnroll = WorkloadActionNoUnroll;\n            }\n\n            // must be kept in sync with TaskDeclarationsProvider.TargetMethodDelegate\n            private void ExecuteBlocking() => Helpers.AwaitHelper.GetResult(startTaskCallback.Invoke());\n\n            [MethodImpl(CodeGenHelper.AggressiveOptimizationOption)]\n            private void WorkloadActionUnroll(long repeatCount)\n            {\n                for (long i = 0; i < repeatCount; i++)\n                {\n                    unrolledCallback();\n                }\n            }\n\n            [MethodImpl(CodeGenHelper.AggressiveOptimizationOption)]\n            private void WorkloadActionNoUnroll(long repeatCount)\n            {\n                for (long i = 0; i < repeatCount; i++)\n                {\n                    callback();\n                }\n            }\n        }\n\n        internal class BenchmarkActionValueTask : BenchmarkActionBase\n        {\n            private readonly Func<ValueTask> startTaskCallback;\n            private readonly Action callback;\n            private readonly Action unrolledCallback;\n\n            public BenchmarkActionValueTask(object? instance, MethodInfo method, int unrollFactor)\n            {\n                if (method == null)\n                {\n                    startTaskCallback = default!;\n                    callback = CreateWorkloadOrOverhead(instance, method);\n                }\n                else\n                {\n                    startTaskCallback = CreateWorkload<Func<ValueTask>>(instance, method);\n                    callback = ExecuteBlocking;\n                }\n                unrolledCallback = Unroll(callback, unrollFactor);\n                InvokeSingle = callback;\n                InvokeUnroll = WorkloadActionUnroll;\n                InvokeNoUnroll = WorkloadActionNoUnroll;\n            }\n\n            // must be kept in sync with TaskDeclarationsProvider.TargetMethodDelegate\n            private void ExecuteBlocking() => Helpers.AwaitHelper.GetResult(startTaskCallback.Invoke());\n\n            [MethodImpl(CodeGenHelper.AggressiveOptimizationOption)]\n            private void WorkloadActionUnroll(long repeatCount)\n            {\n                for (long i = 0; i < repeatCount; i++)\n                {\n                    unrolledCallback();\n                }\n            }\n\n            [MethodImpl(CodeGenHelper.AggressiveOptimizationOption)]\n            private void WorkloadActionNoUnroll(long repeatCount)\n            {\n                for (long i = 0; i < repeatCount; i++)\n                {\n                    callback();\n                }\n            }\n        }\n\n        internal class BenchmarkActionValueTask<T> : BenchmarkActionBase\n        {\n            private readonly Func<ValueTask<T>> startTaskCallback;\n            private readonly Action callback;\n            private readonly Action unrolledCallback;\n\n            public BenchmarkActionValueTask(object? instance, MethodInfo method, int unrollFactor)\n            {\n                if (method == null)\n                {\n                    startTaskCallback = default!;\n                    callback = CreateWorkloadOrOverhead(instance, method);\n                }\n                else\n                {\n                    startTaskCallback = CreateWorkload<Func<ValueTask<T>>>(instance, method);\n                    callback = ExecuteBlocking;\n                }\n                unrolledCallback = Unroll(callback, unrollFactor);\n                InvokeSingle = callback;\n                InvokeUnroll = WorkloadActionUnroll;\n                InvokeNoUnroll = WorkloadActionNoUnroll;\n            }\n\n            // must be kept in sync with TaskDeclarationsProvider.TargetMethodDelegate\n            private void ExecuteBlocking() => Helpers.AwaitHelper.GetResult(startTaskCallback.Invoke());\n\n            [MethodImpl(CodeGenHelper.AggressiveOptimizationOption)]\n            private void WorkloadActionUnroll(long repeatCount)\n            {\n                for (long i = 0; i < repeatCount; i++)\n                {\n                    unrolledCallback();\n                }\n            }\n\n            [MethodImpl(CodeGenHelper.AggressiveOptimizationOption)]\n            private void WorkloadActionNoUnroll(long repeatCount)\n            {\n                for (long i = 0; i < repeatCount; i++)\n                {\n                    callback();\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/InProcess/NoEmit/InProcessNoEmitBuilder.cs",
    "content": "﻿using BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Toolchains.Results;\n\nnamespace BenchmarkDotNet.Toolchains.InProcess.NoEmit\n{\n    /// <summary>\n    /// In process (no emit) toolchain builder\n    /// </summary>\n    /// <seealso cref=\"BenchmarkDotNet.Toolchains.IBuilder\" />\n    public class InProcessNoEmitBuilder : IBuilder\n    {\n        /// <summary>always returns success</summary>\n        public BuildResult Build(GenerateResult generateResult, BuildPartition buildPartition, ILogger logger)\n            => BuildResult.Success(generateResult);\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/InProcess/NoEmit/InProcessNoEmitExecutor.cs",
    "content": "﻿using System;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Reflection;\nusing System.Threading;\nusing BenchmarkDotNet.Detectors;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Toolchains.Parameters;\nusing BenchmarkDotNet.Toolchains.Results;\n\nnamespace BenchmarkDotNet.Toolchains.InProcess.NoEmit\n{\n    internal class InProcessNoEmitExecutor(bool executeOnSeparateThread) : IExecutor\n    {\n        public ExecuteResult Execute(ExecuteParameters executeParameters)\n        {\n            var host = new InProcessHost(executeParameters.BenchmarkCase, executeParameters.Logger, executeParameters.Diagnoser);\n\n            int exitCode = -1;\n            if (executeOnSeparateThread)\n            {\n                var runThread = new Thread(() => exitCode = ExecuteCore(host, executeParameters));\n\n                if (executeParameters.BenchmarkCase.Descriptor.WorkloadMethod.GetCustomAttributes<STAThreadAttribute>(false).Any()\n                    && OsDetector.IsWindows())\n                {\n                    runThread.SetApartmentState(ApartmentState.STA);\n                }\n\n                runThread.IsBackground = true;\n\n                runThread.Start();\n                runThread.Join();\n            }\n            else\n            {\n                exitCode = ExecuteCore(host, executeParameters);\n            }\n\n            host.HandleInProcessDiagnoserResults(executeParameters.BenchmarkCase, executeParameters.CompositeInProcessDiagnoser);\n\n            return ExecuteResult.FromRunResults(host.RunResults, exitCode);\n        }\n\n        private int ExecuteCore(IHost host, ExecuteParameters parameters)\n        {\n            int exitCode = -1;\n            var process = Process.GetCurrentProcess();\n            var oldPriority = process.PriorityClass;\n            var oldAffinity = process.TryGetAffinity();\n            var thread = Thread.CurrentThread;\n            var oldThreadPriority = thread.Priority;\n\n            var affinity = parameters.BenchmarkCase.Job.ResolveValueAsNullable(EnvironmentMode.AffinityCharacteristic);\n            try\n            {\n                process.TrySetPriority(ProcessPriorityClass.High, parameters.Logger);\n                thread.TrySetPriority(ThreadPriority.Highest, parameters.Logger);\n\n                if (affinity != null)\n                {\n                    process.TrySetAffinity(affinity.Value, parameters.Logger);\n                }\n\n                exitCode = InProcessNoEmitRunner.Run(host, parameters);\n            }\n            catch (Exception ex)\n            {\n                parameters.Logger.WriteLineError($\"// ! {GetType().Name}, exception: {ex}\");\n            }\n            finally\n            {\n                process.TrySetPriority(oldPriority, parameters.Logger);\n                thread.TrySetPriority(oldThreadPriority, parameters.Logger);\n\n                if (affinity != null && oldAffinity != null)\n                {\n                    process.TrySetAffinity(oldAffinity.Value, parameters.Logger);\n                }\n            }\n\n            return exitCode;\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/InProcess/NoEmit/InProcessNoEmitGenerator.cs",
    "content": "﻿using System;\n\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Toolchains.Results;\n\nnamespace BenchmarkDotNet.Toolchains.InProcess.NoEmit\n{\n    /// <summary>\n    /// Implementation of <see cref=\"IGenerator\"/> for in-process (no emit) toolchain.\n    /// </summary>\n    public class InProcessNoEmitGenerator : IGenerator\n    {\n        /// <summary>returns a success</summary>\n        public GenerateResult GenerateProject(BuildPartition buildPartition, ILogger logger, string rootArtifactsFolderPath)\n            => GenerateResult.Success(ArtifactsPaths.Empty, artifactsToCleanup: []);\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/InProcess/NoEmit/InProcessNoEmitRunner.cs",
    "content": "using System;\nusing System.Diagnostics.CodeAnalysis;\nusing System.Linq;\nusing System.Reflection;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Exporters;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Toolchains.Parameters;\nusing BenchmarkDotNet.Validators;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Toolchains.InProcess.NoEmit\n{\n    /// <summary>\n    /// In-process (no emit) toolchain runner\n    /// </summary>\n    internal class InProcessNoEmitRunner\n    {\n        [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(Runnable))]\n        public static int Run(IHost host, ExecuteParameters parameters)\n        {\n            // the first thing to do is to let diagnosers hook in before anything happens\n            // so all jit-related diagnosers can catch first jit compilation!\n            host.BeforeAnythingElse();\n\n            try\n            {\n                // we are not using Runnable here in any direct way in order to avoid strong dependency Main<=>Runnable\n                // which could cause the jitting/assembly loading to happen before we do anything\n                // we have some jitting diagnosers and we want them to catch all the informations!!\n\n                string inProcessRunnableTypeName = $\"{typeof(InProcessNoEmitRunner).FullName}+{nameof(Runnable)}\";\n                var type = typeof(InProcessNoEmitRunner).GetTypeInfo().Assembly.GetType(inProcessRunnableTypeName)\n                    ?? throw new InvalidOperationException($\"Bug: type {inProcessRunnableTypeName} not found.\");\n\n                var methodInfo = type.GetMethod(nameof(Runnable.RunCore), BindingFlags.Public | BindingFlags.Static)\n                    ?? throw new InvalidOperationException($\"Bug: method {nameof(Runnable.RunCore)} in {inProcessRunnableTypeName} not found.\");\n                methodInfo.Invoke(null, [host, parameters]);\n\n                return 0;\n            }\n            catch (Exception oom) when (oom is OutOfMemoryException || oom is TargetInvocationException reflection && reflection.InnerException is OutOfMemoryException)\n            {\n                host.WriteLine();\n                host.WriteLine(\"OutOfMemoryException!\");\n                host.WriteLine(\"BenchmarkDotNet continues to run additional iterations until desired accuracy level is achieved. It's possible only if the benchmark method doesn't have any side-effects.\");\n                host.WriteLine(\"If your benchmark allocates memory and keeps it alive, you are creating a memory leak.\");\n                host.WriteLine(\"You should redesign your benchmark and remove the side-effects. You can use `OperationsPerInvoke`, `IterationSetup` and `IterationCleanup` to do that.\");\n                host.WriteLine();\n                host.WriteLine(oom.ToString());\n\n                return -1;\n            }\n            catch (Exception ex)\n            {\n                host.WriteLine();\n                host.WriteLine(ex.ToString());\n                return -1;\n            }\n            finally\n            {\n                host.AfterAll();\n            }\n        }\n\n        /// <summary>Fills the properties of the instance of the object used to run the benchmark.</summary>\n        /// <param name=\"instance\">The instance.</param>\n        /// <param name=\"benchmarkCase\">The benchmark.</param>\n        internal static void FillMembers(object instance, BenchmarkCase benchmarkCase)\n        {\n            foreach (var parameter in benchmarkCase.Parameters.Items)\n            {\n                var flags = BindingFlags.Public;\n                flags |= parameter.IsStatic ? BindingFlags.Static : BindingFlags.Instance;\n\n                var targetType = benchmarkCase.Descriptor.Type;\n                var paramProperty = targetType.GetProperty(parameter.Name, flags);\n\n                if (paramProperty == null)\n                {\n                    var paramField = targetType.GetField(parameter.Name, flags);\n                    if (paramField == null)\n                        throw new InvalidOperationException(\n                            $\"Type {targetType.FullName}: no property or field {parameter.Name} found.\");\n\n                    var callInstance = paramField.IsStatic ? null : instance;\n                    paramField.SetValue(callInstance, parameter.Value);\n                }\n                else\n                {\n                    var setter = paramProperty.GetSetMethod();\n                    if (setter == null)\n                        throw new InvalidOperationException(\n                            $\"Type {targetType.FullName}: no settable property {parameter.Name} found.\");\n\n                    var callInstance = setter.IsStatic ? null : instance;\n                    setter.Invoke(callInstance, [parameter.Value]);\n                }\n            }\n        }\n\n        [UsedImplicitly]\n        private static class Runnable\n        {\n            public static void RunCore(IHost host, ExecuteParameters parameters)\n            {\n                var benchmarkCase = parameters.BenchmarkCase;\n                var target = benchmarkCase.Descriptor;\n                var job = benchmarkCase.Job; // TODO: filter job (same as SourceCodePresenter does)?\n                int unrollFactor = benchmarkCase.Job.ResolveValue(RunMode.UnrollFactorCharacteristic, EnvironmentResolver.Instance);\n\n                // DONTTOUCH: these should be allocated together\n                var instance = Activator.CreateInstance(benchmarkCase.Descriptor.Type)!;\n                var workloadAction = BenchmarkActionFactory.CreateWorkload(target, instance, unrollFactor);\n                var overheadAction = BenchmarkActionFactory.CreateOverhead(target, instance, unrollFactor);\n                var globalSetupAction = BenchmarkActionFactory.CreateGlobalSetup(target, instance);\n                var globalCleanupAction = BenchmarkActionFactory.CreateGlobalCleanup(target, instance);\n                var iterationSetupAction = BenchmarkActionFactory.CreateIterationSetup(target, instance);\n                var iterationCleanupAction = BenchmarkActionFactory.CreateIterationCleanup(target, instance);\n\n                FillMembers(instance, benchmarkCase);\n\n                host.WriteLine();\n                foreach (string infoLine in BenchmarkEnvironmentInfo.GetCurrent().ToFormattedString())\n                    host.WriteLine(\"// {0}\", infoLine);\n                host.WriteLine(\"// Job: {0}\", job.DisplayInfo);\n                host.WriteLine();\n\n                var errors = BenchmarkProcessValidator.Validate(job, instance);\n                if (ValidationErrorReporter.ReportIfAny(errors, host))\n                    return;\n\n                var compositeInProcessDiagnoserHandler = new Diagnosers.CompositeInProcessDiagnoserHandler(\n                    parameters.CompositeInProcessDiagnoser.InProcessDiagnosers\n                        .Select((d, i) => Diagnosers.InProcessDiagnoserRouter.Create(d, benchmarkCase, i))\n                        .Where(r => r.handler != null)\n                        .ToArray(),\n                    host,\n                    parameters.DiagnoserRunMode,\n                    new Diagnosers.InProcessDiagnoserActionArgs(instance)\n                );\n                if (parameters.DiagnoserRunMode == Diagnosers.RunMode.SeparateLogic)\n                {\n                    compositeInProcessDiagnoserHandler.Handle(BenchmarkSignal.SeparateLogic);\n                    return;\n                }\n                compositeInProcessDiagnoserHandler.Handle(BenchmarkSignal.BeforeEngine);\n\n                var engineParameters = new EngineParameters\n                {\n                    Host = host,\n                    WorkloadActionNoUnroll = workloadAction.InvokeNoUnroll,\n                    WorkloadActionUnroll = workloadAction.InvokeUnroll,\n                    OverheadActionNoUnroll = overheadAction.InvokeNoUnroll,\n                    OverheadActionUnroll = overheadAction.InvokeUnroll,\n                    GlobalSetupAction = globalSetupAction.InvokeSingle,\n                    GlobalCleanupAction = globalCleanupAction.InvokeSingle,\n                    IterationSetupAction = iterationSetupAction.InvokeSingle,\n                    IterationCleanupAction = iterationCleanupAction.InvokeSingle,\n                    TargetJob = job,\n                    OperationsPerInvoke = target.OperationsPerInvoke,\n                    RunExtraIteration = benchmarkCase.Config.HasExtraIterationDiagnoser(benchmarkCase),\n                    BenchmarkName = FullNameProvider.GetBenchmarkName(benchmarkCase),\n                    InProcessDiagnoserHandler = compositeInProcessDiagnoserHandler\n                };\n\n                var results = job\n                    .ResolveValue(InfrastructureMode.EngineFactoryCharacteristic, InfrastructureResolver.Instance)!\n                    .Create(engineParameters)\n                    .Run();\n                host.ReportResults(results); // printing costs memory, do this after runs\n\n                compositeInProcessDiagnoserHandler.Handle(BenchmarkSignal.AfterEngine);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/InProcess/NoEmit/InProcessNoEmitSettings.cs",
    "content": "﻿namespace BenchmarkDotNet.Toolchains.InProcess.NoEmit;\n\npublic class InProcessNoEmitSettings : InProcessSettings\n{\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/InProcess/NoEmit/InProcessNoEmitToolchain.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing BenchmarkDotNet.Characteristics;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Validators;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Toolchains.InProcess.NoEmit\n{\n    /// <summary>\n    /// An <see cref=\"IToolchain\"/> to run the benchmarks in-process by reflection.\n    /// </summary>\n    [PublicAPI]\n    public sealed class InProcessNoEmitToolchain : IToolchain\n    {\n        /// <summary>A toolchain instance with default settings.</summary>\n        public static readonly IToolchain Default = new InProcessNoEmitToolchain(new() { ExecuteOnSeparateThread = true });\n\n        /// <summary>Initializes a new instance of the <see cref=\"InProcessNoEmitToolchain\" /> class.</summary>\n        /// <param name=\"settings\">The settings to use for the toolchain.</param>\n        public InProcessNoEmitToolchain(InProcessNoEmitSettings settings)\n        {\n            Generator = new InProcessNoEmitGenerator();\n            Builder = new InProcessNoEmitBuilder();\n            Executor = new InProcessNoEmitExecutor(settings.ExecuteOnSeparateThread);\n        }\n\n        public IEnumerable<ValidationError> Validate(BenchmarkCase benchmarkCase, IResolver resolver) =>\n            InProcessValidator.Validate(benchmarkCase);\n\n        /// <summary>Name of the toolchain.</summary>\n        /// <value>The name of the toolchain.</value>\n        public string Name => nameof(InProcessNoEmitToolchain);\n\n        /// <summary>The generator.</summary>\n        /// <value>The generator.</value>\n        public IGenerator Generator { get; }\n\n        /// <summary>The builder.</summary>\n        /// <value>The builder.</value>\n        public IBuilder Builder { get; }\n\n        /// <summary>The executor.</summary>\n        /// <value>The executor.</value>\n        public IExecutor Executor { get; }\n\n        public bool IsInProcess => true;\n\n        /// <summary>Returns a <see cref=\"string\" /> that represents this instance.</summary>\n        /// <returns>A <see cref=\"string\" /> that represents this instance.</returns>\n        public override string ToString() => GetType().Name;\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/LargeAddressAware.cs",
    "content": "﻿using System;\nusing System.IO;\n\nnamespace BenchmarkDotNet.Toolchains\n{\n    // From https://github.com/KirillOsenkov/LargeAddressAware/blob/95e5fc6024438f94325df4bac6ef73c77bf90e71/SetLargeAddressAware/LargeAddressAware.cs\n    internal class LargeAddressAware\n    {\n\n        public static void SetLargeAddressAware(string filePath)\n        {\n            PrepareStream(filePath, (stream, binaryReader) =>\n            {\n                var value = binaryReader.ReadInt16();\n                if ((value & 0x20) == 0)\n                {\n                    value = (short)(value | 0x20);\n                    stream.Position -= 2;\n                    var binaryWriter = new BinaryWriter(stream);\n                    binaryWriter.Write(value);\n                    binaryWriter.Flush();\n                }\n            });\n        }\n\n        private static void PrepareStream(string filePath, Action<Stream, BinaryReader> action)\n        {\n            using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.ReadWrite, FileShare.Read))\n            {\n                if (stream.Length < 0x3C)\n                {\n                    return;\n                }\n\n                var binaryReader = new BinaryReader(stream);\n\n                // MZ header\n                if (binaryReader.ReadInt16() != 0x5A4D)\n                {\n                    return;\n                }\n\n                stream.Position = 0x3C;\n                var peHeaderLocation = binaryReader.ReadInt32();\n\n                stream.Position = peHeaderLocation;\n\n                // PE header\n                if (binaryReader.ReadInt32() != 0x4550)\n                {\n                    return;\n                }\n\n                stream.Position += 0x12;\n\n                action(stream, binaryReader);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/Mono/MonoAotBuilder.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Helpers;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Toolchains.Results;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Toolchains.Mono\n{\n    [PublicAPI]\n    public class MonoAotBuilder : IBuilder\n    {\n        [PublicAPI]\n        public BuildResult Build(GenerateResult generateResult, BuildPartition buildPartition, ILogger logger)\n        {\n            var result = Roslyn.Builder.Instance.Build(generateResult, buildPartition, logger);\n\n            if (!result.IsBuildSuccess)\n                return result;\n\n            var exePath = generateResult.ArtifactsPaths.ExecutablePath;\n            var monoRuntime = (MonoRuntime)buildPartition.Runtime;\n            var environmentVariables = monoRuntime.MonoBclPath.IsBlank()\n                ? null\n                : new Dictionary<string, string> { { \"MONO_PATH\", monoRuntime.MonoBclPath } };\n\n            var (exitCode, output) = ProcessHelper.RunAndReadOutputLineByLine(\n                fileName: monoRuntime.CustomPath.IsNotBlank() ? monoRuntime.CustomPath : \"mono\",\n                arguments: $\"{monoRuntime.AotArgs} \\\"{Path.GetFullPath(exePath)}\\\"\",\n                workingDirectory: Path.GetDirectoryName(exePath)!,\n                environmentVariables: environmentVariables,\n                includeErrors: true,\n                logger: logger);\n\n            return exitCode != 0\n                ? BuildResult.Failure(generateResult, $\"Attempt to AOT failed: with exit code: {exitCode}, output: {string.Join(Environment.NewLine, output)}\")\n                : result;\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/Mono/MonoAotToolchain.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.IO;\nusing BenchmarkDotNet.Characteristics;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Toolchains.Roslyn;\nusing BenchmarkDotNet.Validators;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Toolchains.Mono\n{\n    public class MonoAotToolchain : Toolchain\n    {\n        public static readonly IToolchain Instance = new MonoAotToolchain();\n\n        [PublicAPI]\n        public MonoAotToolchain() : base(\"MonoAot\", new Generator(), new MonoAotBuilder(), new Executor())\n        {\n        }\n\n        public override IEnumerable<ValidationError> Validate(BenchmarkCase benchmarkCase, IResolver resolver)\n        {\n            foreach (var validationError in base.Validate(benchmarkCase, resolver))\n            {\n                yield return validationError;\n            }\n\n            if (!benchmarkCase.Job.Environment.HasValue(EnvironmentMode.RuntimeCharacteristic) || benchmarkCase.Job.Environment.Runtime is not MonoRuntime)\n            {\n                yield return new ValidationError(true,\n                    \"The MonoAOT toolchain requires the Runtime property to be configured explicitly to an instance of MonoRuntime class\",\n                    benchmarkCase);\n            }\n\n            if ((benchmarkCase.Job.Environment.Runtime is MonoRuntime monoRuntime) && monoRuntime.MonoBclPath.IsNotBlank() && !Directory.Exists(monoRuntime.MonoBclPath))\n            {\n                yield return new ValidationError(true,\n                    $\"The MonoBclPath provided for MonoAOT toolchain: {monoRuntime.MonoBclPath} does NOT exist.\",\n                    benchmarkCase);\n            }\n\n            if (benchmarkCase.Job.HasValue(InfrastructureMode.BuildConfigurationCharacteristic)\n                && benchmarkCase.Job.ResolveValue(InfrastructureMode.BuildConfigurationCharacteristic, resolver) != InfrastructureMode.ReleaseConfigurationName)\n            {\n                yield return new ValidationError(true,\n                    \"The MonoAOT toolchain does not allow to rebuild source project, so defining custom build configuration makes no sense\",\n                    benchmarkCase);\n            }\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/Mono/MonoGenerator.cs",
    "content": "﻿using BenchmarkDotNet.Characteristics;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Toolchains.CsProj;\n\nnamespace BenchmarkDotNet.Toolchains.Mono\n{\n    public class MonoGenerator : CsProjGenerator\n    {\n        public MonoGenerator(string targetFrameworkMoniker, string cliPath, string packagesPath, string runtimeFrameworkVersion) : base(targetFrameworkMoniker, cliPath, packagesPath, runtimeFrameworkVersion, true)\n        {\n        }\n\n        protected override string GetRuntimeSettings(GcMode gcMode, IResolver resolver)\n        {\n            // Workaround for following issues.\n            // 1. 'Found multiple publish output files with the same relative path' error\n            // 2. NU1102 error occurs when running 'dotnet publish' on projects that contain .NET 9.0 or higher. https://github.com/dotnet/BenchmarkDotNet/issues/3000\n            return base.GetRuntimeSettings(gcMode, resolver) +\n                \"\"\"\n                  <PropertyGroup>\n                    <ErrorOnDuplicatePublishOutputFiles>false</ErrorOnDuplicatePublishOutputFiles>\n                  </PropertyGroup>\n                  <PropertyGroup Condition=\"'$(TargetFramework)' == 'net6.0' or '$(TargetFramework)' == 'net7.0' or '$(TargetFramework)' == 'net8.0'\">\n                    <UseMonoRuntime>true</UseMonoRuntime>\n                  </PropertyGroup>\n                \"\"\";\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/Mono/MonoPublisher.cs",
    "content": "﻿using BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Toolchains.DotNetCli;\nusing BenchmarkDotNet.Toolchains.Results;\n\nnamespace BenchmarkDotNet.Toolchains.Mono;\n\npublic class MonoPublisher(string tfm, string customDotNetCliPath) : DotNetCliPublisher(tfm, customDotNetCliPath)\n{\n    public override BuildResult Build(GenerateResult generateResult, BuildPartition buildPartition, ILogger logger)\n        => new DotNetCliCommand(\n            CustomDotNetCliPath,\n            generateResult.ArtifactsPaths.ProjectFilePath,\n            TargetFrameworkMoniker,\n            GetExtraArguments(),\n            generateResult,\n            logger,\n            buildPartition,\n            [],\n            buildPartition.Timeout\n        ).Publish().ToBuildResult(generateResult);\n\n    private static string GetExtraArguments()\n    {\n        var runtimeIdentifier = CustomDotNetCliToolchainBuilder.GetPortableRuntimeIdentifier();\n        // /p:RuntimeIdentifiers is set explicitly here because --self-contained requires it, see https://github.com/dotnet/sdk/issues/10566\n        return $\"--self-contained -r {runtimeIdentifier} /p:RuntimeIdentifiers={runtimeIdentifier}\";\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/Mono/MonoToolchain.cs",
    "content": "﻿using BenchmarkDotNet.Toolchains.CsProj;\nusing BenchmarkDotNet.Toolchains.DotNetCli;\nusing JetBrains.Annotations;\nusing System;\n\nnamespace BenchmarkDotNet.Toolchains.Mono\n{\n    [PublicAPI]\n    public class MonoToolchain : CsProjCoreToolchain, IEquatable<MonoToolchain>\n    {\n        [PublicAPI] public static readonly IToolchain Mono60 = From(new NetCoreAppSettings(\"net6.0\", \"mono60\"));\n        [PublicAPI] public static readonly IToolchain Mono70 = From(new NetCoreAppSettings(\"net7.0\", \"mono70\"));\n        [PublicAPI] public static readonly IToolchain Mono80 = From(new NetCoreAppSettings(\"net8.0\", \"mono80\"));\n\n        private MonoToolchain(string name, IGenerator generator, IBuilder builder, IExecutor executor, string customDotNetCliPath)\n            : base(name, generator, builder, executor, customDotNetCliPath)\n        {\n        }\n\n        [PublicAPI]\n        public static new IToolchain From(NetCoreAppSettings settings)\n            => new MonoToolchain(settings.Name,\n                new MonoGenerator(settings.TargetFrameworkMoniker, settings.CustomDotNetCliPath, settings.PackagesPath, settings.RuntimeFrameworkVersion),\n                new MonoPublisher(settings.TargetFrameworkMoniker, settings.CustomDotNetCliPath),\n                new DotNetCliExecutor(settings.CustomDotNetCliPath),\n                settings.CustomDotNetCliPath);\n\n        public override bool Equals(object? obj) => obj is MonoToolchain typed && Equals(typed);\n\n        public bool Equals(MonoToolchain? other)\n        {\n            if (ReferenceEquals(null, other))\n                return false;\n            if (ReferenceEquals(this, other))\n                return true;\n\n            return Generator.Equals(other.Generator);\n        }\n\n        public override int GetHashCode() => Generator.GetHashCode();\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/MonoAotLLVM/MonoAotCompilerMode.cs",
    "content": "﻿namespace BenchmarkDotNet.Toolchains.MonoAotLLVM\n{\n    public enum MonoAotCompilerMode\n    {\n        mini = 0, // default\n        llvm,\n        wasm\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/MonoAotLLVM/MonoAotLLVMGenerator.cs",
    "content": "﻿using System.IO;\nusing System.Text;\nusing System.Xml;\nusing BenchmarkDotNet.Detectors;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Helpers;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Toolchains.CsProj;\nusing BenchmarkDotNet.Toolchains.DotNetCli;\n\nnamespace BenchmarkDotNet.Toolchains.MonoAotLLVM\n{\n    public class MonoAotLLVMGenerator : CsProjGenerator\n    {\n        private readonly string CustomRuntimePack;\n        private readonly string AotCompilerPath;\n        private readonly MonoAotCompilerMode AotCompilerMode;\n\n        public MonoAotLLVMGenerator(string targetFrameworkMoniker, string cliPath, string packagesPath, string customRuntimePack, string aotCompilerPath, MonoAotCompilerMode aotCompilerMode)\n            : base(targetFrameworkMoniker, cliPath, packagesPath)\n        {\n            CustomRuntimePack = customRuntimePack;\n            AotCompilerPath = aotCompilerPath;\n            AotCompilerMode = aotCompilerMode;\n            BenchmarkRunCallType = Code.CodeGenBenchmarkRunCallType.Direct;\n        }\n\n        protected override void GenerateProject(BuildPartition buildPartition, ArtifactsPaths artifactsPaths, ILogger logger)\n        {\n            BenchmarkCase benchmark = buildPartition.RepresentativeBenchmarkCase;\n            var projectFile = GetProjectFilePath(benchmark.Descriptor.Type, logger);\n\n            string useLLVM = AotCompilerMode == MonoAotCompilerMode.llvm ? \"true\" : \"false\";\n\n            var xmlDoc = new XmlDocument();\n            xmlDoc.Load(projectFile.FullName);\n            var (customProperties, sdkName) = GetSettingsThatNeedToBeCopied(xmlDoc, projectFile);\n\n            string content = new StringBuilder(ResourceHelper.LoadTemplate(\"MonoAOTLLVMCsProj.txt\"))\n                .Replace(\"$PLATFORM$\", buildPartition.Platform.ToConfig())\n                .Replace(\"$CODEFILENAME$\", Path.GetFileName(artifactsPaths.ProgramCodePath))\n                .Replace(\"$CSPROJPATH$\", projectFile.FullName)\n                .Replace(\"$TFM$\", TargetFrameworkMoniker)\n                .Replace(\"$PROGRAMNAME$\", artifactsPaths.ProgramName)\n                .Replace(\"$COPIEDSETTINGS$\", customProperties)\n                .Replace(\"$SDKNAME$\", sdkName)\n                .Replace(\"$RUNTIMEPACK$\", CustomRuntimePack)\n                .Replace(\"$COMPILERBINARYPATH$\", AotCompilerPath)\n                .Replace(\"$RUNTIMEIDENTIFIER$\", CustomDotNetCliToolchainBuilder.GetPortableRuntimeIdentifier())\n                .Replace(\"$USELLVM$\", useLLVM)\n                .ToString();\n\n            File.WriteAllText(artifactsPaths.ProjectFilePath, content);\n\n            GatherReferences(buildPartition, artifactsPaths, logger);\n        }\n\n        protected override string GetPublishDirectoryPath(string buildArtifactsDirectoryPath, string configuration)\n            => Path.Combine(GetBinariesDirectoryPath(buildArtifactsDirectoryPath, configuration), \"publish\");\n\n        protected override string GetExecutablePath(string binariesDirectoryPath, string programName)\n            => OsDetector.IsWindows()\n                ? Path.Combine(binariesDirectoryPath, \"publish\", $\"{programName}.exe\")\n                : Path.Combine(binariesDirectoryPath, \"publish\", programName);\n\n        protected override string GetBinariesDirectoryPath(string buildArtifactsDirectoryPath, string configuration)\n            => Path.Combine(buildArtifactsDirectoryPath, \"bin\", configuration, TargetFrameworkMoniker, CustomDotNetCliToolchainBuilder.GetPortableRuntimeIdentifier());\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/MonoAotLLVM/MonoAotLLVMToolChain.cs",
    "content": "using BenchmarkDotNet.Characteristics;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Toolchains.DotNetCli;\nusing BenchmarkDotNet.Validators;\nusing System.Collections.Generic;\n\nnamespace BenchmarkDotNet.Toolchains.MonoAotLLVM\n{\n    public class MonoAotLLVMToolChain : Toolchain\n    {\n        private readonly string _customDotNetCliPath;\n\n        public MonoAotLLVMToolChain(string name, IGenerator generator, IBuilder builder, IExecutor executor, string customDotNetCliPath)\n            : base(name, generator, builder, executor)\n        {\n            _customDotNetCliPath = customDotNetCliPath;\n        }\n\n        public static IToolchain From(NetCoreAppSettings netCoreAppSettings)\n        => new MonoAotLLVMToolChain(netCoreAppSettings.Name,\n                new MonoAotLLVMGenerator(netCoreAppSettings.TargetFrameworkMoniker,\n                    netCoreAppSettings.CustomDotNetCliPath,\n                    netCoreAppSettings.PackagesPath,\n                    netCoreAppSettings.CustomRuntimePack,\n                    netCoreAppSettings.AOTCompilerPath,\n                    netCoreAppSettings.AOTCompilerMode),\n                new DotNetCliBuilder(netCoreAppSettings.TargetFrameworkMoniker,\n                    netCoreAppSettings.CustomDotNetCliPath),\n                new Executor(),\n                netCoreAppSettings.CustomDotNetCliPath);\n\n        public override IEnumerable<ValidationError> Validate(BenchmarkCase benchmarkCase, IResolver resolver)\n        {\n            foreach (var validationError in base.Validate(benchmarkCase, resolver))\n            {\n                yield return validationError;\n            }\n\n            foreach (var validationError in DotNetSdkValidator.ValidateCoreSdks(_customDotNetCliPath, benchmarkCase))\n            {\n                yield return validationError;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/MonoWasm/WasmExecutor.cs",
    "content": "﻿using BenchmarkDotNet.Characteristics;\nusing BenchmarkDotNet.Diagnosers;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Helpers;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Toolchains.Parameters;\nusing BenchmarkDotNet.Toolchains.Results;\nusing System;\nusing System.Collections.Generic;\nusing System.Collections.Immutable;\nusing System.Diagnostics;\nusing System.IO;\nusing System.Text;\n\nnamespace BenchmarkDotNet.Toolchains.MonoWasm\n{\n    internal class WasmExecutor : IExecutor\n    {\n        public ExecuteResult Execute(ExecuteParameters executeParameters)\n        {\n            string exePath = executeParameters.BuildResult.ArtifactsPaths.ExecutablePath;\n\n            if (!File.Exists(exePath))\n            {\n                return ExecuteResult.CreateFailed();\n            }\n\n            return Execute(executeParameters.BenchmarkCase, executeParameters.BenchmarkId, executeParameters.Logger, executeParameters.BuildResult.ArtifactsPaths,\n                executeParameters.Diagnoser, executeParameters.CompositeInProcessDiagnoser, executeParameters.Resolver, executeParameters.LaunchIndex,\n                executeParameters.DiagnoserRunMode);\n        }\n\n        private static ExecuteResult Execute(BenchmarkCase benchmarkCase, BenchmarkId benchmarkId, ILogger logger, ArtifactsPaths artifactsPaths,\n            IDiagnoser? diagnoser, CompositeInProcessDiagnoser compositeInProcessDiagnoser, IResolver resolver, int launchIndex,\n            Diagnosers.RunMode diagnoserRunMode)\n        {\n            try\n            {\n                using Process process = CreateProcess(benchmarkCase, artifactsPaths, benchmarkId.ToArguments(diagnoserRunMode), resolver);\n                using ConsoleExitHandler consoleExitHandler = new(process, logger);\n                using AsyncProcessOutputReader processOutputReader = new(process, logOutput: true, logger, readStandardError: false);\n\n                diagnoser?.Handle(HostSignal.BeforeProcessStart, new DiagnoserActionParameters(process, benchmarkCase, benchmarkId));\n                return Execute(process, benchmarkCase, processOutputReader, logger, consoleExitHandler, launchIndex, compositeInProcessDiagnoser);\n            }\n            finally\n            {\n                diagnoser?.Handle(HostSignal.AfterProcessExit, new DiagnoserActionParameters(null, benchmarkCase, benchmarkId));\n            }\n        }\n\n        private static Process CreateProcess(BenchmarkCase benchmarkCase, ArtifactsPaths artifactsPaths, string args, IResolver resolver)\n        {\n            WasmRuntime runtime = (WasmRuntime)benchmarkCase.GetRuntime();\n\n            var start = new ProcessStartInfo\n            {\n                FileName = runtime.JavaScriptEngine,\n                Arguments = runtime.JavaScriptEngineArgumentFormatter(runtime, artifactsPaths, args),\n                WorkingDirectory = Path.Combine(artifactsPaths.BinariesDirectoryPath, \"wwwroot\"),\n                UseShellExecute = false,\n                RedirectStandardOutput = true,\n                RedirectStandardInput = false, // not supported by WASM!\n                RedirectStandardError = false, // #1629\n                CreateNoWindow = true\n            };\n\n            start.SetEnvironmentVariables(benchmarkCase, resolver);\n\n            return new Process() { StartInfo = start };\n        }\n\n        private static ExecuteResult Execute(Process process, BenchmarkCase benchmarkCase, AsyncProcessOutputReader processOutputReader,\n            ILogger logger, ConsoleExitHandler consoleExitHandler, int launchIndex, CompositeInProcessDiagnoser compositeInProcessDiagnoser)\n        {\n            logger.WriteLineInfo($\"// Execute: {process.StartInfo.FileName} {process.StartInfo.Arguments} in {process.StartInfo.WorkingDirectory}\");\n\n            process.Start();\n            processOutputReader.BeginRead();\n\n            process.EnsureHighPriority(logger);\n            if (benchmarkCase.Job.Environment.HasValue(EnvironmentMode.AffinityCharacteristic))\n            {\n                process.TrySetAffinity(benchmarkCase.Job.Environment.Affinity, logger);\n            }\n\n            WasmRuntime wasmRuntime = (WasmRuntime)benchmarkCase.GetRuntime();\n            int timeoutMinutes = wasmRuntime.ProcessTimeoutMinutes;\n            if (!process.WaitForExit(milliseconds: (int)TimeSpan.FromMinutes(timeoutMinutes).TotalMilliseconds))\n            {\n                logger.WriteLineInfo($\"// The benchmarking process did not finish within {timeoutMinutes} minutes, it's going to get force killed now.\");\n\n                processOutputReader.CancelRead();\n                consoleExitHandler.KillProcessTree();\n            }\n            else\n            {\n                processOutputReader.StopRead();\n            }\n\n            ImmutableArray<string> outputLines = processOutputReader.GetOutputLines();\n            var prefixedLines = new List<string>();\n            var resultLines = new List<string>();\n            var outputEnumerator = outputLines.GetEnumerator();\n            while (outputEnumerator.MoveNext())\n            {\n                var line = outputEnumerator.Current;\n                if (!line.StartsWith(\"//\"))\n                {\n                    resultLines.Add(line);\n                    continue;\n                }\n\n                prefixedLines.Add(line);\n\n                // Keep in sync with Broker and InProcessHost.\n                if (line.StartsWith(CompositeInProcessDiagnoser.HeaderKey))\n                {\n                    // Something like \"// InProcessDiagnoser 0 1\"\n                    string[] lineItems = line.Split(' ');\n                    int diagnoserIndex = int.Parse(lineItems[2]);\n                    int resultsLinesCount = int.Parse(lineItems[3]);\n                    var resultsStringBuilder = new StringBuilder();\n                    for (int i = 0; i < resultsLinesCount;)\n                    {\n                        // Strip the prepended \"// InProcessDiagnoserResults \".\n                        bool movedNext = outputEnumerator.MoveNext();\n                        Debug.Assert(movedNext);\n                        line = outputEnumerator.Current.Substring(CompositeInProcessDiagnoser.ResultsKey.Length + 1);\n                        resultsStringBuilder.Append(line);\n                        if (++i < resultsLinesCount)\n                        {\n                            resultsStringBuilder.AppendLine();\n                        }\n                    }\n                    compositeInProcessDiagnoser.DeserializeResults(diagnoserIndex, benchmarkCase, resultsStringBuilder.ToString());\n                }\n            }\n\n            return new ExecuteResult(true,\n                process.HasExited ? process.ExitCode : null,\n                process.Id,\n                [.. resultLines],\n                [.. prefixedLines],\n                outputLines,\n                launchIndex);\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/MonoWasm/WasmGenerator.cs",
    "content": "﻿using System.IO;\nusing System.Text;\nusing System.Xml;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Helpers;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Toolchains.CsProj;\n\nnamespace BenchmarkDotNet.Toolchains.MonoWasm\n{\n    public class WasmGenerator : CsProjGenerator\n    {\n        private readonly string CustomRuntimePack;\n\n        public WasmGenerator(string targetFrameworkMoniker, string cliPath, string packagesPath, string customRuntimePack, bool aot)\n            : base(targetFrameworkMoniker, cliPath, packagesPath)\n        {\n            CustomRuntimePack = customRuntimePack;\n            BenchmarkRunCallType = aot ? Code.CodeGenBenchmarkRunCallType.Direct : Code.CodeGenBenchmarkRunCallType.Reflection;\n        }\n\n        protected override void GenerateProject(BuildPartition buildPartition, ArtifactsPaths artifactsPaths, ILogger logger)\n        {\n            var targetMainJsPath = GetExecutablePath(Path.GetDirectoryName(artifactsPaths.ProjectFilePath)!, \"\");\n\n            if (buildPartition.Runtime.IsAOT)\n            {\n                GenerateProjectFile(buildPartition, artifactsPaths, aot: true, logger, targetMainJsPath);\n\n                var linkDescriptionFileName = \"WasmLinkerDescription.xml\";\n                File.WriteAllText(Path.Combine(Path.GetDirectoryName(artifactsPaths.ProjectFilePath)!, linkDescriptionFileName), ResourceHelper.LoadTemplate(linkDescriptionFileName));\n            }\n            else\n            {\n                GenerateProjectFile(buildPartition, artifactsPaths, aot: false, logger: logger, targetMainJsPath);\n            }\n\n            GenerateMainJS(buildPartition, ((WasmRuntime)buildPartition.Runtime).MainJsTemplate, targetMainJsPath);\n        }\n\n        protected void GenerateProjectFile(BuildPartition buildPartition, ArtifactsPaths artifactsPaths, bool aot, ILogger logger, string targetMainJsPath)\n        {\n            BenchmarkCase benchmark = buildPartition.RepresentativeBenchmarkCase;\n            var projectFile = GetProjectFilePath(benchmark.Descriptor.Type, logger);\n\n            WasmRuntime runtime = (WasmRuntime)buildPartition.Runtime;\n\n            var xmlDoc = new XmlDocument();\n            xmlDoc.Load(projectFile.FullName);\n            var (customProperties, _) = GetSettingsThatNeedToBeCopied(xmlDoc, projectFile);\n            string sdkName = \"Microsoft.NET.Sdk.WebAssembly\";\n\n            // For CoreCLR WASM:\n            // - UseMonoRuntime=false: resolves CoreCLR runtime pack instead of Mono\n            // - WasmBuildNative=false: avoids requiring wasm-tools workload\n            // - WasmEnableWebcil=false: CoreCLR doesn't support webcil format\n            string coreclrOverrides = runtime.RuntimeFlavor == RuntimeFlavor.Mono\n                ? string.Empty\n                : @\"\n  <!-- CoreCLR overrides: use CoreCLR runtime instead of Mono -->\n  <PropertyGroup>\n    <UseMonoRuntime>false</UseMonoRuntime>\n    <WasmBuildNative>false</WasmBuildNative>\n    <WasmEnableWebcil>false</WasmEnableWebcil>\n  </PropertyGroup>\n\";\n\n            string content = new StringBuilder(ResourceHelper.LoadTemplate(\"WasmCsProj.txt\"))\n                .Replace(\"$PLATFORM$\", buildPartition.Platform.ToConfig())\n                .Replace(\"$CODEFILENAME$\", Path.GetFileName(artifactsPaths.ProgramCodePath))\n                .Replace(\"$RUN_AOT$\", aot.ToString().ToLower())\n                .Replace(\"$CSPROJPATH$\", projectFile.FullName)\n                .Replace(\"$TFM$\", TargetFrameworkMoniker)\n                .Replace(\"$PROGRAMNAME$\", artifactsPaths.ProgramName)\n                .Replace(\"$COPIEDSETTINGS$\", customProperties)\n                .Replace(\"$SDKNAME$\", sdkName)\n                .Replace(\"$TARGET$\", CustomRuntimePack.IsNotBlank() ? \"PublishWithCustomRuntimePack\" : \"Publish\")\n                .Replace(\"$MAINJS$\", targetMainJsPath)\n                .Replace(\"$CORECLR_OVERRIDES$\", coreclrOverrides)\n            .ToString();\n\n            File.WriteAllText(artifactsPaths.ProjectFilePath, content);\n\n            GatherReferences(buildPartition, artifactsPaths, logger);\n        }\n\n        protected void GenerateMainJS(BuildPartition buildPartition, FileInfo? mainJsTemplate, string targetMainJsPath)\n        {\n            string content = mainJsTemplate is null\n                ? ResourceHelper.LoadTemplate(\"benchmark-main.mjs\")\n                : File.ReadAllText(mainJsTemplate.FullName);\n\n            targetMainJsPath.EnsureFolderExists();\n            File.WriteAllText(targetMainJsPath, content);\n        }\n\n        protected override string GetExecutablePath(string binariesDirectoryPath, string programName) => Path.Combine(binariesDirectoryPath, \"wwwroot\", \"main.mjs\");\n\n        protected override string GetBinariesDirectoryPath(string buildArtifactsDirectoryPath, string configuration)\n            => Path.Combine(buildArtifactsDirectoryPath, \"bin\", configuration, TargetFrameworkMoniker, \"publish\");\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/MonoWasm/WasmToolchain.cs",
    "content": "﻿using System.Collections.Generic;\nusing BenchmarkDotNet.Characteristics;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Toolchains.DotNetCli;\nusing BenchmarkDotNet.Validators;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Toolchains.MonoWasm\n{\n    [PublicAPI]\n    public class WasmToolchain : Toolchain\n    {\n        private string CustomDotNetCliPath { get; }\n\n        private WasmToolchain(string name, IGenerator generator, IBuilder builder, IExecutor executor, string customDotNetCliPath)\n            : base(name, generator, builder, executor)\n        {\n            CustomDotNetCliPath = customDotNetCliPath;\n        }\n\n        public override IEnumerable<ValidationError> Validate(BenchmarkCase benchmarkCase, IResolver resolver)\n        {\n            foreach (var validationError in base.Validate(benchmarkCase, resolver))\n            {\n                yield return validationError;\n            }\n\n            foreach (var validationError in DotNetSdkValidator.ValidateCoreSdks(CustomDotNetCliPath, benchmarkCase))\n            {\n                yield return validationError;\n            }\n        }\n\n        [PublicAPI]\n        public static IToolchain From(NetCoreAppSettings netCoreAppSettings)\n            => new WasmToolchain(netCoreAppSettings.Name,\n                    new WasmGenerator(netCoreAppSettings.TargetFrameworkMoniker,\n                        netCoreAppSettings.CustomDotNetCliPath,\n                        netCoreAppSettings.PackagesPath,\n                        netCoreAppSettings.CustomRuntimePack,\n                        netCoreAppSettings.AOTCompilerMode == MonoAotLLVM.MonoAotCompilerMode.wasm),\n                    new DotNetCliPublisher(netCoreAppSettings.TargetFrameworkMoniker,\n                        netCoreAppSettings.CustomDotNetCliPath,\n                        // aot builds can be very slow\n                        logOutput: netCoreAppSettings.AOTCompilerMode == MonoAotLLVM.MonoAotCompilerMode.wasm),\n                    new WasmExecutor(),\n                    netCoreAppSettings.CustomDotNetCliPath);\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/NativeAot/Generator.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Text;\nusing System.Xml;\nusing BenchmarkDotNet.ConsoleArguments;\nusing BenchmarkDotNet.Detectors;\nusing BenchmarkDotNet.Detectors.Cpu;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Portability;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Toolchains.CsProj;\nusing BenchmarkDotNet.Toolchains.DotNetCli;\n\nnamespace BenchmarkDotNet.Toolchains.NativeAot\n{\n    /// <summary>\n    /// generates new csproj file for self-contained NativeAOT app\n    /// based on https://github.com/dotnet/corert/blob/7f902d4d8b1c3280e60f5e06c71951a60da173fb/Documentation/how-to-build-and-run-ilcompiler-in-console-shell-prompt.md#compiling-source-to-native-code-using-the-ilcompiler-you-built\n    /// and https://github.com/dotnet/corert/tree/7f902d4d8b1c3280e60f5e06c71951a60da173fb/samples/HelloWorld#add-corert-to-your-project\n    /// </summary>\n    public class Generator : CsProjGenerator\n    {\n        internal const string NativeAotNuGetFeed = \"nativeAotNuGetFeed\";\n        internal const string GeneratedRdXmlFileName = \"bdn_generated.rd.xml\";\n\n        internal Generator(string ilCompilerVersion,\n            string runtimeFrameworkVersion,\n            string targetFrameworkMoniker,\n            string cliPath,\n            string runtimeIdentifier,\n            IReadOnlyDictionary<string, string> feeds,\n            bool useNuGetClearTag,\n            bool useTempFolderForRestore,\n            string packagesRestorePath,\n            bool rootAllApplicationAssemblies,\n            bool ilcGenerateStackTraceData,\n            string ilcOptimizationPreference,\n            string ilcInstructionSet)\n            : base(targetFrameworkMoniker, cliPath, GetPackagesDirectoryPath(useTempFolderForRestore, packagesRestorePath), runtimeFrameworkVersion)\n        {\n            this.ilCompilerVersion = ilCompilerVersion;\n            this.runtimeIdentifier = runtimeIdentifier;\n            this.Feeds = feeds;\n            this.useNuGetClearTag = useNuGetClearTag;\n            this.useTempFolderForRestore = useTempFolderForRestore;\n            this.rootAllApplicationAssemblies = rootAllApplicationAssemblies;\n            this.ilcGenerateStackTraceData = ilcGenerateStackTraceData;\n            this.ilcOptimizationPreference = ilcOptimizationPreference;\n            this.ilcInstructionSet = ilcInstructionSet;\n            BenchmarkRunCallType = Code.CodeGenBenchmarkRunCallType.Direct;\n        }\n\n        internal readonly IReadOnlyDictionary<string, string> Feeds;\n        private readonly string ilCompilerVersion;\n        private readonly string runtimeIdentifier;\n        private readonly bool useNuGetClearTag;\n        private readonly bool useTempFolderForRestore;\n        private readonly bool rootAllApplicationAssemblies;\n        private readonly bool ilcGenerateStackTraceData;\n        private readonly string ilcOptimizationPreference;\n        private readonly string ilcInstructionSet;\n\n        protected override string GetExecutableExtension() => OsDetector.ExecutableExtension;\n\n        protected override string GetBuildArtifactsDirectoryPath(BuildPartition buildPartition, string programName)\n            => useTempFolderForRestore\n                ? Path.Combine(Path.GetTempPath(), programName) // store everything in temp to avoid collisions with IDE\n                : base.GetBuildArtifactsDirectoryPath(buildPartition, programName);\n\n        protected override string GetBinariesDirectoryPath(string buildArtifactsDirectoryPath, string configuration)\n            => Path.Combine(buildArtifactsDirectoryPath, \"bin\", configuration, TargetFrameworkMoniker, runtimeIdentifier, \"publish\");\n\n        protected override void GenerateBuildScript(BuildPartition buildPartition, ArtifactsPaths artifactsPaths)\n        {\n            string projectFilePath = GetProjectFilePath(buildPartition.RepresentativeBenchmarkCase.Descriptor.Type, NullLogger.Instance).FullName;\n            string extraArguments = NativeAotToolchain.GetExtraArguments(runtimeIdentifier);\n\n            var content = new StringBuilder(300)\n                .AppendLine($\"call {CliPath} {DotNetCliCommand.GetRestoreCommand(artifactsPaths, buildPartition, projectFilePath, extraArguments)}\")\n                .AppendLine($\"call {CliPath} {DotNetCliCommand.GetPublishCommand(artifactsPaths, buildPartition, projectFilePath, TargetFrameworkMoniker, extraArguments)}\")\n                .AppendLine($\"call {CliPath} {DotNetCliCommand.GetRestoreCommand(artifactsPaths, buildPartition, artifactsPaths.ProjectFilePath, extraArguments)}\")\n                .AppendLine($\"call {CliPath} {DotNetCliCommand.GetPublishCommand(artifactsPaths, buildPartition, artifactsPaths.ProjectFilePath, TargetFrameworkMoniker, extraArguments)}\")\n                .ToString();\n\n            File.WriteAllText(artifactsPaths.BuildScriptFilePath, content);\n        }\n\n        // we always want to have a new directory for NuGet packages restore\n        // to avoid this https://github.com/dotnet/coreclr/blob/master/Documentation/workflow/UsingDotNetCli.md#update-coreclr-using-runtime-nuget-package\n        // some of the packages are going to contain source code, so they can not be in the subfolder of current solution\n        // otherwise they would be compiled too (new .csproj include all .cs files from subfolders by default\n        private static string GetPackagesDirectoryPath(bool useTempFolderForRestore, string packagesRestorePath)\n            => packagesRestorePath.IsBlank() && useTempFolderForRestore\n                   ? Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString())\n                   : \"\";\n\n        protected override string[] GetArtifactsToCleanup(ArtifactsPaths artifactsPaths)\n            => useTempFolderForRestore && artifactsPaths.PackagesDirectoryName.IsNotBlank()\n                ? base.GetArtifactsToCleanup(artifactsPaths).Concat([artifactsPaths.PackagesDirectoryName]).ToArray()\n                : base.GetArtifactsToCleanup(artifactsPaths);\n\n        protected override void GenerateNuGetConfig(ArtifactsPaths artifactsPaths)\n        {\n            if (!Feeds.Any())\n                return;\n\n            string content =\n$@\"<?xml version=\"\"1.0\"\" encoding=\"\"utf-8\"\"?>\n<configuration>\n  <packageSources>\n    {(useNuGetClearTag ? \"<clear/>\" : string.Empty)}\n    {string.Join(Environment.NewLine + \"    \", Feeds.Select(feed => $\"<add key=\\\"{feed.Key}\\\" value=\\\"{feed.Value}\\\" />\"))}\n  </packageSources>\n</configuration>\";\n\n            File.WriteAllText(artifactsPaths.NuGetConfigPath, content);\n        }\n\n        protected override void GenerateProject(BuildPartition buildPartition, ArtifactsPaths artifactsPaths, ILogger logger)\n        {\n            var projectFile = GetProjectFilePath(buildPartition.RepresentativeBenchmarkCase.Descriptor.Type, logger).FullName;\n\n            File.WriteAllText(artifactsPaths.ProjectFilePath, GenerateProjectForNuGetBuild(projectFile, buildPartition, artifactsPaths, logger));\n\n            GatherReferences(buildPartition, artifactsPaths, logger);\n            GenerateReflectionFile(artifactsPaths);\n        }\n\n        private string GenerateProjectForNuGetBuild(string projectFilePath, BuildPartition buildPartition, ArtifactsPaths artifactsPaths, ILogger logger) => $@\"\n<Project Sdk=\"\"Microsoft.NET.Sdk\"\">\n  <PropertyGroup>\n    <ImportDirectoryBuildProps>false</ImportDirectoryBuildProps>\n    <ImportDirectoryBuildTargets>false</ImportDirectoryBuildTargets>\n    <OutputType>Exe</OutputType>\n    <TargetFrameworks>{TargetFrameworkMoniker}</TargetFrameworks>\n    <RuntimeIdentifier>{runtimeIdentifier}</RuntimeIdentifier>\n    <RuntimeFrameworkVersion>{RuntimeFrameworkVersion}</RuntimeFrameworkVersion>\n    <AssemblyName>{artifactsPaths.ProgramName}</AssemblyName>\n    <AssemblyTitle>{artifactsPaths.ProgramName}</AssemblyTitle>\n    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>\n    <PlatformTarget>{buildPartition.Platform.ToConfig()}</PlatformTarget>\n    <TreatWarningsAsErrors>False</TreatWarningsAsErrors>\n    <DebugSymbols>false</DebugSymbols>\n    <UseSharedCompilation>false</UseSharedCompilation>\n    <Deterministic>true</Deterministic>\n    <RunAnalyzers>false</RunAnalyzers>\n    <PublishAot Condition=\"\"$([MSBuild]::VersionGreaterThan('$(NETCoreSdkVersion)', '6.0'))\"\">true</PublishAot>\n    <IlcOptimizationPreference>{ilcOptimizationPreference}</IlcOptimizationPreference>\n    <OptimizationPreference>{ilcOptimizationPreference}</OptimizationPreference>\n    {GetTrimmingSettings()}\n    <IlcGenerateStackTraceData>{ilcGenerateStackTraceData}</IlcGenerateStackTraceData>\n    <StackTraceSupport>{ilcGenerateStackTraceData}</StackTraceSupport>\n    <EnsureNETCoreAppRuntime>false</EnsureNETCoreAppRuntime> <!-- workaround for 'This runtime may not be supported by.NET Core.' error -->\n    <ErrorOnDuplicatePublishOutputFiles>false</ErrorOnDuplicatePublishOutputFiles> <!-- workaround for 'Found multiple publish output files with the same relative path.' error -->\n    <ValidateExecutableReferencesMatchSelfContained>false</ValidateExecutableReferencesMatchSelfContained>\n    <SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings> <!-- Suppress warning for nuget package used in old (unsupported) tfm. -->\n    {GetInstructionSetSettings(buildPartition)}\n  </PropertyGroup>\n  {GetRuntimeSettings(buildPartition.RepresentativeBenchmarkCase.Job.Environment.Gc, buildPartition.Resolver)}\n  <ItemGroup>\n    <Compile Include=\"\"{Path.GetFileName(artifactsPaths.ProgramCodePath)}\"\" Exclude=\"\"bin\\**;obj\\**;**\\*.xproj;packages\\**\"\" />\n  </ItemGroup>\n  <ItemGroup>\n    {GetILCompilerPackageReference()}\n    <ProjectReference Include=\"\"{projectFilePath}\"\" />\n  </ItemGroup>\n  <ItemGroup>\n    {string.Join(Environment.NewLine, GetRdXmlFiles(buildPartition.RepresentativeBenchmarkCase.Descriptor.Type, logger).Select(file => $\"<RdXmlFile Include=\\\"{file}\\\" />\"))}\n  </ItemGroup>\n{GetCustomProperties(buildPartition, logger)}\n</Project>\";\n\n        private string GetCustomProperties(BuildPartition buildPartition, ILogger logger)\n        {\n            var projectFile = GetProjectFilePath(buildPartition.RepresentativeBenchmarkCase.Descriptor.Type, logger);\n            var xmlDoc = new XmlDocument();\n            xmlDoc.Load(projectFile.FullName);\n\n            (string customProperties, _) = GetSettingsThatNeedToBeCopied(xmlDoc, projectFile);\n            return customProperties;\n        }\n\n\n        private string GetILCompilerPackageReference()\n            => ilCompilerVersion.IsBlank() ? \"\" : $@\"<PackageReference Include=\"\"Microsoft.DotNet.ILCompiler\"\" Version=\"\"{ilCompilerVersion}\"\" />\";\n\n        private string GetTrimmingSettings()\n            => rootAllApplicationAssemblies\n                // Use the defaults\n                ? \"\"\n                // TrimMode is set in explicit way as for older versions it might have different default value\n                : \"<TrimMode>link</TrimMode><TrimmerDefaultAction>link</TrimmerDefaultAction>\";\n\n        private string GetInstructionSetSettings(BuildPartition buildPartition)\n        {\n            string instructionSet = ilcInstructionSet.IsBlank()\n                ? GetCurrentInstructionSet(buildPartition.Platform)\n                : ilcInstructionSet;\n\n            return instructionSet.IsNotBlank()\n                ? $\"<IlcInstructionSet>{instructionSet}</IlcInstructionSet>\"\n                : \"\";\n        }\n\n        public IEnumerable<string> GetRdXmlFiles(Type benchmarkTarget, ILogger logger)\n        {\n            yield return GeneratedRdXmlFileName;\n\n            var projectFile = GetProjectFilePath(benchmarkTarget, logger);\n            var projectFileFolder = projectFile.DirectoryName!;\n            var rdXml = Path.Combine(projectFileFolder, \"rd.xml\");\n            if (File.Exists(rdXml))\n            {\n                yield return rdXml;\n            }\n\n            foreach (var item in Directory.GetFiles(projectFileFolder, \"*.rd.xml\"))\n            {\n                yield return item;\n            }\n        }\n\n        /// <summary>\n        /// mandatory to make it possible to call GC.GetAllocatedBytesForCurrentThread() using reflection (not part of .NET Standard)\n        /// </summary>\n        private void GenerateReflectionFile(ArtifactsPaths artifactsPaths)\n        {\n            const string content = @\"\n<Directives>\n    <Application>\n        <Assembly Name=\"\"System.Runtime\"\">\n            <Type Name=\"\"System.GC\"\" Dynamic=\"\"Required All\"\" />\n        </Assembly>\n        <Assembly Name=\"\"System.Threading.ThreadPool\"\">\n            <Type Name=\"\"System.Threading.ThreadPool\"\" Dynamic=\"\"Required All\"\" />\n        </Assembly>\n        <Assembly Name=\"\"System.Threading\"\">\n            <Type Name=\"\"System.Threading.Monitor\"\" Dynamic=\"\"Required All\"\" />\n        </Assembly>\n    </Application>\n</Directives>\n\";\n\n            string directoryName = Path.GetDirectoryName(artifactsPaths.ProjectFilePath)!;\n            if (directoryName != null)\n                File.WriteAllText(Path.Combine(directoryName, GeneratedRdXmlFileName), content);\n            else\n                throw new InvalidOperationException($\"Can't get directory of projectFilePath ('{artifactsPaths.ProjectFilePath}')\");\n        }\n\n        private string GetCurrentInstructionSet(Platform platform)\n            => string.Join(\",\", GetCurrentProcessInstructionSets(platform));\n\n        // based on https://github.com/dotnet/runtime/tree/v10.0.0-rc.1.25451.107/src/coreclr/tools/Common/JitInterface/ThunkGenerator/InstructionSetDesc.txt\n        private IEnumerable<string> GetCurrentProcessInstructionSets(Platform platform)\n        {\n            if (!ConfigParser.TryParse(TargetFrameworkMoniker, out RuntimeMoniker runtimeMoniker))\n            {\n                throw new NotSupportedException($\"Invalid TFM: '{TargetFrameworkMoniker}'\");\n            }\n\n            // TFM is the MSBuild moniker, not the BDN moniker, so it resolves to Net10_0 instead of NativeAot10_0.\n            // TODO: Get the correct moniker from the NativeAotRuntime (#2609)\n            runtimeMoniker += RuntimeMoniker.NativeAot60 - RuntimeMoniker.Net60;\n\n            if (platform == RuntimeInformation.GetCurrentPlatform() // \"native\" does not support cross-compilation (so does BDN for now)\n                && runtimeMoniker >= RuntimeMoniker.NativeAot80)\n            {\n                yield return \"native\"; // added in .NET 8 https://github.com/dotnet/runtime/pull/87865\n                yield break;\n            }\n\n            switch (platform)\n            {\n                case Platform.X86:\n                case Platform.X64:\n                    if (HardwareIntrinsics.IsX86BaseSupported) yield return \"base\";\n                    if (HardwareIntrinsics.IsX86Sse42Supported)\n                    {\n                        if (runtimeMoniker <= RuntimeMoniker.NativeAot10_0) yield return \"sse4.2\";\n                        if (runtimeMoniker <= RuntimeMoniker.NativeAot90) yield return \"popcnt\";\n                    }\n                    if (HardwareIntrinsics.IsX86AvxSupported) yield return \"avx\";\n                    if (HardwareIntrinsics.IsX86Avx2Supported)\n                    {\n                        yield return \"avx2\";\n\n                        if (runtimeMoniker <= RuntimeMoniker.NativeAot90)\n                        {\n                            yield return \"bmi\";\n                            yield return \"bmi2\";\n                            yield return \"fma\";\n                            yield return \"lzcnt\";\n                        }\n                    }\n                    if (HardwareIntrinsics.IsX86Avx512Supported && (runtimeMoniker > RuntimeMoniker.NativeAot80))\n                    {\n                        if (runtimeMoniker >= RuntimeMoniker.NativeAot10_0)\n                        {\n                            yield return \"avx512\";\n                        }\n                        else\n                        {\n                            yield return \"avx512f\";\n                            yield return \"avx512f_vl\";\n                            yield return \"avx512bw\";\n                            yield return \"avx512bw_vl\";\n                            yield return \"avx512cd\";\n                            yield return \"avx512cd_vl\";\n                            yield return \"avx512dq\";\n                            yield return \"avx512dq_vl\";\n                        }\n                    }\n                    if (HardwareIntrinsics.IsX86Avx512v2Supported && (runtimeMoniker > RuntimeMoniker.NativeAot80))\n                    {\n                        if (runtimeMoniker >= RuntimeMoniker.NativeAot10_0)\n                        {\n                            yield return \"avx512v2\";\n                        }\n                        else\n                        {\n                            yield return \"avx512vbmi\";\n                            yield return \"avx512vbmi_vl\";\n                        }\n                    }\n                    if (HardwareIntrinsics.IsX86Avx512v3Supported && (runtimeMoniker >= RuntimeMoniker.NativeAot10_0)) yield return \"avx512v3\";\n                    if (HardwareIntrinsics.IsX86Avx10v1Supported && (runtimeMoniker >= RuntimeMoniker.NativeAot90)) yield return \"avx10v1\";\n                    if (HardwareIntrinsics.IsX86Avx10v2Supported && (runtimeMoniker >= RuntimeMoniker.NativeAot10_0)) yield return \"avx10v2\";\n                    if (HardwareIntrinsics.IsX86AesSupported)\n                    {\n                        yield return \"aes\";\n                        if (runtimeMoniker <= RuntimeMoniker.NativeAot90) yield return \"pclmul\";\n                    }\n                    if (HardwareIntrinsics.IsX86AvxVnniSupported) yield return \"avxvnni\";\n                    if (HardwareIntrinsics.IsX86SerializeSupported && runtimeMoniker > RuntimeMoniker.NativeAot70) yield return \"serialize\"; // https://github.com/dotnet/BenchmarkDotNet/issues/2463#issuecomment-1809625008\n                    break;\n                case Platform.Arm64:\n                    if (HardwareIntrinsics.IsArmBaseSupported)\n                    {\n                        yield return \"base\";\n                        yield return \"neon\";\n                    }\n                    if (HardwareIntrinsics.IsArmAesSupported) yield return \"aes\";\n                    if (HardwareIntrinsics.IsArmCrc32Supported) yield return \"crc\";\n                    if (HardwareIntrinsics.IsArmDpSupported) yield return \"dotprod\";\n                    if (HardwareIntrinsics.IsArmRdmSupported) yield return \"rdma\";\n                    if (HardwareIntrinsics.IsArmSha1Supported) yield return \"sha1\";\n                    if (HardwareIntrinsics.IsArmSha256Supported) yield return \"sha2\";\n                    break;\n                default:\n                    yield break;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/NativeAot/NativeAotToolchain.cs",
    "content": "﻿using System.Collections.Generic;\nusing BenchmarkDotNet.Characteristics;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Toolchains.DotNetCli;\nusing BenchmarkDotNet.Validators;\n\nnamespace BenchmarkDotNet.Toolchains.NativeAot\n{\n    public class NativeAotToolchain : Toolchain\n    {\n        /// <summary>\n        /// compiled as net6.0, targets experimental 6.0.0-* NativeAOT build from the https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-experimental/nuget/v3/index.json\n        /// </summary>\n        public static readonly IToolchain Net60 = CreateBuilder()\n            .UseNuGet(\"6.0.0-*\", \"https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-experimental/nuget/v3/index.json\")\n            .TargetFrameworkMoniker(\"net6.0\")\n            .ToToolchain();\n\n        /// <summary>\n        /// compiled as net7.0, targets latest NativeAOT build from the NuGet.org feed\n        /// </summary>\n        public static readonly IToolchain Net70 = CreateBuilder()\n            .UseNuGet(\"\", \"https://api.nuget.org/v3/index.json\")\n            .TargetFrameworkMoniker(\"net7.0\")\n            .ToToolchain();\n\n        /// <summary>\n        /// compiled as net8.0, targets latest NativeAOT build from the NuGet.org feed: \"https://api.nuget.org/v3/index.json\"\n        /// </summary>\n        public static readonly IToolchain Net80 = CreateBuilder()\n            .UseNuGet(\"\", \"https://api.nuget.org/v3/index.json\")\n            .TargetFrameworkMoniker(\"net8.0\")\n            .ToToolchain();\n\n        /// <summary>\n        /// compiled as net9.0, targets latest NativeAOT build from the .NET 9 feed: https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet9/nuget/v3/index.json\n        /// </summary>\n        public static readonly IToolchain Net90 = CreateBuilder()\n            .UseNuGet(\"\", \"https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet9/nuget/v3/index.json\")\n            .TargetFrameworkMoniker(\"net9.0\")\n            .ToToolchain();\n\n        /// <summary>\n        /// compiled as net10.0, targets latest NativeAOT build from the .NET 10 feed: https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet10/nuget/v3/index.json\n        /// </summary>\n        public static readonly IToolchain Net10_0 = CreateBuilder()\n            .UseNuGet(\"\", \"https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet10/nuget/v3/index.json\")\n            .TargetFrameworkMoniker(\"net10.0\")\n            .ToToolchain();\n\n        /// <summary>\n        /// compiled as net11.0, targets latest NativeAOT build from the .NET 11 feed: https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet11/nuget/v3/index.json\n        /// </summary>\n        public static readonly IToolchain Net11_0 = CreateBuilder()\n            .UseNuGet(\"\", \"https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet11/nuget/v3/index.json\")\n            .TargetFrameworkMoniker(\"net11.0\")\n            .ToToolchain();\n\n        internal NativeAotToolchain(string displayName,\n            string ilCompilerVersion,\n            string runtimeFrameworkVersion, string targetFrameworkMoniker, string runtimeIdentifier,\n            string customDotNetCliPath, string packagesRestorePath,\n            Dictionary<string, string> feeds, bool useNuGetClearTag, bool useTempFolderForRestore,\n            bool rootAllApplicationAssemblies, bool ilcGenerateStackTraceData,\n            string ilcOptimizationPreference, string ilcInstructionSet)\n            : base(displayName,\n                new Generator(ilCompilerVersion, runtimeFrameworkVersion, targetFrameworkMoniker, customDotNetCliPath,\n                    runtimeIdentifier, feeds, useNuGetClearTag, useTempFolderForRestore, packagesRestorePath,\n                    rootAllApplicationAssemblies, ilcGenerateStackTraceData,\n                    ilcOptimizationPreference, ilcInstructionSet),\n                new DotNetCliPublisher(targetFrameworkMoniker, customDotNetCliPath, GetExtraArguments(runtimeIdentifier)),\n                new Executor())\n        {\n            CustomDotNetCliPath = customDotNetCliPath;\n        }\n\n        internal string CustomDotNetCliPath { get; }\n\n        public static NativeAotToolchainBuilder CreateBuilder() => NativeAotToolchainBuilder.Create();\n\n        public static string GetExtraArguments(string runtimeIdentifier) => $\"-r {runtimeIdentifier}\";\n\n        public override IEnumerable<ValidationError> Validate(BenchmarkCase benchmarkCase, IResolver resolver)\n        {\n            foreach (var error in base.Validate(benchmarkCase, resolver))\n            {\n                yield return error;\n            }\n\n            foreach (var validationError in DotNetSdkValidator.ValidateCoreSdks(CustomDotNetCliPath, benchmarkCase))\n            {\n                yield return validationError;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/NativeAot/NativeAotToolchainBuilder.cs",
    "content": "using System;\nusing System.Diagnostics.CodeAnalysis;\nusing System.IO;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Toolchains.DotNetCli;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Toolchains.NativeAot\n{\n    public class NativeAotToolchainBuilder : CustomDotNetCliToolchainBuilder\n    {\n        public static NativeAotToolchainBuilder Create() => new NativeAotToolchainBuilder();\n\n        private string? ilCompilerVersion;\n        private string? packagesRestorePath;\n        // we set those default values on purpose https://github.com/dotnet/BenchmarkDotNet/pull/1057#issuecomment-461832612\n        private bool rootAllApplicationAssemblies;\n        private bool ilcGenerateStackTraceData = true;\n        private string ilcOptimizationPreference = \"Speed\";\n        private string? ilcInstructionSet;\n\n        private bool isIlCompilerConfigured;\n\n        /// <summary>\n        /// creates a NativeAOT toolchain targeting NuGet build of Microsoft.DotNet.ILCompiler\n        /// Based on https://github.com/dotnet/runtimelab/blob/d0a37893a67c125f9b0cd8671846ff7d867df241/samples/HelloWorld/README.md#add-corert-to-your-project\n        /// </summary>\n        /// <param name=\"microsoftDotNetILCompilerVersion\">the version of Microsoft.DotNet.ILCompiler which should be used. The default is empty which maps to latest version.</param>\n        /// <param name=\"nuGetFeedUrl\">url to NuGet feed, The default is: \"https://api.nuget.org/v3/index.json\"</param>\n        [PublicAPI]\n        public NativeAotToolchainBuilder UseNuGet(string microsoftDotNetILCompilerVersion = \"\", string nuGetFeedUrl = \"https://api.nuget.org/v3/index.json\")\n        {\n            ilCompilerVersion = microsoftDotNetILCompilerVersion;\n\n            Feeds[Generator.NativeAotNuGetFeed] = nuGetFeedUrl ?? throw new ArgumentNullException(nameof(nuGetFeedUrl));\n\n            DisplayName(ilCompilerVersion.IsBlank() ? \"Latest ILCompiler\" : $\"ILCompiler {ilCompilerVersion}\");\n\n            isIlCompilerConfigured = true;\n\n            return this;\n        }\n\n        /// <summary>\n        /// creates a NativeAOT toolchain targeting local build of ILCompiler\n        /// Based on https://github.com/dotnet/runtime/blob/main/docs/workflow/building/coreclr/nativeaot.md\n        /// </summary>\n        /// <param name=\"ilcPackages\">the path to shipping packages, example: \"C:\\runtime\\artifacts\\packages\\Release\\Shipping\"</param>\n        [PublicAPI]\n        public NativeAotToolchainBuilder UseLocalBuild(DirectoryInfo ilcPackages)\n        {\n            if (!ilcPackages.Exists) \n                throw new DirectoryNotFoundException($\"{ilcPackages} provided as {nameof(ilcPackages)} does NOT exist\");\n\n            Feeds[\"local\"] = ilcPackages.FullName;\n            ilCompilerVersion = \"11.0.0-dev\";\n            Feeds[\"dotnet11\"] = \"https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet11/nuget/v3/index.json\";\n            useTempFolderForRestore = true;\n            DisplayName(\"local ILCompiler build\");\n\n            isIlCompilerConfigured = true;\n\n            return this;\n        }\n\n        /// <summary>\n        /// The directory to restore packages to (optional).\n        /// </summary>\n        [PublicAPI]\n        [SuppressMessage(\"ReSharper\", \"ParameterHidesMember\")]\n        public NativeAotToolchainBuilder PackagesRestorePath(string packagesRestorePath)\n        {\n            this.packagesRestorePath = packagesRestorePath;\n\n            return this;\n        }\n\n        /// <summary>\n        /// This controls the compiler behavior where all code in the application assemblies is considered dynamically reachable.\n        /// This option is disabled by default.\n        /// Enabling this option (true) has a significant effect on the size of the resulting executable because it prevents removal of unused code that would otherwise happen.\n        /// </summary>\n        [PublicAPI]\n        public NativeAotToolchainBuilder RootAllApplicationAssemblies(bool value)\n        {\n            rootAllApplicationAssemblies = value;\n\n            return this;\n        }\n\n        /// <summary>\n        /// This controls generation of stack trace metadata that provides textual names in stack traces.\n        /// This option is enabled by default.\n        /// This is for example the text string one gets by calling Exception.ToString() on a caught exception.\n        /// With this option disabled, stack traces will still be generated, but will be based on reflection metadata alone (they might be less complete).\n        /// </summary>\n        [PublicAPI]\n        public NativeAotToolchainBuilder IlcGenerateStackTraceData(bool value)\n        {\n            ilcGenerateStackTraceData = value;\n\n            return this;\n        }\n\n        /// <summary>\n        /// Options related to code generation.\n        /// </summary>\n        /// <param name=\"value\">\"Speed\" to favor code execution speed (default), \"Size\" to favor smaller code size</param>\n        [PublicAPI]\n        public NativeAotToolchainBuilder IlcOptimizationPreference(string value = \"Speed\")\n        {\n            ilcOptimizationPreference = value;\n\n            return this;\n        }\n\n        /// <summary>\n        /// By default, the compiler targets the minimum instruction set supported by the target OS and architecture.\n        /// This option allows targeting newer instruction sets for better performance.\n        /// The native binary will require the instruction sets to be supported by the hardware in order to run.\n        /// For example, `avx2,bmi2,fma,pclmul,popcnt,aes` will produce binary that takes advantage of instruction sets\n        /// that are typically present on current Intel and AMD processors.\n        /// </summary>\n        /// <param name=\"value\">Specify empty string (\"\", not null) to use the defaults.</param>\n        [PublicAPI]\n        public NativeAotToolchainBuilder IlcInstructionSet(string value)\n        {\n            ilcInstructionSet = value;\n\n            return this;\n        }\n\n        [PublicAPI]\n        public override IToolchain ToToolchain()\n        {\n            if (!isIlCompilerConfigured)\n                throw new InvalidOperationException(\"You need to use UseNuGet or UseLocalBuild methods to tell us which ILCompiler to use.\");\n\n            return new NativeAotToolchain(\n                displayName: displayName!,\n                ilCompilerVersion: ilCompilerVersion!,\n                runtimeFrameworkVersion: runtimeFrameworkVersion ?? \"\",\n                targetFrameworkMoniker: GetTargetFrameworkMoniker(),\n                runtimeIdentifier: runtimeIdentifier ?? GetPortableRuntimeIdentifier(),\n                customDotNetCliPath: customDotNetCliPath ?? \"\",\n                packagesRestorePath: packagesRestorePath ?? \"\",\n                feeds: Feeds,\n                useNuGetClearTag: useNuGetClearTag,\n                useTempFolderForRestore: useTempFolderForRestore,\n                rootAllApplicationAssemblies: rootAllApplicationAssemblies,\n                ilcGenerateStackTraceData: ilcGenerateStackTraceData,\n                ilcOptimizationPreference: ilcOptimizationPreference,\n                ilcInstructionSet: ilcInstructionSet ?? \"\"\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/Parameters/ExecuteParameters.cs",
    "content": "﻿using BenchmarkDotNet.Characteristics;\nusing BenchmarkDotNet.Diagnosers;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Toolchains.Results;\nusing System;\n\nnamespace BenchmarkDotNet.Toolchains.Parameters\n{\n    public class ExecuteParameters(BuildResult buildResult, BenchmarkCase benchmarkCase, BenchmarkId benchmarkId,\n        ILogger logger, IResolver resolver, int launchIndex,\n        CompositeInProcessDiagnoser compositeInProcessDiagnoser,\n        IDiagnoser? diagnoser = null, RunMode diagnoserRunMode = RunMode.None)\n    {\n        internal static readonly TimeSpan ProcessExitTimeout = TimeSpan.FromSeconds(2);\n\n        public BuildResult BuildResult { get; } = buildResult;\n\n        public BenchmarkCase BenchmarkCase { get; } = benchmarkCase;\n\n        public BenchmarkId BenchmarkId { get; } = benchmarkId;\n\n        public ILogger Logger { get; } = logger;\n\n        public IResolver Resolver { get; } = resolver;\n\n        public CompositeInProcessDiagnoser CompositeInProcessDiagnoser { get; } = compositeInProcessDiagnoser;\n\n        public IDiagnoser? Diagnoser { get; } = diagnoser;\n\n        public int LaunchIndex { get; } = launchIndex;\n\n        public RunMode DiagnoserRunMode { get; } = diagnoserRunMode;\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/R2R/R2RGenerator.cs",
    "content": "﻿using System.IO;\nusing System.Text;\nusing System.Xml;\nusing BenchmarkDotNet.Detectors;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Helpers;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Toolchains.CsProj;\nusing BenchmarkDotNet.Toolchains.DotNetCli;\n\nnamespace BenchmarkDotNet.Toolchains.R2R\n{\n    public class R2RGenerator : CsProjGenerator\n    {\n        private readonly string CustomRuntimePack;\n        private readonly string Crossgen2Pack;\n\n        public R2RGenerator(string targetFrameworkMoniker, string cliPath, string packagesPath, string customRuntimePack, string crossgen2Pack)\n            : base(targetFrameworkMoniker, cliPath, packagesPath)\n        {\n            CustomRuntimePack = customRuntimePack;\n            Crossgen2Pack = crossgen2Pack;\n            BenchmarkRunCallType = Code.CodeGenBenchmarkRunCallType.Direct;\n        }\n\n        protected override void GenerateProject(BuildPartition buildPartition, ArtifactsPaths artifactsPaths, ILogger logger)\n        {\n            BenchmarkCase benchmark = buildPartition.RepresentativeBenchmarkCase;\n            var projectFile = GetProjectFilePath(benchmark.Descriptor.Type, logger);\n\n            var xmlDoc = new XmlDocument();\n            xmlDoc.Load(projectFile.FullName);\n            var (customProperties, sdkName) = GetSettingsThatNeedToBeCopied(xmlDoc, projectFile);\n\n            string content = new StringBuilder(ResourceHelper.LoadTemplate(\"R2RCsProj.txt\"))\n                .Replace(\"$PLATFORM$\", buildPartition.Platform.ToConfig())\n                .Replace(\"$CODEFILENAME$\", Path.GetFileName(artifactsPaths.ProgramCodePath))\n                .Replace(\"$CSPROJPATH$\", projectFile.FullName)\n                .Replace(\"$TFM$\", TargetFrameworkMoniker)\n                .Replace(\"$PROGRAMNAME$\", artifactsPaths.ProgramName)\n                .Replace(\"$COPIEDSETTINGS$\", customProperties)\n                .Replace(\"$SDKNAME$\", sdkName)\n                .Replace(\"$RUNTIMEPACK$\", CustomRuntimePack)\n                .Replace(\"$CROSSGEN2PACK$\", Crossgen2Pack)\n                .Replace(\"$RUNTIMEIDENTIFIER$\", CustomDotNetCliToolchainBuilder.GetPortableRuntimeIdentifier())\n                .ToString();\n\n            File.WriteAllText(artifactsPaths.ProjectFilePath, content);\n\n            GatherReferences(buildPartition, artifactsPaths, logger);\n        }\n\n        protected override string GetExecutableExtension() => OsDetector.ExecutableExtension;\n\n        protected override string GetBinariesDirectoryPath(string buildArtifactsDirectoryPath, string configuration)\n            => Path.Combine(buildArtifactsDirectoryPath, \"bin\", configuration, TargetFrameworkMoniker, CustomDotNetCliToolchainBuilder.GetPortableRuntimeIdentifier(), \"publish\");\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/R2R/R2RToolchain.cs",
    "content": "﻿using BenchmarkDotNet.Characteristics;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Toolchains.CsProj;\nusing BenchmarkDotNet.Toolchains.DotNetCli;\nusing BenchmarkDotNet.Validators;\nusing JetBrains.Annotations;\nusing System;\nusing System.Collections.Generic;\n\nnamespace BenchmarkDotNet.Toolchains.R2R\n{\n    [PublicAPI]\n    public class R2RToolchain : CsProjCoreToolchain, IEquatable<R2RToolchain>\n    {\n        [PublicAPI] public static readonly IToolchain R2R80 = From(new NetCoreAppSettings(\"net8.0\", \"R2R 8.0\"));\n        [PublicAPI] public static readonly IToolchain R2R90 = From(new NetCoreAppSettings(\"net9.0\", \"R2R 9.0\"));\n        [PublicAPI] public static readonly IToolchain R2R10_0 = From(new NetCoreAppSettings(\"net10.0\", \"R2R 10.0\"));\n        [PublicAPI] public static readonly IToolchain R2R11_0 = From(new NetCoreAppSettings(\"net11.0\", \"R2R 11.0\"));\n\n        private readonly string _customDotNetCliPath;\n        private R2RToolchain(string name, IGenerator generator, IBuilder builder, IExecutor executor, string customDotNetCliPath)\n            : base(name, generator, builder, executor, customDotNetCliPath)\n        {\n            _customDotNetCliPath = customDotNetCliPath;\n        }\n\n        [PublicAPI]\n        public static new IToolchain From(NetCoreAppSettings settings)\n            => new R2RToolchain(settings.Name,\n                new R2RGenerator(settings.TargetFrameworkMoniker, settings.CustomDotNetCliPath, settings.PackagesPath, settings.CustomRuntimePack, settings.AOTCompilerPath),\n                new DotNetCliPublisher(settings.TargetFrameworkMoniker, settings.CustomDotNetCliPath),\n                new Executor(),\n                settings.CustomDotNetCliPath);\n\n        public override IEnumerable<ValidationError> Validate(BenchmarkCase benchmarkCase, IResolver resolver)\n        {\n            foreach (var validationError in DotNetSdkValidator.ValidateCoreSdks(_customDotNetCliPath, benchmarkCase))\n            {\n                yield return validationError;\n            }\n        }\n\n        public override bool Equals(object? obj) => obj is R2RToolchain typed && Equals(typed);\n\n        public bool Equals(R2RToolchain? other)\n        {\n            if (ReferenceEquals(this, other))\n                return true;\n\n            if (other is null)\n                return false;\n\n            return Generator.Equals(other.Generator);\n        }\n\n        public override int GetHashCode() => Generator.GetHashCode();\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/Results/BuildResult.cs",
    "content": "﻿using System;\nusing System.Diagnostics.CodeAnalysis;\nusing BenchmarkDotNet.Toolchains.DotNetCli;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Toolchains.Results\n{\n    [PublicAPI]\n    public class BuildResult : GenerateResult\n    {\n        public bool IsBuildSuccess { get; }\n        public string ErrorMessage { get; }\n\n        private BuildResult(GenerateResult generateResult, bool isBuildSuccess, string errorMessage)\n            : base(generateResult.ArtifactsPaths, generateResult.IsGenerateSuccess, generateResult.GenerateException, generateResult.ArtifactsToCleanup)\n        {\n            IsBuildSuccess = isBuildSuccess;\n            ErrorMessage = errorMessage;\n        }\n\n        [PublicAPI]\n        public static BuildResult Success(GenerateResult generateResult)\n            => new BuildResult(generateResult, true, errorMessage: \"\");\n\n        [PublicAPI]\n        public static BuildResult Failure(GenerateResult generateResult, string errorMessage)\n            => new BuildResult(generateResult, false, errorMessage);\n\n        [PublicAPI]\n        public static BuildResult Failure(GenerateResult generateResult, Exception exception)\n            => new BuildResult(generateResult, false, $\"Exception! {Environment.NewLine}Message: {exception.Message},{Environment.NewLine}Stack trace:{Environment.NewLine}{exception.StackTrace}\");\n\n        public override string ToString() => \"BuildResult: \" + (IsBuildSuccess ? \"Success\" : \"Failure\");\n\n        internal bool TryToExplainFailureReason([NotNullWhen(true)] out string? reason) => MsBuildErrorMapper.TryToExplainFailureReason(this, out reason);\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/Results/ExecuteResult.cs",
    "content": "﻿using BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Validators;\nusing System.Collections.Generic;\nusing System.Linq;\n\nnamespace BenchmarkDotNet.Toolchains.Results\n{\n    public class ExecuteResult\n    {\n        public bool FoundExecutable { get; }\n        public int? ExitCode { get; }\n        public int? ProcessId { get; }\n        public IReadOnlyList<string> Errors => errors;\n        public IReadOnlyList<Measurement> Measurements => measurements;\n\n        /// <summary>\n        /// All lines printed to standard output by the Benchmark process\n        /// </summary>\n        public IReadOnlyList<string> StandardOutput { get; }\n\n        /// <summary>\n        /// Lines reported by the Benchmark process that are starting with \"//\"\n        /// </summary>\n        public IReadOnlyList<string> PrefixedLines { get; }\n\n        /// <summary>\n        /// Lines reported by the Benchmark process that are not starting with \"//\"\n        /// </summary>\n        public IReadOnlyList<string> Results { get; }\n\n        internal readonly GcStats GcStats;\n        private readonly List<string> errors;\n        private readonly List<Measurement> measurements;\n\n        // benchmark can fail after few Workload Actual iterations\n        // that is why we search for Workload Results as they are produced at the end\n        public bool IsSuccess => Measurements.Any(m => m.Is(IterationMode.Workload, IterationStage.Result));\n\n        public ExecuteResult(bool foundExecutable, int? exitCode, int? processId, IReadOnlyList<string> results, IReadOnlyList<string> prefixedLines, IReadOnlyList<string> standardOutput, int launchIndex)\n        {\n            FoundExecutable = foundExecutable;\n            Results = results;\n            ProcessId = processId;\n            ExitCode = exitCode;\n            PrefixedLines = prefixedLines;\n            StandardOutput = standardOutput;\n            Parse(results, prefixedLines, launchIndex, out measurements, out errors, out GcStats);\n        }\n\n        internal ExecuteResult(List<Measurement> measurements, GcStats gcStats)\n        {\n            FoundExecutable = true;\n            ExitCode = 0;\n            errors = [];\n            PrefixedLines = [];\n            this.measurements = measurements;\n            GcStats = gcStats;\n            StandardOutput = [];\n            Results = [];\n        }\n\n        internal ExecuteResult(List<Measurement> measurements)\n        {\n            FoundExecutable = true;\n            ExitCode = 0;\n            errors = [];\n            PrefixedLines = [];\n            this.measurements = measurements;\n            GcStats = GcStats.Empty;\n            StandardOutput = [];\n            Results = [];\n        }\n\n        internal static ExecuteResult FromRunResults(RunResults runResults, int exitCode)\n            => exitCode != 0\n                ? CreateFailed(exitCode)\n                : new ExecuteResult([.. runResults.GetAllMeasurements()], runResults.GCStats);\n\n        internal static ExecuteResult CreateFailed(int exitCode = -1)\n            => new(false, exitCode, default, [], [], [], 0);\n\n        internal static ExecuteResult CreateFailed(string error)\n        {\n            var result = new ExecuteResult(false, -1, default, [], [], [], 0);\n            result.errors.Add(error);\n            return result;\n        }\n\n        public override string ToString() => \"ExecuteResult: \" + (FoundExecutable ? \"Found executable\" : \"Executable not found\");\n\n        public void LogIssues(ILogger logger, BuildResult buildResult)\n        {\n            if (!FoundExecutable)\n            {\n                logger.WriteLineError($\"Executable {buildResult.ArtifactsPaths.ExecutablePath} not found\");\n            }\n\n            // exit code can be different than 0 if the process has hanged at the end\n            // so we check if some results were reported, if not then it was a failure\n            if (ExitCode != 0 && Results.Count == 0)\n            {\n                logger.WriteLineError(\"ExitCode != 0 and no results reported\");\n            }\n\n            foreach (string error in Errors)\n            {\n                logger.WriteLineError(error);\n            }\n\n            if (!Measurements.Any(m => m.Is(IterationMode.Workload, IterationStage.Result)))\n            {\n                logger.WriteLineError(\"No Workload Results were obtained from the run.\");\n            }\n        }\n\n        private static void Parse(IReadOnlyList<string> results, IReadOnlyList<string> prefixedLines, int launchIndex, out List<Measurement> measurements,\n            out List<string> errors, out GcStats gcStats)\n        {\n            measurements = [];\n            errors = [];\n            gcStats = default;\n\n            foreach (string line in results.Where(text => !string.IsNullOrEmpty(text)))\n            {\n                Measurement measurement = Measurement.Parse(line, launchIndex);\n                if (measurement.IterationMode != IterationMode.Unknown)\n                {\n                    measurements.Add(measurement);\n                }\n            }\n\n            foreach (string line in prefixedLines.Where(text => !string.IsNullOrEmpty(text)))\n            {\n                if (line.StartsWith(ValidationErrorReporter.ConsoleErrorPrefix))\n                {\n                    errors.Add(line[ValidationErrorReporter.ConsoleErrorPrefix.Length..].Trim());\n                }\n                else if (line.StartsWith(GcStats.ResultsLinePrefix))\n                {\n                    gcStats = GcStats.Parse(line);\n                }\n            }\n\n            if (errors.Count > 0)\n            {\n                measurements.Clear();\n                gcStats = default;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/Results/GenerateResult.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\n\nnamespace BenchmarkDotNet.Toolchains.Results\n{\n    public class GenerateResult\n    {\n        public ArtifactsPaths ArtifactsPaths { get; }\n        public bool IsGenerateSuccess { get; }\n        public Exception? GenerateException { get; }\n        public IReadOnlyCollection<string> ArtifactsToCleanup { get; }\n\n        public GenerateResult(ArtifactsPaths artifactsPaths, bool isGenerateSuccess, Exception? generateException,\n            IReadOnlyCollection<string> artifactsToCleanup)\n        {\n            ArtifactsPaths = artifactsPaths;\n            IsGenerateSuccess = isGenerateSuccess;\n            GenerateException = generateException;\n            ArtifactsToCleanup = artifactsToCleanup;\n        }\n\n        public static GenerateResult Success(ArtifactsPaths artifactsPaths, IReadOnlyCollection<string> artifactsToCleanup)\n            => new GenerateResult(artifactsPaths, true, null, artifactsToCleanup);\n\n        public static GenerateResult Failure(ArtifactsPaths artifactsPaths, IReadOnlyCollection<string> artifactsToCleanup, Exception? exception = null)\n            => new GenerateResult(artifactsPaths, false, exception, artifactsToCleanup);\n\n        public override string ToString() => \"GenerateResult: \" + (IsGenerateSuccess ? \"Success\" : \"Fail\");\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/Roslyn/Builder.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Globalization;\nusing System.IO;\nusing System.Linq;\nusing System.Reflection;\nusing System.Text;\nusing System.Threading;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Toolchains.Results;\nusing JetBrains.Annotations;\nusing Microsoft.CodeAnalysis;\nusing Microsoft.CodeAnalysis.CSharp;\nusing Microsoft.CodeAnalysis.Emit;\nusing OurPlatform = BenchmarkDotNet.Environments.Platform;\n\nnamespace BenchmarkDotNet.Toolchains.Roslyn\n{\n    [PublicAPI]\n    public class Builder : IBuilder\n    {\n        private const string MissingReferenceError = \"CS0012\";\n\n        public static readonly IBuilder Instance = new Builder();\n\n        private static readonly Lazy<AssemblyMetadata[]> FrameworkAssembliesMetadata = new Lazy<AssemblyMetadata[]>(GetFrameworkAssembliesMetadata);\n\n        [PublicAPI]\n        public BuildResult Build(GenerateResult generateResult, BuildPartition buildPartition, ILogger logger)\n        {\n            logger.WriteLineInfo($\"BuildScript: {generateResult.ArtifactsPaths.BuildScriptFilePath}\");\n\n            CancellationTokenSource cts = new CancellationTokenSource(buildPartition.Timeout);\n            try\n            {\n                return Build(generateResult, buildPartition, logger, cts.Token);\n            }\n            catch (OperationCanceledException)\n            {\n                return BuildResult.Failure(generateResult, $\"The configured timeout {buildPartition.Timeout} was reached!\");\n            }\n            finally\n            {\n                cts.Dispose();\n            }\n        }\n\n        private BuildResult Build(GenerateResult generateResult, BuildPartition buildPartition, ILogger logger, CancellationToken cancellationToken)\n        {\n            var syntaxTree = CSharpSyntaxTree.ParseText(\n                text: File.ReadAllText(generateResult.ArtifactsPaths.ProgramCodePath),\n                // this version is used to parse the boilerplate code generated by BDN, so th benchmark themselves can use more recent version\n                options: new CSharpParseOptions(LanguageVersion.CSharp7_3),\n                cancellationToken: cancellationToken);\n\n            var compilationOptions = new CSharpCompilationOptions(\n                outputKind: OutputKind.ConsoleApplication,\n                optimizationLevel: OptimizationLevel.Release,\n                allowUnsafe: true,\n                platform: GetPlatform(buildPartition.Platform),\n                deterministic: true);\n\n            compilationOptions = compilationOptions.WithIgnoreCorLibraryDuplicatedTypes();\n\n            var references = Generator\n                .GetAllReferences(buildPartition.RepresentativeBenchmarkCase)\n                .Select(assembly => AssemblyMetadata.CreateFromFile(assembly.Location))\n                .Concat(FrameworkAssembliesMetadata.Value)\n                .Distinct()\n                .Select(uniqueMetadata => uniqueMetadata.GetReference())\n                .ToList();\n\n            var (result, missingReferences) = Build(generateResult, buildPartition, syntaxTree, compilationOptions, references, cancellationToken);\n\n            if (result.IsBuildSuccess || !missingReferences.Any())\n                return result;\n\n            var withMissingReferences = references.Union(missingReferences.Select(assemblyMetadata => assemblyMetadata.GetReference()));\n\n            return Build(generateResult, buildPartition, syntaxTree, compilationOptions, withMissingReferences, cancellationToken).result;\n        }\n\n        private static (BuildResult result, AssemblyMetadata[] missingReference) Build(GenerateResult generateResult, BuildPartition buildPartition, SyntaxTree syntaxTree,\n            CSharpCompilationOptions compilationOptions, IEnumerable<PortableExecutableReference> references, CancellationToken cancellationToken)\n        {\n            var compilation = CSharpCompilation\n                .Create(assemblyName: Path.GetFileName(generateResult.ArtifactsPaths.ExecutablePath))\n                .AddSyntaxTrees(syntaxTree)\n                .WithOptions(compilationOptions)\n                .AddReferences(references);\n\n            EmitResult emitResult;\n            using (var executable = File.Create(generateResult.ArtifactsPaths.ExecutablePath))\n            {\n                emitResult = compilation.Emit(executable, cancellationToken: cancellationToken);\n            }\n            if (emitResult.Success)\n            {\n                if (buildPartition.RepresentativeBenchmarkCase.Job.Environment.LargeAddressAware)\n                {\n                    LargeAddressAware.SetLargeAddressAware(generateResult.ArtifactsPaths.ExecutablePath);\n                }\n                return (BuildResult.Success(generateResult), missingReference: []);\n            }\n\n            var compilationErrors = emitResult.Diagnostics\n                .Where(diagnostic => diagnostic.IsWarningAsError || diagnostic.Severity == DiagnosticSeverity.Error)\n                .ToArray();\n\n            var errors = new StringBuilder(\"The build has failed!\").AppendLine();\n            foreach (var diagnostic in compilationErrors)\n                errors.AppendLine($\"{diagnostic.Id}: {diagnostic.GetMessage(CultureInfo.InvariantCulture)}\");\n\n            var missingReferences = GetMissingReferences(compilationErrors);\n\n            return (BuildResult.Failure(generateResult, errors.ToString()), missingReferences);\n        }\n\n        private Platform GetPlatform(OurPlatform platform)\n        {\n            switch (platform)\n            {\n                case OurPlatform.AnyCpu:\n                    return Platform.AnyCpu;\n                case OurPlatform.X86:\n                    return Platform.X86;\n                case OurPlatform.X64:\n                    return Platform.X64;\n                case OurPlatform.Arm:\n                    return Platform.Arm;\n                case OurPlatform.Arm64:\n                    return Platform.Arm64;\n                default:\n                    throw new ArgumentOutOfRangeException(nameof(platform), platform, null);\n            }\n        }\n\n        private static AssemblyMetadata[] GetFrameworkAssembliesMetadata()\n            => GetFrameworkAssembliesPaths()\n                .Where(File.Exists)\n                .Select(AssemblyMetadata.CreateFromFile)\n                .ToArray();\n\n        private static string[] GetFrameworkAssembliesPaths()\n        {\n            string? frameworkAssembliesDirectory = Path.GetDirectoryName(typeof(object).Assembly.Location);\n            if (frameworkAssembliesDirectory == null)\n                return [];\n\n            return\n            [\n                Path.Combine(frameworkAssembliesDirectory, \"mscorlib.dll\"),\n                Path.Combine(frameworkAssembliesDirectory, \"System.dll\"),\n                Path.Combine(frameworkAssembliesDirectory, \"System.Core.dll\"),\n                Path.Combine(frameworkAssembliesDirectory, \"System.Runtime.dll\")\n            ];\n        }\n\n        private static AssemblyMetadata[] GetMissingReferences(Diagnostic[] compilationErrors)\n            => compilationErrors\n                    .Where(diagnostic => diagnostic.Id == MissingReferenceError)\n                    .Select(GetAssemblyName)\n                    .WhereNotNull()\n                    .Distinct()\n                    .Select(assemblyName => Assembly.Load(new AssemblyName(assemblyName)))\n                    .Where(assembly => assembly != default)\n                    .Select(assembly => AssemblyMetadata.CreateFromFile(assembly.Location))\n                    .ToArray();\n\n        private static string? GetAssemblyName(Diagnostic diagnostic)\n        {\n            if (diagnostic.Id != MissingReferenceError)\n                return default;\n\n            string message = diagnostic.GetMessage(CultureInfo.InvariantCulture);\n            if (!message.Contains(\"You must add a reference to assembly\"))\n                return default;\n\n            // there is no nice property which would expose the reference name, so we need to some parsing..\n            // CS0012: The type 'ValueType' is defined in an assembly that is not referenced. You must add a reference to assembly 'netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'\n            return message.Split('\\'').SingleOrDefault(text => text.Contains(\"Version=\"));\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/Roslyn/Generator.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Reflection;\nusing BenchmarkDotNet.Detectors;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Portability;\nusing BenchmarkDotNet.Running;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Toolchains.Roslyn\n{\n    [PublicAPI]\n    public class Generator : GeneratorBase\n    {\n        protected override string GetBuildArtifactsDirectoryPath(BuildPartition buildPartition, string programName)\n            => Path.GetDirectoryName(buildPartition.AssemblyLocation)!;\n\n        [PublicAPI]\n        protected override string[] GetArtifactsToCleanup(ArtifactsPaths artifactsPaths)\n            =>\n            [\n                artifactsPaths.ProgramCodePath,\n                artifactsPaths.AppConfigPath,\n                artifactsPaths.BuildScriptFilePath,\n                artifactsPaths.ExecutablePath\n            ];\n\n        protected override void GenerateBuildScript(BuildPartition buildPartition, ArtifactsPaths artifactsPaths)\n        {\n            string prefix = OsDetector.IsWindows() ? \"\" : \"#!/bin/bash\\n\";\n            var list = new List<string>();\n            if (!OsDetector.IsWindows())\n                list.Add(\"mono\");\n            list.Add(\"csc\");\n            list.Add(\"/noconfig\");\n            list.Add(\"/target:exe\");\n            list.Add(\"/optimize\");\n            list.Add(\"/unsafe\");\n            list.Add(\"/deterministic\");\n            list.Add(\"/platform:\" + buildPartition.Platform.ToConfig());\n            list.Add(\"/appconfig:\" + artifactsPaths.AppConfigPath.EscapeCommandLine());\n            var references = GetAllReferences(buildPartition.RepresentativeBenchmarkCase).Select(assembly => assembly.Location.EscapeCommandLine());\n            list.Add(\"/reference:\" + string.Join(\",\", references));\n            list.Add(Path.GetFileName(artifactsPaths.ProgramCodePath));\n\n            File.WriteAllText(\n                artifactsPaths.BuildScriptFilePath,\n                prefix + string.Join(\" \", list));\n        }\n\n        internal static IEnumerable<Assembly> GetAllReferences(BenchmarkCase benchmarkCase)\n            => benchmarkCase.Descriptor.Type.GetTypeInfo().Assembly\n                .GetReferencedAssemblies()\n                .Select(Assembly.Load)\n                .Concat(\n                    [\n                        benchmarkCase.Descriptor.Type.GetTypeInfo().Assembly, // this assembly does not has to have a reference to BenchmarkDotNet (e.g. custom framework for benchmarking that internally uses BenchmarkDotNet\n                        typeof(BenchmarkCase).Assembly // BenchmarkDotNet\n                    ])\n                .Distinct();\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/Roslyn/RoslynToolchain.cs",
    "content": "﻿using System.Collections.Generic;\nusing BenchmarkDotNet.Characteristics;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Portability;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Validators;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Toolchains.Roslyn\n{\n    /// <summary>\n    /// Build a benchmark program with the Roslyn compiler.\n    /// </summary>\n    [PublicAPI]\n    public class RoslynToolchain : Toolchain\n    {\n        public static readonly IToolchain Instance = new RoslynToolchain();\n\n        [PublicAPI]\n        public RoslynToolchain() : base(\"Roslyn\", new Generator(), Roslyn.Builder.Instance, new Executor())\n        {\n        }\n\n        [PublicAPI]\n        public override IEnumerable<ValidationError> Validate(BenchmarkCase benchmarkCase, IResolver resolver)\n        {\n            foreach (var validationError in base.Validate(benchmarkCase, resolver))\n            {\n                yield return validationError;\n            }\n\n            if (!RuntimeInformation.IsFullFramework)\n            {\n                yield return new ValidationError(true,\n                    \"The Roslyn toolchain is only supported on .NET Framework\",\n                    benchmarkCase);\n            }\n\n            if (benchmarkCase.Job.ResolveValue(GcMode.RetainVmCharacteristic, resolver))\n            {\n                yield return new ValidationError(true,\n                    $\"Currently App.config does not support RetainVM option, benchmark '{benchmarkCase.DisplayInfo}' will not be executed\",\n                    benchmarkCase);\n            }\n\n            if (benchmarkCase.Job.HasValue(InfrastructureMode.BuildConfigurationCharacteristic)\n                && benchmarkCase.Job.ResolveValue(InfrastructureMode.BuildConfigurationCharacteristic, resolver) != InfrastructureMode.ReleaseConfigurationName)\n            {\n                yield return new ValidationError(true,\n                    \"The Roslyn toolchain does not allow to rebuild source project, so defining custom build configuration makes no sense\",\n                    benchmarkCase);\n            }\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/Roslyn/RoslynWorkarounds.cs",
    "content": "﻿using System.Reflection;\nusing Microsoft.CodeAnalysis.CSharp;\n\nnamespace BenchmarkDotNet.Toolchains.Roslyn\n{\n    internal static class RoslynWorkarounds\n    {\n        internal static CSharpCompilationOptions WithIgnoreCorLibraryDuplicatedTypes(this CSharpCompilationOptions compilationOptions)\n        {\n            // this prevents from\n            // The type 'ValueTuple<T1>' exists in both 'System.ValueTuple, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51' and 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'\n            // idea taken from: https://github.com/OmniSharp/omnisharp-roslyn/pull/785\n\n            var topLevelBinderFlagsProperty = typeof(CSharpCompilationOptions).GetProperty(\"TopLevelBinderFlags\", BindingFlags.Instance | BindingFlags.NonPublic);\n            var binderFlagsType = typeof(CSharpCompilationOptions).GetTypeInfo().Assembly.GetType(\"Microsoft.CodeAnalysis.CSharp.BinderFlags\");\n\n            var ignoreCorLibraryDuplicatedTypesMember = binderFlagsType?.GetField(\"IgnoreCorLibraryDuplicatedTypes\", BindingFlags.Static | BindingFlags.Public);\n            var ignoreCorLibraryDuplicatedTypesValue = ignoreCorLibraryDuplicatedTypesMember?.GetValue(null);\n            if (ignoreCorLibraryDuplicatedTypesValue != null)\n            {\n                topLevelBinderFlagsProperty?.SetValue(compilationOptions, ignoreCorLibraryDuplicatedTypesValue);\n            }\n\n            return compilationOptions;\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/Toolchain.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.IO;\nusing BenchmarkDotNet.Characteristics;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Validators;\n\nnamespace BenchmarkDotNet.Toolchains\n{\n    public class Toolchain : IToolchain\n    {\n        public string Name { get; }\n\n        public IGenerator Generator { get; }\n\n        public IBuilder Builder { get; }\n\n        public IExecutor Executor { get; }\n\n        public virtual bool IsInProcess => false;\n\n        public Toolchain(string name, IGenerator generator, IBuilder builder, IExecutor executor)\n        {\n            Name = name;\n            Generator = generator;\n            Builder = builder;\n            Executor = executor;\n        }\n\n        public virtual IEnumerable<ValidationError> Validate(BenchmarkCase benchmarkCase, IResolver resolver)\n        {\n            var runtime = benchmarkCase.Job.ResolveValue(EnvironmentMode.RuntimeCharacteristic, resolver);\n            var jit = benchmarkCase.Job.ResolveValue(EnvironmentMode.JitCharacteristic, resolver);\n            if (!(runtime is MonoRuntime) && jit == Jit.Llvm)\n            {\n                yield return new ValidationError(true,\n                    $\"Llvm is supported only for Mono, benchmark '{benchmarkCase.DisplayInfo}' will not be executed\",\n                    benchmarkCase);\n            }\n\n            if (runtime is MonoRuntime mono && !mono.IsDotNetBuiltIn && !benchmarkCase.GetToolchain().IsInProcess)\n            {\n                if (mono.CustomPath.IsBlank() && !HostEnvironmentInfo.GetCurrent().IsMonoInstalled.Value)\n                {\n                    yield return new ValidationError(true,\n                        $\"Mono is not installed or added to PATH, benchmark '{benchmarkCase.DisplayInfo}' will not be executed\",\n                        benchmarkCase);\n                }\n\n                if (mono.CustomPath.IsNotBlank() && !File.Exists(mono.CustomPath))\n                {\n                    yield return new ValidationError(true,\n                        $\"We could not find Mono in provided path ({mono.CustomPath}), benchmark '{benchmarkCase.DisplayInfo}' will not be executed\",\n                        benchmarkCase);\n                }\n            }\n        }\n\n        public override string ToString() => Name;\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Toolchains/ToolchainExtensions.cs",
    "content": "﻿using System;\nusing BenchmarkDotNet.Detectors;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Portability;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Toolchains.R2R;\nusing BenchmarkDotNet.Toolchains.CsProj;\nusing BenchmarkDotNet.Toolchains.DotNetCli;\nusing BenchmarkDotNet.Toolchains.InProcess.Emit;\nusing BenchmarkDotNet.Toolchains.InProcess.NoEmit;\nusing BenchmarkDotNet.Toolchains.Mono;\nusing BenchmarkDotNet.Toolchains.MonoWasm;\nusing BenchmarkDotNet.Toolchains.NativeAot;\nusing BenchmarkDotNet.Toolchains.Roslyn;\n\nnamespace BenchmarkDotNet.Toolchains\n{\n    internal static class ToolchainExtensions\n    {\n        internal static IToolchain GetToolchain(this BenchmarkCase benchmarkCase)\n            => benchmarkCase.Job.Infrastructure.TryGetToolchain(out var toolchain)\n                ? toolchain\n                : GetToolchain(\n                    benchmarkCase.GetRuntime(),\n                    benchmarkCase.Descriptor,\n                    benchmarkCase.Job.HasDynamicBuildCharacteristic(),\n                    benchmarkCase.Job.Environment.HasValue(EnvironmentMode.RuntimeCharacteristic)\n                );\n\n        internal static IToolchain GetToolchain(this Job job)\n            => job.Infrastructure.TryGetToolchain(out var toolchain)\n                ? toolchain\n                : GetToolchain(\n                    job.ResolveValue(EnvironmentMode.RuntimeCharacteristic, EnvironmentResolver.Instance)!,\n                    null,\n                    job.HasDynamicBuildCharacteristic(),\n                    job.Environment.HasValue(EnvironmentMode.RuntimeCharacteristic)\n                );\n\n        internal static IToolchain GetToolchain(this Runtime runtime, Descriptor? descriptor = null, bool preferMsBuildToolchains = false, bool isRuntimeExplicit = false)\n        {\n            switch (runtime)\n            {\n                case ClrRuntime clrRuntime:\n                    bool UseRoslyn()\n                        => !isRuntimeExplicit\n                        || runtime.MsBuildMoniker == ClrRuntime.GetTargetOrCurrentVersion(descriptor?.WorkloadMethod.DeclaringType?.Assembly).MsBuildMoniker;\n\n                    if (!preferMsBuildToolchains && RuntimeInformation.IsFullFramework && UseRoslyn())\n                        return RoslynToolchain.Instance;\n\n                    return clrRuntime.RuntimeMoniker != RuntimeMoniker.NotRecognized\n                        ? GetToolchain(clrRuntime.RuntimeMoniker)\n                        : CsProjClassicNetToolchain.From(clrRuntime.MsBuildMoniker);\n\n                case MonoRuntime mono:\n                    if (OsDetector.IsAndroid())\n                        return InProcessEmitToolchain.Default;\n                    if (OsDetector.IsIOS())\n                        return InProcessNoEmitToolchain.Default;\n                    if (mono.AotArgs.IsNotBlank())\n                        return MonoAotToolchain.Instance;\n                    if (mono.IsDotNetBuiltIn)\n                        if (RuntimeInformation.IsNewMono)\n                        {\n                            // It's a .NET SDK with Mono as default VM.\n                            // Publishing self-contained apps might not work like in https://github.com/dotnet/performance/issues/2787.\n                            // In such case, we are going to use default .NET toolchain that is just going to perform dotnet build,\n                            // which internally will result in creating Mono-based app.\n                            return mono.RuntimeMoniker switch\n                            {\n                                RuntimeMoniker.Mono60 => GetToolchain(RuntimeMoniker.Net60),\n                                RuntimeMoniker.Mono70 => GetToolchain(RuntimeMoniker.Net70),\n                                RuntimeMoniker.Mono80 => GetToolchain(RuntimeMoniker.Net80),\n                                _ => CsProjCoreToolchain.From(new NetCoreAppSettings(mono.MsBuildMoniker, mono.Name))\n                            };\n                        }\n                        else\n                        {\n                            return MonoToolchain.From(\n                                new NetCoreAppSettings(targetFrameworkMoniker: mono.MsBuildMoniker, name: mono.Name));\n                        }\n\n                    return RoslynToolchain.Instance;\n\n                case CoreRuntime coreRuntime:\n                    if (descriptor != null && descriptor.Type.Assembly.IsLinqPad())\n                        return InProcessEmitToolchain.Default;\n                    if (coreRuntime.RuntimeMoniker != RuntimeMoniker.NotRecognized && !coreRuntime.IsPlatformSpecific)\n                        return GetToolchain(coreRuntime.RuntimeMoniker);\n\n                    return CsProjCoreToolchain.From(new NetCoreAppSettings(coreRuntime.MsBuildMoniker, coreRuntime.Name));\n\n                case NativeAotRuntime nativeAotRuntime:\n                    return nativeAotRuntime.RuntimeMoniker != RuntimeMoniker.NotRecognized\n                            ? GetToolchain(nativeAotRuntime.RuntimeMoniker)\n                            : NativeAotToolchain.CreateBuilder().UseNuGet().TargetFrameworkMoniker(nativeAotRuntime.MsBuildMoniker).ToToolchain();\n\n                case WasmRuntime wasmRuntime:\n                    return WasmToolchain.From(new NetCoreAppSettings(targetFrameworkMoniker: wasmRuntime.MsBuildMoniker, name: wasmRuntime.Name));\n\n                case R2RRuntime r2rRuntime:\n                    if (r2rRuntime.RuntimeMoniker != RuntimeMoniker.NotRecognized)\n                        return GetToolchain(r2rRuntime.RuntimeMoniker);\n\n                    return CsProjCoreToolchain.From(new NetCoreAppSettings(r2rRuntime.MsBuildMoniker, r2rRuntime.Name));\n\n                default:\n                    throw new ArgumentOutOfRangeException(nameof(runtime), runtime, \"Runtime not supported\");\n            }\n        }\n\n        private static IToolchain GetToolchain(RuntimeMoniker runtimeMoniker)\n        {\n            switch (runtimeMoniker)\n            {\n                case RuntimeMoniker.Net461:\n                    return CsProjClassicNetToolchain.Net461;\n\n                case RuntimeMoniker.Net462:\n                    return CsProjClassicNetToolchain.Net462;\n\n                case RuntimeMoniker.Net47:\n                    return CsProjClassicNetToolchain.Net47;\n\n                case RuntimeMoniker.Net471:\n                    return CsProjClassicNetToolchain.Net471;\n\n                case RuntimeMoniker.Net472:\n                    return CsProjClassicNetToolchain.Net472;\n\n                case RuntimeMoniker.Net48:\n                    return CsProjClassicNetToolchain.Net48;\n\n                case RuntimeMoniker.Net481:\n                    return CsProjClassicNetToolchain.Net481;\n\n                case RuntimeMoniker.NetCoreApp20:\n                    return CsProjCoreToolchain.NetCoreApp20;\n\n                case RuntimeMoniker.NetCoreApp21:\n                    return CsProjCoreToolchain.NetCoreApp21;\n\n                case RuntimeMoniker.NetCoreApp22:\n                    return CsProjCoreToolchain.NetCoreApp22;\n\n                case RuntimeMoniker.NetCoreApp30:\n                    return CsProjCoreToolchain.NetCoreApp30;\n\n                case RuntimeMoniker.NetCoreApp31:\n                    return CsProjCoreToolchain.NetCoreApp31;\n                case RuntimeMoniker.Net50:\n                    return CsProjCoreToolchain.NetCoreApp50;\n\n                case RuntimeMoniker.Net60:\n                    return CsProjCoreToolchain.NetCoreApp60;\n\n                case RuntimeMoniker.Net70:\n                    return CsProjCoreToolchain.NetCoreApp70;\n\n                case RuntimeMoniker.Net80:\n                    return CsProjCoreToolchain.NetCoreApp80;\n\n                case RuntimeMoniker.Net90:\n                    return CsProjCoreToolchain.NetCoreApp90;\n\n                case RuntimeMoniker.Net10_0:\n                    return CsProjCoreToolchain.NetCoreApp10_0;\n\n                case RuntimeMoniker.Net11_0:\n                    return CsProjCoreToolchain.NetCoreApp11_0;\n\n                case RuntimeMoniker.NativeAot60:\n                    return NativeAotToolchain.Net60;\n\n                case RuntimeMoniker.NativeAot70:\n                    return NativeAotToolchain.Net70;\n\n                case RuntimeMoniker.NativeAot80:\n                    return NativeAotToolchain.Net80;\n\n                case RuntimeMoniker.NativeAot90:\n                    return NativeAotToolchain.Net90;\n\n                case RuntimeMoniker.NativeAot10_0:\n                    return NativeAotToolchain.Net10_0;\n\n                case RuntimeMoniker.NativeAot11_0:\n                    return NativeAotToolchain.Net11_0;\n\n                case RuntimeMoniker.Mono60:\n                    return MonoToolchain.Mono60;\n\n                case RuntimeMoniker.Mono70:\n                    return MonoToolchain.Mono70;\n\n                case RuntimeMoniker.Mono80:\n                    return MonoToolchain.Mono80;\n\n                case RuntimeMoniker.R2R80:\n                    return R2RToolchain.R2R80;\n\n                case RuntimeMoniker.R2R90:\n                    return R2RToolchain.R2R90;\n\n                case RuntimeMoniker.R2R10_0:\n                    return R2RToolchain.R2R10_0;\n\n                case RuntimeMoniker.R2R11_0:\n                    return R2RToolchain.R2R11_0;\n\n                default:\n                    throw new ArgumentOutOfRangeException(nameof(runtimeMoniker), runtimeMoniker, \"RuntimeMoniker not supported\");\n            }\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Validators/BaselineValidator.cs",
    "content": "﻿using BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Order;\nusing System.Collections.Generic;\nusing System.Collections.Immutable;\nusing System.Linq;\n\nnamespace BenchmarkDotNet.Validators\n{\n    public class BaselineValidator : IValidator\n    {\n        public static readonly BaselineValidator FailOnError = new BaselineValidator();\n\n        private BaselineValidator() { }\n\n        public bool TreatsWarningsAsErrors => true; // it is a must!\n\n        public IEnumerable<ValidationError> Validate(ValidationParameters input)\n        {\n            var allBenchmarks = input.Benchmarks.ToImmutableArray();\n            var orderProvider = input.Config.Orderer ?? DefaultOrderer.Instance;\n\n            var benchmarkLogicalGroups = allBenchmarks\n                .Select(benchmark => orderProvider.GetLogicalGroupKey(allBenchmarks, benchmark))\n                .ToArray();\n\n            var logicalGroups = benchmarkLogicalGroups.Distinct().ToArray();\n            foreach (string? logicalGroup in logicalGroups)\n            {\n                var benchmarks = allBenchmarks.Where((benchmark, index) => benchmarkLogicalGroups[index] == logicalGroup).ToArray();\n                int methodBaselineCount = benchmarks.Select(b => b.Descriptor).Distinct().Count(it => it.Baseline);\n                int jobBaselineCount = benchmarks.Select(b => b.Job).Distinct(JobComparer.Default).Count(it => it.Meta.Baseline);\n                string className = benchmarks.First().Descriptor.Type.Name;\n\n                if (methodBaselineCount > 1)\n                    yield return CreateError(\"benchmark method\", \"Baseline = true\", logicalGroup, className, methodBaselineCount.ToString());\n\n                if (jobBaselineCount > 1)\n                    yield return CreateError(\"job\", \"Baseline = true\", logicalGroup, className, jobBaselineCount.ToString());\n            }\n        }\n\n        private ValidationError CreateError(string subject, string property, string? groupName, string className, string actual) =>\n            new ValidationError(\n                TreatsWarningsAsErrors,\n                $\"Only 1 {subject} in a group can have \\\"{property}\\\" applied to it, group {groupName} in class {className} has {actual}\");\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Validators/BenchmarkProcessValidator.cs",
    "content": "﻿using BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Jobs;\nusing JetBrains.Annotations;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Reflection;\n\nnamespace BenchmarkDotNet.Validators\n{\n    [UsedImplicitly]\n    public static class BenchmarkProcessValidator\n    {\n        public static IEnumerable<ValidationError> Validate(Job job, object benchmarkInstance)\n        {\n            foreach (var validationError in BenchmarkEnvironmentInfo.Validate(job))\n            {\n                yield return validationError;\n            }\n\n            var inlineableBenchmarks = benchmarkInstance.GetType().BaseType!\n                .GetMethods(BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public)\n                .Where(method => method.HasAttribute<BenchmarkAttribute>() && !method.MethodImplementationFlags.HasFlag(MethodImplAttributes.NoInlining));\n            foreach (var benchmark in inlineableBenchmarks)\n            {\n                yield return new ValidationError(\n                    true,\n                    $\"Benchmark method `{benchmark.Name}` does not have MethodImplOptions.NoInlining flag set.\" +\n                    $\" You may need to rebuild your project, or apply it manually if you are not using MSBuild to build your project.\"\n                );\n            }\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Validators/CompilationValidator.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Collections.Immutable;\nusing System.Linq;\nusing System.Reflection;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Toolchains;\nusing Microsoft.CodeAnalysis.CSharp;\nusing BenchmarkDotNet.Attributes;\n\nnamespace BenchmarkDotNet.Validators\n{\n    public class CompilationValidator : IValidator\n    {\n        private const char Underscore = '_';\n\n        public static readonly IValidator FailOnError = new CompilationValidator();\n\n        private static readonly ImmutableHashSet<string> CsharpKeywords = GetCsharpKeywords().ToImmutableHashSet();\n\n        private CompilationValidator() { }\n\n        public bool TreatsWarningsAsErrors => true;\n\n        public IEnumerable<ValidationError> Validate(ValidationParameters validationParameters)\n            => ValidateCSharpNaming(validationParameters.Benchmarks)\n                    .Union(ValidateClassModifiers((validationParameters.Benchmarks))\n                    .Union(ValidateAccessModifiers(validationParameters.Benchmarks))\n                    .Union(ValidateBindingModifiers(validationParameters.Benchmarks))\n                    .Union(ValidateMethodImpl(validationParameters.Benchmarks))\n                );\n\n        private static IEnumerable<ValidationError> ValidateClassModifiers(IEnumerable<BenchmarkCase> benchmarks)\n        {\n            return benchmarks\n                .Distinct(BenchmarkMethodEqualityComparer.Instance)\n                .SelectMany(benchmark =>\n                {\n                    var type = benchmark.Descriptor.Type;\n                    var errors = new List<ValidationError>();\n\n                    if (type.IsSealed)\n                    {\n                        errors.Add(new ValidationError(\n                           true,\n                           $\"Benchmarked method `{benchmark.Descriptor.WorkloadMethod.Name}` is within a sealed class, Declaring type must be unsealed.\",\n                           benchmark));\n                    }\n                    if (!type.IsVisible)\n                    {\n                        errors.Add(new ValidationError(\n                            true,\n                            $\"Benchmarked method `{benchmark.Descriptor.WorkloadMethod.Name}` is within a non-visible class, all declaring types must be public.\",\n                            benchmark));\n                    }\n                    // TODO: Generics validation\n                    return errors;\n                });\n        }\n\n        private static IEnumerable<ValidationError> ValidateCSharpNaming(IEnumerable<BenchmarkCase> benchmarks)\n            => benchmarks\n                .Where(benchmark => !IsValidCSharpIdentifier(benchmark.Descriptor.WorkloadMethod.Name))\n                .Distinct(BenchmarkMethodEqualityComparer.Instance) // we might have multiple jobs targeting same method. Single error should be enough ;)\n                .Select(benchmark\n                    => new ValidationError(\n                        true,\n                        $\"Benchmarked method `{benchmark.Descriptor.WorkloadMethod.Name}` contains illegal character(s) or uses C# keyword. Please use `[<Benchmark(Description = \\\"Custom name\\\")>]` to set custom display name.\",\n                        benchmark\n                    ));\n\n        private static IEnumerable<ValidationError> ValidateAccessModifiers(IEnumerable<BenchmarkCase> benchmarks)\n            => benchmarks.Where(x => x.Descriptor.Type.IsGenericType\n                                     && HasPrivateGenericArguments(x.Descriptor.Type))\n                         .Select(benchmark => new ValidationError(true, $\"Generic class {benchmark.Descriptor.Type.GetDisplayName()} has non public generic argument(s)\"));\n\n        private static IEnumerable<ValidationError> ValidateBindingModifiers(IEnumerable<BenchmarkCase> benchmarks)\n            => benchmarks.Where(x => x.Descriptor.WorkloadMethod.IsStatic && !x.GetToolchain().IsInProcess)\n                          .Distinct(BenchmarkMethodEqualityComparer.Instance)\n                          .Select(benchmark\n                              => new ValidationError(\n                                  true,\n                                  $\"Benchmarked method `{benchmark.Descriptor.WorkloadMethod.Name}` is static. Benchmarks MUST be instance methods, static methods are not supported.\",\n                                  benchmark\n                              ));\n\n        private static IEnumerable<ValidationError> ValidateMethodImpl(IEnumerable<BenchmarkCase> benchmarks)\n            => benchmarks.Where(x => !x.Descriptor.WorkloadMethod.MethodImplementationFlags.HasFlag(MethodImplAttributes.NoInlining))\n                .Distinct(BenchmarkMethodEqualityComparer.Instance)\n                .Select(benchmark\n                    => new ValidationError(\n                        true,\n                        $\"Benchmarked method `{benchmark.Descriptor.WorkloadMethod.Name}` does not have MethodImplOptions.NoInlining flag set.\" +\n                        $\" You may need to rebuild your project, or apply it manually if you are not using MSBuild to build your project.\",\n                        benchmark\n                    ));\n\n        private static bool IsValidCSharpIdentifier(string identifier) // F# allows to use whitespaces as names #479\n            => !string.IsNullOrEmpty(identifier)\n               && (char.IsLetter(identifier[0]) || identifier[0] == Underscore) // An identifier must start with a letter or an underscore\n               && identifier.Skip(1).All(character => char.IsLetterOrDigit(character) || character == Underscore)\n               && !CsharpKeywords.Contains(identifier);\n\n        private static bool HasPrivateGenericArguments(Type type) => type.GetGenericArguments().Any(a => !(a.IsPublic || a.IsNestedPublic));\n\n        // source: https://stackoverflow.com/a/19562316\n        private static IEnumerable<string> GetCsharpKeywords()\n        {\n            var memberInfos = typeof(SyntaxKind).GetMembers(BindingFlags.Public | BindingFlags.Static);\n\n            return from memberInfo in memberInfos\n                           where memberInfo.Name.EndsWith(\"Keyword\")\n                           orderby memberInfo.Name\n                           select memberInfo.Name.Substring(startIndex: 0, length: memberInfo.Name.IndexOf(\"Keyword\", StringComparison.Ordinal)).ToLower();\n        }\n\n        private class BenchmarkMethodEqualityComparer : IEqualityComparer<BenchmarkCase>\n        {\n            internal static readonly IEqualityComparer<BenchmarkCase> Instance = new BenchmarkMethodEqualityComparer();\n\n            public bool Equals(BenchmarkCase? x, BenchmarkCase? y)\n            {\n                if (x == null && y == null) return true;\n                if (x == null || y == null) return false;\n                if (x.Descriptor.WorkloadMethod.Equals(y.Descriptor.WorkloadMethod))\n                    return true;\n                return false;\n            }\n\n            public int GetHashCode(BenchmarkCase obj) => obj.Descriptor.WorkloadMethod.GetHashCode();\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Validators/CompositeValidator.cs",
    "content": "using System.Collections.Generic;\nusing System.Collections.Immutable;\nusing System.Linq;\n\nnamespace BenchmarkDotNet.Validators\n{\n    internal class CompositeValidator : IValidator\n    {\n        private readonly ImmutableHashSet<IValidator> validators;\n\n        public CompositeValidator(ImmutableHashSet<IValidator> validators) => this.validators = validators;\n\n        /// <summary>\n        /// returns true if any of the validators has TreatsWarningsAsErrors == true\n        /// </summary>\n        public bool TreatsWarningsAsErrors\n            => validators.Any(validator => validator.TreatsWarningsAsErrors);\n\n        public IEnumerable<ValidationError> Validate(ValidationParameters validationParameters)\n            => validators.SelectMany(validator => validator.Validate(validationParameters)).Distinct();\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Validators/ConfigValidator.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Security;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Loggers;\n\nnamespace BenchmarkDotNet.Validators\n{\n    public class ConfigValidator : IValidator\n    {\n        public static readonly IValidator DontFailOnError = new ConfigValidator();\n\n        private ConfigValidator() { }\n\n        public bool TreatsWarningsAsErrors => false;\n\n        public IEnumerable<ValidationError> Validate(ValidationParameters validationParameters)\n        {\n            if (validationParameters.Config.GetLoggers().IsEmpty())\n            {\n                const string errorMessage = \"No loggers defined, you will not see any progress!\";\n\n                ConsoleLogger.Default.WriteLineError(errorMessage); // no loggers defined, so we need to somehow display this information\n\n                yield return new ValidationError(false, errorMessage);\n            }\n\n            if (validationParameters.Config.GetExporters().IsEmpty())\n                yield return new ValidationError(false, \"No exporters defined, results will not be persisted.\");\n            if (validationParameters.Config.GetColumnProviders().IsEmpty())\n                yield return new ValidationError(false, \"No column providers defined, result table will be empty.\");\n\n            var pathValidation = ValidateArtifactsPath(validationParameters.Config.ArtifactsPath);\n\n            if (pathValidation != null)\n                yield return pathValidation;\n        }\n\n        private static ValidationError? ValidateArtifactsPath(string artifactsPath)\n        {\n            if (artifactsPath == null) // null is OK, default path will be used\n                return null;\n\n            if (string.IsNullOrWhiteSpace(artifactsPath))\n                return new ValidationError(true, $\"The ArtifactsPath is empty or whitespace. Use null to get the default value ({DefaultConfig.Instance.ArtifactsPath}).\");\n            if (artifactsPath.IndexOfAny(Path.GetInvalidPathChars()) != -1)\n                return new ValidationError(true, $\"The ArtifactsPath contains invalid path characters (one of {string.Join(\",\", Path.GetInvalidPathChars().Select(@char => $\"'{@char}'\"))}).\");\n\n            try\n            {\n                // ReSharper disable once ReturnValueOfPureMethodIsNotUsed\n                Path.GetFullPath(artifactsPath);\n            }\n            catch (PathTooLongException)\n            {\n                return new ValidationError(true, \"The ArtifactsPath is too long.\");\n            }\n            catch (SecurityException)\n            {\n                return new ValidationError(true, $\"You don't have the required permission to access ArtifactsPath ({artifactsPath}).\");\n            }\n\n            return null;\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Validators/DeferredExecutionValidator.cs",
    "content": "﻿using System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing BenchmarkDotNet.Extensions;\n\nnamespace BenchmarkDotNet.Validators\n{\n    public class DeferredExecutionValidator : IValidator\n    {\n        public static readonly IValidator DontFailOnError = new DeferredExecutionValidator(false);\n        public static readonly IValidator FailOnError = new DeferredExecutionValidator(true);\n\n        private DeferredExecutionValidator(bool failOnError) => TreatsWarningsAsErrors = failOnError;\n\n        public bool TreatsWarningsAsErrors { get; }\n\n        public IEnumerable<ValidationError> Validate(ValidationParameters validationParameters)\n            => validationParameters.Benchmarks\n                .Where(benchmark => IsDeferredExecution(benchmark.Descriptor.WorkloadMethod.ReturnType))\n                .Select(benchmark =>\n                    new ValidationError(\n                        TreatsWarningsAsErrors,\n                        $\"Benchmark {benchmark.Descriptor.Type.Name}.{benchmark.Descriptor.WorkloadMethod.Name} returns a deferred execution result ({benchmark.Descriptor.WorkloadMethod.ReturnType.GetCorrectCSharpTypeName(false, false)}). \" +\n                        \"You need to either change the method declaration to return a materialized result or consume it on your own. You can use .Consume() extension method to do that.\",\n                        benchmark));\n\n        private bool IsDeferredExecution(Type returnType)\n        {\n            if (returnType.IsByRef && !returnType.IsGenericType)\n                return IsDeferredExecution(returnType.GetElementType()!);\n\n            if (returnType.IsGenericType && (returnType.GetGenericTypeDefinition() == typeof(Task<>) || returnType.GetGenericTypeDefinition() == typeof(ValueTask<>)))\n                return IsDeferredExecution(returnType.GetGenericArguments().Single());\n\n            if (returnType == typeof(IEnumerable) || returnType == typeof(IQueryable))\n                return true;\n\n            if (!returnType.IsGenericType)\n                return false;\n\n            return returnType.GetGenericTypeDefinition() == typeof(IEnumerable<>)\n                || returnType.GetGenericTypeDefinition() == typeof(IQueryable<>)\n                || returnType.GetGenericTypeDefinition() == typeof(Lazy<>);\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Validators/DiagnosersValidator.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Linq;\n\nnamespace BenchmarkDotNet.Validators\n{\n    public class DiagnosersValidator : IValidator\n    {\n        public static readonly IValidator Composite = new DiagnosersValidator();\n\n        private DiagnosersValidator()\n        {\n        }\n\n        public bool TreatsWarningsAsErrors => true;\n\n        public IEnumerable<ValidationError> Validate(ValidationParameters validationParameters)\n            => validationParameters\n                .Config\n                .GetDiagnosers()\n                .SelectMany(diagnoser => diagnoser.Validate(validationParameters));\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Validators/DotNetSdkValidator.cs",
    "content": "﻿using BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Running;\nusing System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Diagnostics;\nusing System.Diagnostics.CodeAnalysis;\nusing System.IO;\nusing System.Linq;\nusing System.Runtime.InteropServices;\n\nnamespace BenchmarkDotNet.Validators\n{\n    internal static class DotNetSdkValidator\n    {\n        private static readonly Lazy<List<string>> cachedFrameworkSdks = new Lazy<List<string>>(GetInstalledFrameworkSdks, true);\n\n        public static IEnumerable<ValidationError> ValidateCoreSdks(string? customDotNetCliPath, BenchmarkCase benchmark)\n        {\n            if (IsCliPathInvalid(customDotNetCliPath, benchmark, out ValidationError? cliPathError))\n            {\n                yield return cliPathError;\n                yield break;\n            }\n            var requiredSdkVersion = benchmark.GetRuntime().RuntimeMoniker.GetRuntimeVersion();\n            if (!GetInstalledDotNetSdks(customDotNetCliPath).Any(sdk => sdk >= requiredSdkVersion))\n            {\n                yield return new ValidationError(true, $\"The required .NET Core SDK version {requiredSdkVersion} or higher for runtime moniker {benchmark.Job.Environment.Runtime!.RuntimeMoniker} is not installed.\", benchmark);\n            }\n        }\n\n        public static IEnumerable<ValidationError> ValidateFrameworkSdks(BenchmarkCase benchmark)\n        {\n            var targetRuntime = benchmark.Job.Environment.HasValue(EnvironmentMode.RuntimeCharacteristic)\n                ? benchmark.Job.Environment.Runtime!\n                : ClrRuntime.GetTargetOrCurrentVersion(benchmark.Descriptor.WorkloadMethod.DeclaringType!.Assembly);\n            var requiredSdkVersion = targetRuntime.RuntimeMoniker.GetRuntimeVersion();\n\n            var installedVersionString = cachedFrameworkSdks.Value.FirstOrDefault();\n            if (installedVersionString == null || Version.TryParse(installedVersionString, out var installedVersion) && installedVersion < requiredSdkVersion)\n            {\n                yield return new ValidationError(true, $\"The required .NET Framework SDK version {requiredSdkVersion} or higher is not installed.\", benchmark);\n            }\n        }\n\n        public static bool IsCliPathInvalid(string? customDotNetCliPath, BenchmarkCase benchmarkCase, [NotNullWhen(true)] out ValidationError? validationError)\n        {\n            validationError = null;\n\n            if (string.IsNullOrEmpty(customDotNetCliPath) && !HostEnvironmentInfo.GetCurrent().IsDotNetCliInstalled())\n            {\n                validationError = new ValidationError(true,\n                    $\"BenchmarkDotNet requires dotnet SDK to be installed or path to local dotnet cli provided in explicit way using `--cli` argument, benchmark '{benchmarkCase.DisplayInfo}' will not be executed\",\n                    benchmarkCase);\n\n                return true;\n            }\n\n            if (!string.IsNullOrEmpty(customDotNetCliPath) && !File.Exists(customDotNetCliPath))\n            {\n                validationError = new ValidationError(true,\n                    $\"Provided custom dotnet cli path does not exist, benchmark '{benchmarkCase.DisplayInfo}' will not be executed\",\n                    benchmarkCase);\n\n                return true;\n            }\n\n            return false;\n        }\n\n        private static IEnumerable<Version> GetInstalledDotNetSdks(string? customDotNetCliPath)\n        {\n            string dotnetExecutable = string.IsNullOrEmpty(customDotNetCliPath) ? \"dotnet\" : customDotNetCliPath!;\n            var startInfo = new ProcessStartInfo(dotnetExecutable, \"--list-sdks\")\n            {\n                RedirectStandardOutput = true,\n                UseShellExecute = false,\n                CreateNoWindow = true\n            };\n\n            try\n            {\n                using (var process = Process.Start(startInfo))\n                {\n                    if (process == null)\n                    {\n                        return [];\n                    }\n\n                    var output = process.StandardOutput.ReadToEnd();\n                    process.WaitForExit();\n\n                    if (process.ExitCode == 0)\n                    {\n                        var lines = output.Split(['\\r', '\\n'], StringSplitOptions.RemoveEmptyEntries);\n\n                        var versions = new List<Version>(lines.Count());\n                        foreach (var line in lines)\n                        {\n                            // Version.TryParse does not handle things like 3.0.0-WORD, so this will get just the 3.0.0 part\n                            var parsableVersionPart = CoreRuntime.GetParsableVersionPart(line);\n                            if (Version.TryParse(parsableVersionPart, out var version))\n                            {\n                                versions.Add(version);\n                            }\n                        }\n\n                        return versions;\n                    }\n                    else\n                    {\n                        return [];\n                    }\n                }\n            }\n            catch (Win32Exception) // dotnet CLI is not installed or not found in the path.\n            {\n                return [];\n            }\n        }\n\n        public static List<string> GetInstalledFrameworkSdks()\n        {\n            var versions = new List<string>();\n\n            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))\n            {\n                Get45PlusFromRegistry(versions);\n            }\n\n            return versions;\n        }\n\n        [System.Diagnostics.CodeAnalysis.SuppressMessage(\"Interoperability\", \"CA1416:Validate platform compatibility\", Justification = \"This code is protected with a runtime OS platform check\")]\n        private static void Get45PlusFromRegistry(List<string> versions)\n        {\n            const string subkey = @\"SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v4\\Full\\\";\n\n            using (var ndpKey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(subkey))\n            {\n                if (ndpKey == null)\n                {\n                    return;\n                }\n\n                if (ndpKey.GetValue(\"Version\") != null)\n                {\n                    versions.Add(ndpKey.GetValue(\"Version\")!.ToString()!);\n                }\n                else\n                {\n                    if (ndpKey.GetValue(\"Release\") != null)\n                    {\n                        versions.Add(CheckFor45PlusVersion((int)ndpKey.GetValue(\"Release\")!));\n                    }\n                }\n            }\n        }\n\n        private static string CheckFor45PlusVersion(int releaseKey)\n        {\n            if (releaseKey >= 533320)\n                return \"4.8.1\";\n            if (releaseKey >= 528040)\n                return \"4.8\";\n            if (releaseKey >= 461808)\n                return \"4.7.2\";\n            if (releaseKey >= 461308)\n                return \"4.7.1\";\n            if (releaseKey >= 460798)\n                return \"4.7\";\n            if (releaseKey >= 394802)\n                return \"4.6.2\";\n            if (releaseKey >= 394254)\n                return \"4.6.1\";\n            if (releaseKey >= 393295)\n                return \"4.6\";\n            if (releaseKey >= 379893)\n                return \"4.5.2\";\n            if (releaseKey >= 378675)\n                return \"4.5.1\";\n            if (releaseKey >= 378389)\n                return \"4.5\";\n\n            return \"\";\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Validators/ExecutionValidator.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing BenchmarkDotNet.Running;\n\nnamespace BenchmarkDotNet.Validators\n{\n    public class ExecutionValidator : ExecutionValidatorBase\n    {\n        public static readonly ExecutionValidator DontFailOnError = new ExecutionValidator(false);\n        public static readonly ExecutionValidator FailOnError = new ExecutionValidator(true);\n\n        private ExecutionValidator(bool failOnError)\n            : base(failOnError) { }\n\n        protected override void ExecuteBenchmarks(object benchmarkTypeInstance, IEnumerable<BenchmarkCase> benchmarks, List<ValidationError> errors)\n        {\n            foreach (var benchmark in benchmarks)\n            {\n                try\n                {\n                    benchmark.Descriptor.WorkloadMethod.Invoke(benchmarkTypeInstance, null);\n                }\n                catch (Exception ex)\n                {\n                    errors.Add(new ValidationError(\n                        TreatsWarningsAsErrors,\n                        $\"Failed to execute benchmark '{benchmark.DisplayInfo}', exception was: '{GetDisplayExceptionMessage(ex)}'\",\n                        benchmark));\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Validators/ExecutionValidatorBase.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Diagnostics.CodeAnalysis;\nusing System.Linq;\nusing System.Reflection;\nusing System.Threading.Tasks;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Helpers;\nusing BenchmarkDotNet.Running;\n\nnamespace BenchmarkDotNet.Validators\n{\n    public abstract class ExecutionValidatorBase : IValidator\n    {\n        protected ExecutionValidatorBase(bool failOnError)\n        {\n            TreatsWarningsAsErrors = failOnError;\n        }\n\n        public bool TreatsWarningsAsErrors { get; }\n\n        public IEnumerable<ValidationError> Validate(ValidationParameters validationParameters)\n        {\n            var errors = new List<ValidationError>();\n\n            foreach (var typeGroup in validationParameters.Benchmarks.GroupBy(benchmark => benchmark.Descriptor.Type))\n            {\n                if (!TryCreateBenchmarkTypeInstance(typeGroup.Key, errors, out var benchmarkTypeInstance))\n                {\n                    continue;\n                }\n\n                if (!TryToSetParamsFields(benchmarkTypeInstance, errors))\n                {\n                    continue;\n                }\n\n                if (!TryToSetParamsProperties(benchmarkTypeInstance, errors))\n                {\n                    continue;\n                }\n\n                if (!TryToCallGlobalSetup(benchmarkTypeInstance, errors))\n                {\n                    continue;\n                }\n\n                ExecuteBenchmarks(benchmarkTypeInstance, typeGroup, errors);\n\n                TryToCallGlobalCleanup(benchmarkTypeInstance, errors);\n            }\n\n            return errors;\n        }\n\n        private bool TryCreateBenchmarkTypeInstance(Type type, List<ValidationError> errors, [NotNullWhen(true)] out object? instance)\n        {\n            try\n            {\n                instance = Activator.CreateInstance(type)!;\n\n                return true;\n            }\n            catch (Exception ex)\n            {\n                errors.Add(new ValidationError(\n                    TreatsWarningsAsErrors,\n                    $\"Unable to create instance of {type.Name}, exception was: {GetDisplayExceptionMessage(ex)}\"));\n\n                instance = null;\n                return false;\n            }\n        }\n\n        private bool TryToCallGlobalSetup(object benchmarkTypeInstance, List<ValidationError> errors)\n        {\n            return TryToCallGlobalMethod<GlobalSetupAttribute>(benchmarkTypeInstance, errors);\n        }\n\n        private void TryToCallGlobalCleanup(object benchmarkTypeInstance, List<ValidationError> errors)\n        {\n            TryToCallGlobalMethod<GlobalCleanupAttribute>(benchmarkTypeInstance, errors);\n        }\n\n        private bool TryToCallGlobalMethod<T>(object benchmarkTypeInstance, List<ValidationError> errors)\n        {\n            var methods = benchmarkTypeInstance\n                .GetType()\n                .GetAllMethods()\n                .Where(methodInfo => methodInfo.GetCustomAttributes(false).OfType<T>().Any())\n                .ToArray();\n\n            if (!methods.Any())\n            {\n                return true;\n            }\n\n            if (methods.Count(methodInfo => !methodInfo.IsVirtual) > 1)\n            {\n                errors.Add(new ValidationError(\n                    TreatsWarningsAsErrors,\n                    $\"Only single [{GetAttributeName(typeof(T))}] method is allowed per type, type {benchmarkTypeInstance.GetType().Name} has few\"));\n\n                return false;\n            }\n\n            try\n            {\n                var result = methods.First().Invoke(benchmarkTypeInstance, null);\n\n                TryToGetTaskResult(result);\n            }\n            catch (Exception ex)\n            {\n                errors.Add(new ValidationError(\n                    TreatsWarningsAsErrors,\n                    $\"Failed to execute [{GetAttributeName(typeof(T))}] for {benchmarkTypeInstance.GetType().Name}, exception was {GetDisplayExceptionMessage(ex)}\"));\n\n                return false;\n            }\n\n            return true;\n        }\n\n        private string GetAttributeName(Type type) => type.Name.Replace(\"Attribute\", string.Empty);\n\n        private void TryToGetTaskResult(object? result)\n        {\n            if (result == null)\n            {\n                return;\n            }\n\n            AwaitHelper.GetGetResultMethod(result.GetType())\n                ?.Invoke(null, [result]);\n        }\n\n        private bool TryToSetParamsFields(object benchmarkTypeInstance, List<ValidationError> errors)\n        {\n            var paramFields = benchmarkTypeInstance\n                .GetType()\n                .GetAllFields()\n                .Where(fieldInfo => fieldInfo.GetCustomAttributes(false).OfType<ParamsAttribute>().Any())\n                .ToArray();\n\n            if (!paramFields.Any())\n            {\n                return true;\n            }\n\n            foreach (var paramField in paramFields)\n            {\n                if (!paramField.IsPublic)\n                {\n                    errors.Add(new ValidationError(\n                        TreatsWarningsAsErrors,\n                        $\"Fields marked with [Params] must be public, {paramField.Name} of {benchmarkTypeInstance.GetType().Name} is not\"));\n\n                    return false;\n                }\n\n                var values = paramField.GetCustomAttributes(false).OfType<ParamsAttribute>().Single().Values;\n                if (!values.Any())\n                {\n                    errors.Add(new ValidationError(\n                        TreatsWarningsAsErrors,\n                        $\"Fields marked with [Params] must have some values defined, {paramField.Name} of {benchmarkTypeInstance.GetType().Name} has none\"));\n\n                    return false;\n                }\n\n                try\n                {\n                    paramField.SetValue(benchmarkTypeInstance, values.First());\n                }\n                catch (Exception ex)\n                {\n                    errors.Add(new ValidationError(\n                        TreatsWarningsAsErrors,\n                        $\"Failed to set {paramField.Name} of {benchmarkTypeInstance.GetType().Name} to {values.First()}, exception was: {GetDisplayExceptionMessage(ex)}\"));\n\n                    return false;\n                }\n            }\n\n            return true;\n        }\n\n        private bool TryToSetParamsProperties(object benchmarkTypeInstance, List<ValidationError> errors)\n        {\n            var paramProperties = benchmarkTypeInstance\n                .GetType()\n                .GetAllProperties()\n                .Where(propertyInfo => propertyInfo.GetCustomAttributes(false).OfType<ParamsAttribute>().Any())\n                .ToArray();\n\n            if (!paramProperties.Any())\n            {\n                return true;\n            }\n\n            foreach (var paramProperty in paramProperties)\n            {\n                var setter = paramProperty.SetMethod;\n                if (setter == null || !setter.IsPublic)\n                {\n                    errors.Add(new ValidationError(\n                        TreatsWarningsAsErrors,\n                        $\"Properties marked with [Params] must have public setter, {paramProperty.Name} of {benchmarkTypeInstance.GetType().Name} has not\"));\n\n                    return false;\n                }\n\n                var values = paramProperty.GetCustomAttributes(false).OfType<ParamsAttribute>().Single().Values;\n                if (!values.Any())\n                {\n                    errors.Add(new ValidationError(\n                        TreatsWarningsAsErrors,\n                        $\"Properties marked with [Params] must have some values defined, {paramProperty.Name} of {benchmarkTypeInstance.GetType().Name} has not\"));\n\n                    return false;\n                }\n\n                try\n                {\n                    setter.Invoke(benchmarkTypeInstance, [values.First()]);\n                }\n                catch (Exception ex)\n                {\n                    errors.Add(new ValidationError(\n                        TreatsWarningsAsErrors,\n                        $\"Failed to set {paramProperty.Name} of {benchmarkTypeInstance.GetType().Name} to {values.First()}, exception was: {GetDisplayExceptionMessage(ex)}\"));\n\n                    return false;\n                }\n            }\n\n            return true;\n        }\n\n        protected static string GetDisplayExceptionMessage(Exception ex)\n        {\n            if (ex is TargetInvocationException targetInvocationException)\n                ex = targetInvocationException.InnerException!;\n\n            return ex?.Message ?? \"Unknown error\";\n        }\n\n        protected abstract void ExecuteBenchmarks(object benchmarkTypeInstance, IEnumerable<BenchmarkCase> benchmarks, List<ValidationError> errors);\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Validators/GenericBenchmarksValidator.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Linq;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Helpers;\n\nnamespace BenchmarkDotNet.Validators\n{\n    public class GenericBenchmarksValidator : IValidator\n    {\n        public static readonly IValidator DontFailOnError = new GenericBenchmarksValidator();\n\n        public bool TreatsWarningsAsErrors => false;\n\n        public IEnumerable<ValidationError> Validate(ValidationParameters validationParameters)\n            => validationParameters\n                .Benchmarks\n                .Select(benchmark => benchmark.Descriptor.Type.Assembly)\n                .Distinct()\n                .SelectMany(assembly => assembly.GetRunnableBenchmarks())\n                .SelectMany(GenericBenchmarksBuilder.BuildGenericsIfNeeded)\n                .Where(result => !result.isSuccess)\n                .Select(result => new ValidationError(false, $\"Generic type {result.result.Name} failed to build due to wrong type argument or arguments count, ignoring.\"));\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Validators/IValidator.cs",
    "content": "﻿using System.Collections.Generic;\n\nnamespace BenchmarkDotNet.Validators\n{\n    public interface IValidator\n    {\n        bool TreatsWarningsAsErrors { get; }\n\n        IEnumerable<ValidationError> Validate(ValidationParameters validationParameters);\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Validators/JitOptimizationsValidator.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Reflection;\nusing BenchmarkDotNet.Extensions;\n\nnamespace BenchmarkDotNet.Validators\n{\n    public class JitOptimizationsValidator : IValidator\n    {\n        public static readonly IValidator DontFailOnError = new JitOptimizationsValidator(false);\n        public static readonly IValidator FailOnError = new JitOptimizationsValidator(true);\n\n        private JitOptimizationsValidator(bool failOnErrors) => TreatsWarningsAsErrors = failOnErrors;\n\n        public bool TreatsWarningsAsErrors { get; }\n\n        public IEnumerable<ValidationError> Validate(ValidationParameters validationParameters)\n        {\n            foreach (var group in validationParameters.Benchmarks.GroupBy(benchmark => benchmark.Descriptor.Type.GetTypeInfo().Assembly))\n            {\n                // GetReferencedAssemblies() is not supported in NativeAOT currently.\n                AssemblyName[] referencedAssemblies;\n                try\n                {\n                    referencedAssemblies = group.Key.GetReferencedAssemblies();\n                }\n                catch (NotSupportedException)\n                {\n                    referencedAssemblies = [];\n                }\n                foreach (var referencedAssemblyName in referencedAssemblies)\n                {\n                    var referencedAssembly = Assembly.Load(referencedAssemblyName);\n\n                    // LINQPad.exe is non-optimized on purpose, see https://github.com/dotnet/BenchmarkDotNet/issues/580#issuecomment-345484889 for more details\n                    // we don't warn about non-optimized dependency to LINQPad\n                    // but we give extra hint if the dll with benchmark itself was build without optimization by LINQPad\n                    if (referencedAssembly.IsJitOptimizationDisabled().IsTrue() && !referencedAssembly.IsLinqPad())\n                    {\n                        yield return new ValidationError(\n                            TreatsWarningsAsErrors,\n                            $\"Assembly {group.Key.GetName().Name} which defines benchmarks references non-optimized {referencedAssemblyName.Name}\" +\n                            $\"{Environment.NewLine}\\tIf you own this dependency, please, build it in RELEASE.\" +\n                            $\"{Environment.NewLine}\\tIf you don't, you can disable this policy by using 'config.WithOptions(ConfigOptions.DisableOptimizationsValidator)'.\");\n                    }\n                }\n\n                if (group.Key.IsJitOptimizationDisabled().IsTrue())\n                {\n                    yield return new ValidationError(\n                        TreatsWarningsAsErrors,\n                        $\"Assembly {group.Key.GetName().Name} which defines benchmarks is non-optimized\" + Environment.NewLine +\n                        \"Benchmark was built without optimization enabled (most probably a DEBUG configuration). Please, build it in RELEASE.\" + Environment.NewLine +\n                        \"If you want to debug the benchmarks, please see https://benchmarkdotnet.org/articles/guides/troubleshooting.html#debugging-benchmarks.\"\n                        + (group.Key.IsLinqPad()\n                            ? Environment.NewLine + \"Please enable optimizations in your LINQPad. Go to Preferences -> Query and select \\\"compile with /optimize+\\\"\"\n                            : string.Empty));\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Validators/ParamsAllValuesValidator.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Diagnostics.CodeAnalysis;\nusing System.Linq;\nusing System.Reflection;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Extensions;\n\nnamespace BenchmarkDotNet.Validators\n{\n    public class ParamsAllValuesValidator : IValidator\n    {\n        public static readonly ParamsAllValuesValidator FailOnError = new ParamsAllValuesValidator();\n\n        public bool TreatsWarningsAsErrors => true;\n\n        private ParamsAllValuesValidator() { }\n\n        private const BindingFlags ReflectionFlags = BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;\n\n        public IEnumerable<ValidationError> Validate(ValidationParameters input) =>\n            input.Benchmarks\n                .Select(benchmark => benchmark.Descriptor.Type)\n                .Distinct()\n                .SelectMany(type => type.GetTypeMembersWithGivenAttribute<ParamsAllValuesAttribute>(ReflectionFlags))\n                .Distinct()\n                .Select(member => GetErrorOrDefault(member.ParameterType))\n                .WhereNotNull();\n\n        private bool IsBool(Type paramType) => paramType == typeof(bool);\n        private bool IsEnum(Type paramType) => paramType.GetTypeInfo().IsEnum;\n        private bool IsFlagsEnum(Type paramType)\n        {\n            var typeInfo = paramType.GetTypeInfo();\n            return typeInfo.IsEnum && typeInfo.IsDefined(typeof(FlagsAttribute));\n        }\n        private bool IsNullable(Type paramType, [NotNullWhen(true)] out Type? underlyingType)\n        {\n            underlyingType = Nullable.GetUnderlyingType(paramType);\n            return underlyingType != null;\n        }\n\n        private ValidationError? GetErrorOrDefault(Type parameterType)\n        {\n            switch (parameterType)\n            {\n                case Type t when IsNullable(t, out var underType):\n                    return GetErrorOrDefault(underType);\n\n                case Type t when IsFlagsEnum(t):\n                    return new ValidationError(\n                        TreatsWarningsAsErrors,\n                        $\"Unable to use {parameterType.Name} with [ParamsAllValues], because it's flags enum.\");\n\n                case Type t when IsBool(t) || IsEnum(t):\n                    return default;\n\n                default:\n                    return new ValidationError(\n                        TreatsWarningsAsErrors,\n                        $\"Type {parameterType.Name} cannot be used with [ParamsAllValues], allowed types are: bool, enum types and nullable type for another allowed type.\");\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Validators/ParamsValidator.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Reflection;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Extensions;\n\nnamespace BenchmarkDotNet.Validators\n{\n    public class ParamsValidator : IValidator\n    {\n        public static readonly ParamsValidator FailOnError = new();\n\n        public bool TreatsWarningsAsErrors => true;\n\n        public IEnumerable<ValidationError> Validate(ValidationParameters input) => input.Benchmarks\n            .Select(benchmark => benchmark.Descriptor.Type)\n            .Distinct()\n            .SelectMany(Validate);\n\n        private IEnumerable<ValidationError> Validate(Type type)\n        {\n            const BindingFlags reflectionFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance |\n                                                 BindingFlags.FlattenHierarchy;\n            foreach (var memberInfo in type.GetMembers(reflectionFlags))\n            {\n                var attributes = new Attribute?[]\n                    {\n                        memberInfo.ResolveAttribute<ParamsAttribute>(),\n                        memberInfo.ResolveAttribute<ParamsAllValuesAttribute>(),\n                        memberInfo.ResolveAttribute<ParamsSourceAttribute>()\n                    }\n                    .WhereNotNull()\n                    .ToList();\n                if (attributes.IsEmpty())\n                    continue;\n\n                string name = $\"{type.Name}.{memberInfo.Name}\";\n                string attributeString = string.Join(\", \", attributes.Select(attribute => $\"[{attribute.GetType().Name.Replace(nameof(Attribute), \"\")}]\"));\n\n                if (attributes.Count > 1)\n                    yield return new ValidationError(TreatsWarningsAsErrors,\n                        $\"Unable to use {name} with {attributeString} at the same time. Please, use a single attribute.\");\n\n                if (memberInfo is FieldInfo fieldInfo)\n                {\n                    if (fieldInfo.IsLiteral || fieldInfo.IsInitOnly)\n                    {\n                        string modifier = fieldInfo.IsInitOnly ? \"readonly\" : \"constant\";\n                        yield return new ValidationError(TreatsWarningsAsErrors,\n                            $\"Unable to use {name} with {attributeString} because it's a {modifier} field. Please, remove the {modifier} modifier.\");\n                    }\n\n                    if (!fieldInfo.IsPublic)\n                        yield return new ValidationError(TreatsWarningsAsErrors,\n                            $\"Unable to use {name} with {attributeString} because it's not public. Please, make it public.\");\n                }\n\n                if (memberInfo is PropertyInfo propertyInfo)\n                {\n                    if (propertyInfo.IsInitOnly())\n                        yield return new ValidationError(TreatsWarningsAsErrors,\n                            $\"Unable to use {name} with {attributeString} because it's init-only. Please, provide a public setter.\");\n\n                    if (propertyInfo.SetMethod == null)\n                        yield return new ValidationError(TreatsWarningsAsErrors,\n                            $\"Unable to use {name} with {attributeString} because it has no setter. Please, provide a public setter.\");\n\n                    if (propertyInfo.SetMethod != null && !propertyInfo.SetMethod.IsPublic)\n                        yield return new ValidationError(TreatsWarningsAsErrors,\n                            $\"Unable to use {name} with {attributeString} because its setter is not public. Please, make the setter public.\");\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Validators/ReturnValueValidator.cs",
    "content": "﻿using System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Diagnostics.CodeAnalysis;\nusing System.Linq;\nusing System.Reflection;\n\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Parameters;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Toolchains.InProcess.NoEmit;\n\nnamespace BenchmarkDotNet.Validators\n{\n    public class ReturnValueValidator : ExecutionValidatorBase\n    {\n        public static ReturnValueValidator DontFailOnError { get; } = new ReturnValueValidator(false);\n        public static ReturnValueValidator FailOnError { get; } = new ReturnValueValidator(true);\n\n        private ReturnValueValidator(bool failOnError)\n            : base(failOnError) { }\n\n        protected override void ExecuteBenchmarks(object benchmarkTypeInstance, IEnumerable<BenchmarkCase> benchmarks, List<ValidationError> errors)\n        {\n            foreach (var parameterGroup in benchmarks.GroupBy(i => i.Parameters, ParameterInstancesEqualityComparer.Instance))\n            {\n                var results = new List<(BenchmarkCase benchmark, object returnValue)>();\n                bool hasErrorsInGroup = false;\n\n                foreach (var benchmark in parameterGroup.DistinctBy(i => i.Descriptor.WorkloadMethod))\n                {\n                    try\n                    {\n                        InProcessNoEmitRunner.FillMembers(benchmarkTypeInstance, benchmark);\n                        var result = benchmark.Descriptor.WorkloadMethod.Invoke(benchmarkTypeInstance, null)!;\n\n                        if (benchmark.Descriptor.WorkloadMethod.ReturnType != typeof(void))\n                            results.Add((benchmark, result));\n                    }\n                    catch (Exception ex)\n                    {\n                        hasErrorsInGroup = true;\n\n                        errors.Add(new ValidationError(\n                            TreatsWarningsAsErrors,\n                            $\"Failed to execute benchmark '{benchmark.DisplayInfo}', exception was: '{GetDisplayExceptionMessage(ex)}'\",\n                            benchmark));\n                    }\n                }\n\n                if (hasErrorsInGroup || results.Count == 0)\n                    continue;\n\n                if (results.Any(result => !InDepthEqualityComparer.Instance.Equals(result.returnValue, results[0].returnValue)))\n                {\n                    errors.Add(new ValidationError(\n                        TreatsWarningsAsErrors,\n                        $\"Inconsistent benchmark return values in {results[0].benchmark.Descriptor.TypeInfo}: {string.Join(\", \", results.Select(r => $\"{r.benchmark.Descriptor.WorkloadMethodDisplayInfo}: {r.returnValue}\"))} {parameterGroup.Key.DisplayInfo}\"));\n                }\n            }\n        }\n\n        private class ParameterInstancesEqualityComparer : IEqualityComparer<ParameterInstances>\n        {\n            public static ParameterInstancesEqualityComparer Instance { get; } = new ParameterInstancesEqualityComparer();\n\n            public bool Equals(ParameterInstances? x, ParameterInstances? y)\n            {\n                if (ReferenceEquals(x, y))\n                    return true;\n\n                if (x == null || y == null)\n                    return false;\n\n                if (x.Count != y.Count)\n                    return false;\n\n                return x.Items.OrderBy(i => i.Name).Zip(y.Items.OrderBy(i => i.Name), (a, b) => a.Name == b.Name && Equals(a.Value, b.Value)).All(i => i);\n            }\n\n            public int GetHashCode(ParameterInstances obj)\n            {\n                if (obj.Count == 0)\n                    return 0;\n\n                var hashCode = new HashCode();\n                foreach (var instance in obj.Items.OrderBy(i => i.Name))\n                {\n                    hashCode.Add(instance.Name);\n                    hashCode.Add(instance.Value);\n                }\n                return hashCode.ToHashCode();\n            }\n        }\n\n        private class InDepthEqualityComparer : IEqualityComparer\n        {\n            public static InDepthEqualityComparer Instance { get; } = new InDepthEqualityComparer();\n\n            [SuppressMessage(\"ReSharper\", \"MemberHidesStaticFromOuterClass\")]\n            public new bool Equals(object? x, object? y)\n            {\n                if (ReferenceEquals(x, y) || object.Equals(x, y))\n                    return true;\n\n                if (x == null || y == null)\n                    return false;\n\n                return CompareEquatable(x, y) || CompareEquatable(y, x) || CompareStructural(x, y) || CompareStructural(y, x);\n            }\n\n            private static bool CompareEquatable(object x, object y)\n            {\n                var yType = y.GetType();\n\n                var equatableInterface = x.GetType().GetInterfaces().FirstOrDefault(i => i.IsGenericType\n                                                                                         && i.GetGenericTypeDefinition() == typeof(IEquatable<>)\n                                                                                         && i.GetGenericArguments().Single().IsAssignableFrom(yType));\n\n                if (equatableInterface == null)\n                    return false;\n\n                var method = equatableInterface.GetMethod(nameof(IEquatable<object>.Equals), BindingFlags.Public | BindingFlags.Instance);\n                return (bool?)method?.Invoke(x, [y]) ?? false;\n            }\n\n            private bool CompareStructural(object x, object y)\n            {\n                if (x is IStructuralEquatable xStructuralEquatable)\n                    return xStructuralEquatable.Equals(y, this);\n\n                var xArray = ToStructuralEquatable(x);\n                var yArray = ToStructuralEquatable(y);\n\n                if (xArray != null && yArray != null)\n                    return Equals(xArray, yArray);\n\n                return false;\n\n                Array? ToStructuralEquatable(object obj)\n                {\n                    switch (obj)\n                    {\n                        case Array array:\n                            return array;\n\n                        case IDictionary dict:\n                            return dict.Keys.Cast<object>().OrderBy(k => k).Select(k => (k, dict[k])).ToArray();\n\n                        case IEnumerable enumerable:\n                            return enumerable.Cast<object>().ToArray();\n\n                        default:\n                            return null;\n                    }\n                }\n            }\n\n            public int GetHashCode(object obj) => StructuralComparisons.StructuralEqualityComparer.GetHashCode(obj);\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Validators/RunModeValidator.cs",
    "content": "﻿using System.Collections.Generic;\nusing BenchmarkDotNet.Characteristics;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Running;\n\nnamespace BenchmarkDotNet.Validators\n{\n    public class RunModeValidator : IValidator\n    {\n        public static readonly IValidator FailOnError = new RunModeValidator();\n\n        private RunModeValidator() { }\n\n        public bool TreatsWarningsAsErrors => true;\n\n        public IEnumerable<ValidationError> Validate(ValidationParameters validationParameters)\n        {\n            var resolver = new CompositeResolver(EnvironmentResolver.Instance, EngineResolver.Instance); // TODO: use specified resolver.\n            foreach (var benchmark in validationParameters.Benchmarks)\n            {\n                var run = benchmark.Job.Run;\n                int unrollFactor = run.ResolveValue(RunMode.UnrollFactorCharacteristic, resolver);\n                if (unrollFactor <= 0)\n                {\n                    yield return new ValidationError(true, $\"Specified UnrollFactor ({unrollFactor}) must be greater than zero\", benchmark);\n                }\n                else if (run.HasValue(RunMode.InvocationCountCharacteristic))\n                {\n                    long invocationCount = run.InvocationCount;\n                    if (invocationCount % unrollFactor != 0)\n                    {\n                        string message = $\"Specified InvocationCount ({invocationCount}) must be a multiple of UnrollFactor ({unrollFactor})\";\n                        yield return new ValidationError(true, message, benchmark);\n                    }\n                }\n\n                foreach (var validationError in ValidateMinMax(run, resolver, benchmark, RunMode.MinIterationCountCharacteristic, RunMode.MaxIterationCountCharacteristic))\n                    yield return validationError;\n\n                foreach (var validationError in ValidateMinMax(run, resolver, benchmark, RunMode.MinWarmupIterationCountCharacteristic, RunMode.MaxWarmupIterationCountCharacteristic))\n                    yield return validationError;\n            }\n        }\n\n        private static IEnumerable<ValidationError> ValidateMinMax(RunMode run, CompositeResolver resolver, BenchmarkCase benchmark,\n            Characteristic<int> minCharacteristic, Characteristic<int> maxCharacteristic)\n        {\n            string GetName(Characteristic characteristic) => $\"{characteristic.DeclaringType.Name}.{characteristic.Id}\";\n\n            int minCount = run.ResolveValue(minCharacteristic, resolver);\n            int maxCount = run.ResolveValue(maxCharacteristic, resolver);\n\n            if (minCount <= 0)\n                yield return new ValidationError(true, $\"{GetName(minCharacteristic)} must be greater than zero (was {minCount})\", benchmark);\n\n            if (maxCount <= 0)\n                yield return new ValidationError(true, $\"{GetName(maxCharacteristic)} must be greater than zero (was {maxCount})\", benchmark);\n\n            if (minCount >= maxCount)\n                yield return new ValidationError(true, $\"{GetName(maxCharacteristic)} must be greater than {GetName(minCharacteristic)} (was {maxCount} and {minCount})\", benchmark);\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Validators/RuntimeValidator.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Linq;\nusing BenchmarkDotNet.Characteristics;\nusing BenchmarkDotNet.Toolchains;\n\nnamespace BenchmarkDotNet.Validators;\n\n/// <summary>\n/// Validator for runtime characteristic.\n/// <see href=\"https://github.com/dotnet/BenchmarkDotNet/issues/2609\" />\n/// </summary>\npublic class RuntimeValidator : IValidator\n{\n    public static readonly IValidator DontFailOnError = new RuntimeValidator();\n\n    private RuntimeValidator() { }\n\n    public bool TreatsWarningsAsErrors => false;\n\n    public IEnumerable<ValidationError> Validate(ValidationParameters input)\n    {\n        var allBenchmarks = input.Benchmarks.ToArray();\n        var nullRuntimeBenchmarks = allBenchmarks.Where(x => x.Job.Environment.Runtime == null).ToArray();\n\n        // There is no validation error if all the runtimes are set or if all the runtimes are null.\n        if (allBenchmarks.Length == nullRuntimeBenchmarks.Length)\n        {\n            return [];\n        }\n\n        var errors = new List<ValidationError>();\n        foreach (var benchmark in nullRuntimeBenchmarks.Where(x=> !x.GetToolchain().IsInProcess))\n        {\n            var job = benchmark.Job;\n            var jobText = job.HasValue(CharacteristicObject.IdCharacteristic)\n                ? job.Id\n                : CharacteristicSetPresenter.Display.ToPresentation(job); // Use job text representation instead for auto generated JobId.\n\n            var message = $\"Job({jobText}) doesn't have a Runtime characteristic. It's recommended to specify runtime by using WithRuntime explicitly.\";\n            errors.Add(new ValidationError(false, message));\n        }\n        return errors;\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Validators/SetupCleanupValidator.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Linq;\nusing System.Reflection;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Extensions;\n\nnamespace BenchmarkDotNet.Validators\n{\n    public class SetupCleanupValidator : IValidator\n    {\n        public static readonly SetupCleanupValidator FailOnError = new SetupCleanupValidator();\n\n        private SetupCleanupValidator() { }\n\n        public bool TreatsWarningsAsErrors => true; // it is a must!\n\n        public IEnumerable<ValidationError> Validate(ValidationParameters input)\n        {\n            var validationErrors = new List<ValidationError>();\n\n            foreach (var groupByType in input.Benchmarks.GroupBy(benchmark => benchmark.Descriptor.Type))\n            {\n                var allMethods = groupByType.Key.GetAllMethods().ToArray();\n\n                validationErrors.AddRange(ValidateAttributes<GlobalSetupAttribute>(groupByType.Key.Name, allMethods));\n                validationErrors.AddRange(ValidateAttributes<GlobalCleanupAttribute>(groupByType.Key.Name, allMethods));\n                validationErrors.AddRange(ValidateAttributes<IterationSetupAttribute>(groupByType.Key.Name, allMethods));\n                validationErrors.AddRange(ValidateAttributes<IterationSetupAttribute>(groupByType.Key.Name, allMethods));\n            }\n\n            return validationErrors;\n        }\n\n        private IEnumerable<ValidationError> ValidateAttributes<T>(string benchmarkClassName, IEnumerable<MethodInfo> allMethods) where T : TargetedAttribute\n        {\n            int emptyTargetCount = 0;\n            var targetCount = new Dictionary<string, int>();\n\n            foreach (var method in allMethods)\n            {\n                var attributes = method.GetCustomAttributes(false).OfType<T>();\n\n                foreach (var attribute in attributes)\n                {\n                    if (attribute.Targets.IsNullOrEmpty())\n                    {\n                        emptyTargetCount++;\n                    }\n                    else\n                    {\n                        foreach (string target in attribute.Targets)\n                        {\n                            if (!targetCount.ContainsKey(target))\n                            {\n                                targetCount[target] = 1;\n                            }\n                            else\n                            {\n                                targetCount[target] += 1;\n                            }\n                        }\n                    }\n                }\n            }\n\n            if (emptyTargetCount > 1)\n            {\n                yield return new ValidationError(\n                    TreatsWarningsAsErrors,\n                    $\"Only 1 [{typeof(T).Name}] in a class can have an empty target applied to it, class {benchmarkClassName} has {emptyTargetCount}\");\n            }\n\n            foreach (var targetPair in targetCount)\n            {\n                if (targetPair.Value > 1)\n                {\n                    yield return new ValidationError(\n                        TreatsWarningsAsErrors,\n                        $\"Only 1 [{typeof(T).Name}] in a class can \\\"Target = {targetPair.Key}\\\" applied to it, class {benchmarkClassName} has {targetPair.Value}\");\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet/Validators/ShadowCopyValidator.cs",
    "content": "using System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Reflection;\n\nnamespace BenchmarkDotNet.Validators\n{\n    public class ShadowCopyValidator : IValidator\n    {\n        public static readonly IValidator DontFailOnError = new ShadowCopyValidator();\n\n        private ShadowCopyValidator() { }\n\n        public bool TreatsWarningsAsErrors => false;\n\n        public IEnumerable<ValidationError> Validate(ValidationParameters validationParameters)\n            => validationParameters\n                .Benchmarks\n                .Select(benchmark => benchmark.Descriptor.Type.GetTypeInfo().Assembly)\n                .Distinct()\n                .Where(assembly => assembly.Location.StartsWith(Path.GetTempPath()))\n                .Select(\n                    assembly => new ValidationError(\n                        false,\n                        $\"Assembly {assembly} is located in temp. If you are running benchmarks from xUnit you need to disable shadow copy. It's not supported by design.\"));\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Validators/ValidationError.cs",
    "content": "﻿using System;\nusing BenchmarkDotNet.Running;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Validators\n{\n    public class ValidationError : IEquatable<ValidationError>\n    {\n        public ValidationError(bool isCritical, string message, BenchmarkCase? benchmarkCase = null)\n        {\n            IsCritical = isCritical;\n            Message = message;\n            BenchmarkCase = benchmarkCase;\n        }\n\n        [PublicAPI] public bool IsCritical { get; }\n        [PublicAPI] public string Message { get; }\n        [PublicAPI] public BenchmarkCase? BenchmarkCase { get; }\n\n        public override string ToString() => Message;\n\n        public bool Equals(ValidationError? other)\n        {\n            if (ReferenceEquals(null, other))\n                return false;\n            if (ReferenceEquals(this, other))\n                return true;\n            return IsCritical == other.IsCritical && string.Equals(Message, other.Message) && Equals(BenchmarkCase, other.BenchmarkCase);\n        }\n\n        public override bool Equals(object? obj)\n        {\n            if (ReferenceEquals(null, obj))\n                return false;\n            if (ReferenceEquals(this, obj))\n                return true;\n            if (obj.GetType() != GetType())\n                return false;\n            return Equals((ValidationError)obj);\n        }\n\n        public override int GetHashCode() => HashCode.Combine(IsCritical, Message, BenchmarkCase);\n\n        public static bool operator ==(ValidationError left, ValidationError right) => Equals(left, right);\n\n        public static bool operator !=(ValidationError? left, ValidationError? right) => !Equals(left, right);\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Validators/ValidationErrorReporter.cs",
    "content": "﻿using System.Collections.Generic;\nusing BenchmarkDotNet.Engines;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Validators\n{\n    public static class ValidationErrorReporter\n    {\n        public const string ConsoleErrorPrefix = \"// ERROR: \";\n\n        [UsedImplicitly] // Generated benchmarks\n        public static bool ReportIfAny(IEnumerable<ValidationError> validationErrors, IHost host)\n        {\n            bool hasErrors = false;\n            foreach (var validationError in validationErrors)\n            {\n                host.SendError(validationError.Message);\n                hasErrors = true;\n            }\n            return hasErrors;\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet/Validators/ValidationParameters.cs",
    "content": "﻿using System.Collections.Generic;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Running;\n\nnamespace BenchmarkDotNet.Validators\n{\n    public class ValidationParameters\n    {\n        public IReadOnlyList<BenchmarkCase> Benchmarks { get; }\n\n        public ImmutableConfig Config { get; }\n\n        public ValidationParameters(IReadOnlyList<BenchmarkCase> benchmarks, ImmutableConfig config)\n        {\n            Benchmarks = benchmarks;\n            Config = config;\n        }\n\n        // Note: Following implicit operators are expected to be used for test projects.\n        public static implicit operator ValidationParameters(BenchmarkCase[] benchmarksCase) => new ValidationParameters(benchmarksCase, DefaultConfig.Instance.CreateImmutableConfig());\n        public static implicit operator ValidationParameters(BenchmarkRunInfo benchmarkRunInfo) => new ValidationParameters(benchmarkRunInfo.BenchmarksCases, benchmarkRunInfo.Config);\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet.Analyzers/AnalyzerHelper.cs",
    "content": "﻿using Microsoft.CodeAnalysis;\r\nusing Microsoft.CodeAnalysis.CSharp;\r\nusing Microsoft.CodeAnalysis.CSharp.Syntax;\r\nusing System.Collections.Generic;\r\nusing System.Collections.Immutable;\r\nusing System.Diagnostics;\r\nusing System.Globalization;\r\nusing System.Linq;\r\n\r\nnamespace BenchmarkDotNet.Analyzers;\r\n\r\ninternal static class AnalyzerHelper\r\n{\r\n    internal const string InterceptorsNamespaces = \"InterceptorsNamespaces\";\r\n\r\n    public static LocalizableResourceString GetResourceString(string name)\r\n        => new(name, BenchmarkDotNetAnalyzerResources.ResourceManager, typeof(BenchmarkDotNetAnalyzerResources));\r\n\r\n    public static INamedTypeSymbol? GetBenchmarkAttributeTypeSymbol(Compilation compilation)\r\n        => compilation.GetTypeByMetadataName(\"BenchmarkDotNet.Attributes.BenchmarkAttribute\");\r\n\r\n    public static bool AttributeListsContainAttribute(INamedTypeSymbol? attributeTypeSymbol, SyntaxList<AttributeListSyntax> attributeLists, SemanticModel semanticModel)\r\n    {\r\n        if (attributeTypeSymbol == null || attributeTypeSymbol.TypeKind == TypeKind.Error)\r\n        {\r\n            return false;\r\n        }\r\n\r\n        foreach (var attributeListSyntax in attributeLists)\r\n        {\r\n            foreach (var attributeSyntax in attributeListSyntax.Attributes)\r\n            {\r\n                var attributeSyntaxTypeSymbol = semanticModel.GetTypeInfo(attributeSyntax).Type;\r\n                if (attributeSyntaxTypeSymbol == null)\r\n                {\r\n                    continue;\r\n                }\r\n\r\n                if (SymbolEqualityComparer.Default.Equals(attributeSyntaxTypeSymbol, attributeTypeSymbol))\r\n                {\r\n                    return true;\r\n                }\r\n            }\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    public static bool AttributeListContainsAttribute(string attributeName, Compilation compilation, ImmutableArray<AttributeData> attributeList)\r\n        => AttributeListContainsAttribute(compilation.GetTypeByMetadataName(attributeName), attributeList);\r\n\r\n    public static bool AttributeListContainsAttribute(INamedTypeSymbol? attributeTypeSymbol, ImmutableArray<AttributeData> attributeList)\r\n    {\r\n        if (attributeTypeSymbol == null || attributeTypeSymbol.TypeKind == TypeKind.Error)\r\n        {\r\n            return false;\r\n        }\r\n\r\n        return attributeList.Any(ad => SymbolEqualityComparer.Default.Equals(ad.AttributeClass, attributeTypeSymbol));\r\n    }\r\n\r\n    public static ImmutableArray<AttributeSyntax> GetAttributes(string attributeName, Compilation compilation, SyntaxList<AttributeListSyntax> attributeLists, SemanticModel semanticModel)\r\n        => GetAttributes(compilation.GetTypeByMetadataName(attributeName), attributeLists, semanticModel);\r\n\r\n    public static ImmutableArray<AttributeSyntax> GetAttributes(INamedTypeSymbol? attributeTypeSymbol, SyntaxList<AttributeListSyntax> attributeLists, SemanticModel semanticModel)\r\n    {\r\n        var attributesBuilder = ImmutableArray.CreateBuilder<AttributeSyntax>();\r\n\r\n        if (attributeTypeSymbol == null)\r\n        {\r\n            return attributesBuilder.ToImmutable();\r\n        }\r\n\r\n        foreach (var attributeListSyntax in attributeLists)\r\n        {\r\n            foreach (var attributeSyntax in attributeListSyntax.Attributes)\r\n            {\r\n                var attributeSyntaxTypeSymbol = semanticModel.GetTypeInfo(attributeSyntax).Type;\r\n                if (attributeSyntaxTypeSymbol == null)\r\n                {\r\n                    continue;\r\n                }\r\n\r\n                if (SymbolEqualityComparer.Default.Equals(attributeSyntaxTypeSymbol, attributeTypeSymbol))\r\n                {\r\n                    attributesBuilder.Add(attributeSyntax);\r\n                }\r\n            }\r\n        }\r\n\r\n        return attributesBuilder.ToImmutable();\r\n    }\r\n\r\n    public static string NormalizeTypeName(INamedTypeSymbol namedTypeSymbol)\r\n    {\r\n        string typeName;\r\n\r\n        if (namedTypeSymbol.SpecialType != SpecialType.None)\r\n        {\r\n            typeName = namedTypeSymbol.ToString();\r\n        }\r\n        else if (namedTypeSymbol.IsUnboundGenericType)\r\n        {\r\n            typeName = $\"{namedTypeSymbol.Name}<{new string(',', namedTypeSymbol.TypeArguments.Length - 1)}>\";\r\n        }\r\n        else\r\n        {\r\n            typeName = namedTypeSymbol.Name;\r\n        }\r\n\r\n        return typeName;\r\n    }\r\n\r\n    public static void Deconstruct<T1, T2>(this KeyValuePair<T1, T2> tuple, out T1 key, out T2 value)\r\n    {\r\n        key = tuple.Key;\r\n        value = tuple.Value;\r\n    }\r\n\r\n    public static Location GetLocation(this AttributeData attributeData)\r\n        => attributeData.ApplicationSyntaxReference?.SyntaxTree.GetLocation(attributeData.ApplicationSyntaxReference.Span)\r\n            ?? Location.None;\r\n\r\n    public static bool IsAssignable(TypedConstant constant, ExpressionSyntax expression, ITypeSymbol targetType, Compilation compilation)\r\n    {\r\n        if (constant.IsNull)\r\n        {\r\n            // Check if targetType is a reference type or nullable.\r\n            return targetType.IsReferenceType || targetType.OriginalDefinition.SpecialType == SpecialType.System_Nullable_T;\r\n        }\r\n\r\n        var sourceType = constant.Type;\r\n        if (sourceType == null)\r\n        {\r\n            return false;\r\n        }\r\n\r\n        // Test if the constant type is implicitly assignable.\r\n        var conversion = compilation.ClassifyConversion(sourceType, targetType);\r\n        if (conversion.IsImplicit)\r\n        {\r\n            return true;\r\n        }\r\n\r\n        // Int32 values fail the test to smaller types, but it's still valid in the generated code to assign the literal to a smaller integer type,\r\n        // so test if the expression is implicitly assignable.\r\n        var semanticModel = compilation.GetSemanticModel(expression.SyntaxTree);\r\n        // Only enums use explicit casting, so we test with explicit cast only for enums. See BenchmarkConverter.Map(...).\r\n        bool isEnum = targetType.TypeKind == TypeKind.Enum;\r\n        // The existing implementation only checks for direct enum type, not Nullable<TEnum>, so we won't check it here either unless BenchmarkConverter gets updated to handle it.\r\n        //bool isNullableEnum =\r\n        //    targetType.OriginalDefinition.SpecialType == SpecialType.System_Nullable_T &&\r\n        //    targetType is INamedTypeSymbol named &&\r\n        //    named.TypeArguments.Length == 1 &&\r\n        //    named.TypeArguments[0].TypeKind == TypeKind.Enum;\r\n        conversion = semanticModel.ClassifyConversion(expression, targetType, isEnum);\r\n        if (conversion.IsImplicit)\r\n        {\r\n            return true;\r\n        }\r\n        return isEnum && conversion.IsExplicit;\r\n    }\r\n\r\n    // Assumes a single `params object[] values` constructor\r\n    public static ExpressionSyntax GetAttributeParamsArgumentExpression(this AttributeData attributeData, int index)\r\n    {\r\n        Debug.Assert(index >= 0);\r\n        // Properties must come after constructor arguments, so we don't need to worry about it here.\r\n        var attrSyntax = (AttributeSyntax)attributeData.ApplicationSyntaxReference!.GetSyntax();\r\n        var args = attrSyntax.ArgumentList!.Arguments;\r\n        Debug.Assert(args is { Count: > 0 });\r\n        var maybeArrayExpression = args[0].Expression;\r\n\r\n#if CODE_ANALYSIS_4_8\r\n        if (maybeArrayExpression is CollectionExpressionSyntax collectionExpressionSyntax)\r\n        {\r\n            Debug.Assert(index < collectionExpressionSyntax.Elements.Count);\r\n            return ((ExpressionElementSyntax)collectionExpressionSyntax.Elements[index]).Expression;\r\n        }\r\n#endif\r\n\r\n        if (maybeArrayExpression is ArrayCreationExpressionSyntax arrayCreationExpressionSyntax)\r\n        {\r\n            if (arrayCreationExpressionSyntax.Initializer == null)\r\n            {\r\n                return maybeArrayExpression;\r\n            }\r\n            Debug.Assert(index < arrayCreationExpressionSyntax.Initializer.Expressions.Count);\r\n            return arrayCreationExpressionSyntax.Initializer.Expressions[index];\r\n        }\r\n\r\n        // Params values\r\n        Debug.Assert(index < args.Count);\r\n        Debug.Assert(args[index].NameEquals is null);\r\n        return args[index].Expression;\r\n    }\r\n}"
  },
  {
    "path": "src/BenchmarkDotNet.Analyzers/AnalyzerReleases.Shipped.md",
    "content": "## v0.15.8\n\n### New Rules\n\nRule ID  | Category | Severity | Notes\n---------|----------|----------|--------------------\nBDN1503  |  Usage   | Error\t   | [Arguments] method has no parameters\n\n\n## v0.15.7\n\n### New Rules\n\nRule ID  | Category | Severity | Notes\n---------|----------|----------|--------------------\nBDN1000  |  Usage   | Error\t   | BenchmarkRunner.Run() type is missing benchmark methods\nBDN1001  |  Usage   | Error\t   | BenchmarkRunner.Run() type is not public\nBDN1002  |  Usage   | Error\t   | BenchmarkRunner.Run() type is sealed\nBDN1003  |  Usage   | Error\t   | BenchmarkRunner.Run() type is abstract\nBDN1004  |  Usage   | Error\t   | BenchmarkRunner.Run() generic type is not annotated\nBDN1100  |  Usage   | Error\t   | Annotated generic benchmark class is abstract\nBDN1101  |  Usage   | Error\t   | Annotated benchmark class is not generic\nBDN1102  |  Usage   | Error\t   | Annotated generic benchmark class does not match type parameter count\nBDN1103  |  Usage   | Error\t   | Benchmark method is not public\nBDN1104  |  Usage   | Error\t   | Benchmark method is generic\nBDN1105  |  Usage   | Error\t   | Benchmark class is static\nBDN1106  |  Usage   | Error\t   | Single null argument passed to category\nBDN1107  |  Usage   | Error\t   | Multiple baseline benchmark methods\nBDN1108  |  Usage   | Warning  | Multiple baseline benchmark methods per category\nBDN1200  |  Usage   | Error\t   | More than one [Params(Source\\|AllValues)] on a field\nBDN1201  |  Usage   | Error\t   | More than one [Params(Source\\|AllValues)] on a property\nBDN1202  |  Usage   | Error\t   | [Params(Source\\|AllValues)] field is not public\nBDN1203  |  Usage   | Error\t   | [Params(Source\\|AllValues)] property is not public\nBDN1204  |  Usage   | Error\t   | [Params(Source\\|AllValues)] field is readonly\nBDN1205  |  Usage   | Error\t   | [Params(Source\\|AllValues)] field is constant\nBDN1206  |  Usage   | Error\t   | [Params(Source\\|AllValues)] property is init only\nBDN1207  |  Usage   | Error\t   | [Params(Source\\|AllValues)] has no public setter\nBDN1300  |  Usage   | Error\t   | [Params] has no values\nBDN1301  |  Usage   | Error\t   | [Params] values do not match the type of the field or property\nBDN1302  |  Usage   | Info\t   | [Params] used with a single value\nBDN1303  |  Usage   | Error\t   | [ParamsAllValues] used with a [Flags] enum\nBDN1304  |  Usage   | Error\t   | [ParamsAllValues] used with a type that is not enum or bool\nBDN1400  |  Usage   | Error\t   | Benchmark method with parameters not annotated with [Arguments(Source)]\nBDN1500  |  Usage   | Error\t   | [Arguments(Source)] method is not a benchmark method\nBDN1501  |  Usage   | Error\t   | [Arguments] value(s) count does not match method parameter(s) count\nBDN1502  |  Usage   | Error\t   | [Arguments] value(s) do not match the type(s) of the method parameters"
  },
  {
    "path": "src/BenchmarkDotNet.Analyzers/AnalyzerReleases.Unshipped.md",
    "content": "### New Rules\n\nRule ID  | Category | Severity | Notes\n---------|----------|----------|--------------------\nBDN1305  |  Usage   | Error\t   | [ParamsSource] cannot reference write-only property\n\n\n### Removed Rules\n\nRule ID  | Category | Severity | Notes\n---------|----------|----------|--------------------\nBDN1100  |  Usage   | Error    | Rule removed as GenericTypeArguments now supports abstract classes"
  },
  {
    "path": "src/BenchmarkDotNet.Analyzers/Attributes/ArgumentsAttributeAnalyzer.cs",
    "content": "﻿using Microsoft.CodeAnalysis;\r\nusing Microsoft.CodeAnalysis.CSharp;\r\nusing Microsoft.CodeAnalysis.CSharp.Syntax;\r\nusing Microsoft.CodeAnalysis.Diagnostics;\r\nusing Microsoft.CodeAnalysis.Text;\r\nusing System;\r\nusing System.Collections.Generic;\r\nusing System.Collections.Immutable;\r\nusing System.Linq;\r\n\r\nnamespace BenchmarkDotNet.Analyzers.Attributes;\r\n\r\n[DiagnosticAnalyzer(LanguageNames.CSharp)]\r\npublic class ArgumentsAttributeAnalyzer : DiagnosticAnalyzer\r\n{\r\n    internal static readonly DiagnosticDescriptor RequiresBenchmarkAttributeRule = new(\r\n        DiagnosticIds.Attributes_ArgumentsAttribute_RequiresBenchmarkAttribute,\r\n        AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.Attributes_ArgumentsAttribute_RequiresBenchmarkAttribute_Title)),\r\n        AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.Attributes_ArgumentsAttribute_RequiresBenchmarkAttribute_MessageFormat)),\r\n        \"Usage\",\r\n        DiagnosticSeverity.Error,\r\n        isEnabledByDefault: true);\r\n\r\n    internal static readonly DiagnosticDescriptor MustHaveMatchingValueCountRule = new(\r\n        DiagnosticIds.Attributes_ArgumentsAttribute_MustHaveMatchingValueCount,\r\n        AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.Attributes_ArgumentsAttribute_MustHaveMatchingValueCount_Title)),\r\n        AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.Attributes_ArgumentsAttribute_MustHaveMatchingValueCount_MessageFormat)),\r\n        \"Usage\",\r\n        DiagnosticSeverity.Error,\r\n        isEnabledByDefault: true,\r\n        description: AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.Attributes_ArgumentsAttribute_MustHaveMatchingValueCount_Description)));\r\n\r\n    internal static readonly DiagnosticDescriptor MustHaveMatchingValueTypeRule = new(\r\n        DiagnosticIds.Attributes_ArgumentsAttribute_MustHaveMatchingValueType,\r\n        AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.Attributes_ArgumentsAttribute_MustHaveMatchingValueType_Title)),\r\n        AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.Attributes_ArgumentsAttribute_MustHaveMatchingValueType_MessageFormat)),\r\n        \"Usage\",\r\n        DiagnosticSeverity.Error,\r\n        isEnabledByDefault: true,\r\n        description: AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.Attributes_ArgumentsAttribute_MustHaveMatchingValueType_Description)));\r\n\r\n    internal static readonly DiagnosticDescriptor RequiresParametersRule = new(\r\n        DiagnosticIds.Attributes_ArgumentsAttribute_RequiresParameters,\r\n        AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.Attributes_ArgumentsAttribute_RequiresParameters_Title)),\r\n        AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.Attributes_ArgumentsAttribute_RequiresParameters_MessageFormat)),\r\n        \"Usage\",\r\n        DiagnosticSeverity.Error,\r\n        isEnabledByDefault: true,\r\n        description: AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.Attributes_ArgumentsAttribute_RequiresParameters_Description)));\r\n\r\n    public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => new DiagnosticDescriptor[]\r\n    {\r\n        RequiresBenchmarkAttributeRule,\r\n        MustHaveMatchingValueCountRule,\r\n        MustHaveMatchingValueTypeRule,\r\n        RequiresParametersRule,\r\n    }.ToImmutableArray();\r\n\r\n    public override void Initialize(AnalysisContext analysisContext)\r\n    {\r\n        analysisContext.EnableConcurrentExecution();\r\n        analysisContext.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);\r\n\r\n        analysisContext.RegisterCompilationStartAction(ctx =>\r\n        {\r\n            // Only run if BenchmarkDotNet.Annotations is referenced\r\n            var benchmarkAttributeTypeSymbol = AnalyzerHelper.GetBenchmarkAttributeTypeSymbol(ctx.Compilation);\r\n            if (benchmarkAttributeTypeSymbol == null)\r\n            {\r\n                return;\r\n            }\r\n\r\n            ctx.RegisterSymbolAction(AnalyzeMethodSymbol, SymbolKind.Method);\r\n        });\r\n    }\r\n\r\n    private static void AnalyzeMethodSymbol(SymbolAnalysisContext context)\r\n    {\r\n        if (context.Symbol is not IMethodSymbol methodSymbol)\r\n        {\r\n            return;\r\n        }\r\n\r\n        var benchmarkAttributeTypeSymbol = AnalyzerHelper.GetBenchmarkAttributeTypeSymbol(context.Compilation);\r\n        var argumentsAttributeTypeSymbol = context.Compilation.GetTypeByMetadataName(\"BenchmarkDotNet.Attributes.ArgumentsAttribute\");\r\n        var argumentsSourceAttributeTypeSymbol = context.Compilation.GetTypeByMetadataName(\"BenchmarkDotNet.Attributes.ArgumentsSourceAttribute\");\r\n\r\n        if (argumentsAttributeTypeSymbol == null || argumentsSourceAttributeTypeSymbol == null)\r\n        {\r\n            return;\r\n        }\r\n\r\n        bool hasBenchmarkAttribute = false;\r\n        var argumentsAttributes = new List<AttributeData>();\r\n        var argumentsSourceAttributes = new List<AttributeData>();\r\n        foreach (var attr in methodSymbol.GetAttributes())\r\n        {\r\n            if (SymbolEqualityComparer.Default.Equals(attr.AttributeClass, benchmarkAttributeTypeSymbol))\r\n            {\r\n                hasBenchmarkAttribute = true;\r\n            }\r\n            else if (SymbolEqualityComparer.Default.Equals(attr.AttributeClass, argumentsAttributeTypeSymbol))\r\n            {\r\n                argumentsAttributes.Add(attr);\r\n            }\r\n            else if (SymbolEqualityComparer.Default.Equals(attr.AttributeClass, argumentsSourceAttributeTypeSymbol))\r\n            {\r\n                argumentsSourceAttributes.Add(attr);\r\n            }\r\n        }\r\n\r\n        if (argumentsAttributes.Count == 0 && argumentsSourceAttributes.Count == 0)\r\n        {\r\n            return;\r\n        }\r\n\r\n        bool methodHasZeroParams = methodSymbol.Parameters.Length == 0;\r\n        if (!hasBenchmarkAttribute || methodHasZeroParams)\r\n        {\r\n            argumentsAttributes.AddRange(argumentsSourceAttributes);\r\n            foreach (var attr in argumentsAttributes)\r\n            {\r\n                if (!hasBenchmarkAttribute)\r\n                {\r\n                    context.ReportDiagnostic(Diagnostic.Create(RequiresBenchmarkAttributeRule, attr.GetLocation()));\r\n                }\r\n                if (methodHasZeroParams)\r\n                {\r\n                    context.ReportDiagnostic(Diagnostic.Create(RequiresParametersRule, attr.GetLocation(), methodSymbol.Name));\r\n                }\r\n            }\r\n            return;\r\n        }\r\n\r\n        foreach (var attr in argumentsAttributes)\r\n        {\r\n            // [Arguments]\r\n            if (attr.ConstructorArguments.Length == 0)\r\n            {\r\n                ReportMustHaveMatchingValueCountDiagnostic(attr.GetLocation(), 0);\r\n                continue;\r\n            }\r\n\r\n            // [Arguments(null)]\r\n            if (attr.ConstructorArguments[0].IsNull)\r\n            {\r\n                if (methodSymbol.Parameters.Length > 1)\r\n                {\r\n                    ReportMustHaveMatchingValueCountDiagnostic(attr.GetLocation(), 1);\r\n                }\r\n                else\r\n                {\r\n                    var syntax = (AttributeSyntax)attr.ApplicationSyntaxReference!.GetSyntax();\r\n                    AnalyzeAssignableValueType(\r\n                        attr.ConstructorArguments[0],\r\n                        syntax.ArgumentList!.Arguments[0].Expression,\r\n                        methodSymbol.Parameters[0].Type\r\n                    );\r\n                }\r\n                continue;\r\n            }\r\n\r\n            // [Arguments(multiple, values)]\r\n            var actualValues = attr.ConstructorArguments[0].Values;\r\n            if (actualValues.Length != methodSymbol.Parameters.Length)\r\n            {\r\n                ReportMustHaveMatchingValueCountDiagnostic(attr.GetLocation(), actualValues.Length);\r\n                continue;\r\n            }\r\n\r\n            for (int i = 0; i < actualValues.Length; i++)\r\n            {\r\n                AnalyzeAssignableValueType(\r\n                    actualValues[i],\r\n                    AnalyzerHelper.GetAttributeParamsArgumentExpression(attr, i),\r\n                    methodSymbol.Parameters[i].Type\r\n                );\r\n            }\r\n        }\r\n\r\n        void ReportMustHaveMatchingValueCountDiagnostic(Location diagnosticLocation, int valueCount)\r\n            => context.ReportDiagnostic(Diagnostic.Create(MustHaveMatchingValueCountRule,\r\n                diagnosticLocation,\r\n                methodSymbol.Parameters.Length,\r\n                methodSymbol.Parameters.Length == 1 ? \"\" : \"s\",\r\n                methodSymbol.Name,\r\n                valueCount)\r\n            );\r\n\r\n        void AnalyzeAssignableValueType(TypedConstant value, ExpressionSyntax expression, ITypeSymbol parameterType)\r\n        {\r\n            // Don't analyze unknown types.\r\n            if (value.Kind == TypedConstantKind.Error || parameterType is IErrorTypeSymbol)\r\n            {\r\n                return;\r\n            }\r\n            if (!AnalyzerHelper.IsAssignable(value, expression, parameterType, context.Compilation))\r\n            {\r\n                context.ReportDiagnostic(Diagnostic.Create(MustHaveMatchingValueTypeRule,\r\n                    expression.GetLocation(),\r\n                    expression.ToString(),\r\n                    parameterType.ToDisplayString(),\r\n                    value.IsNull ? \"null\" : value.Type!.ToDisplayString())\r\n                );\r\n            }\r\n        }\r\n    }\r\n}"
  },
  {
    "path": "src/BenchmarkDotNet.Analyzers/Attributes/GeneralArgumentAttributesAnalyzer.cs",
    "content": "﻿using Microsoft.CodeAnalysis;\r\nusing Microsoft.CodeAnalysis.CSharp;\r\nusing Microsoft.CodeAnalysis.CSharp.Syntax;\r\nusing Microsoft.CodeAnalysis.Diagnostics;\r\nusing System.Collections.Immutable;\r\n\r\nnamespace BenchmarkDotNet.Analyzers.Attributes;\r\n\r\n[DiagnosticAnalyzer(LanguageNames.CSharp)]\r\npublic class GeneralArgumentAttributesAnalyzer : DiagnosticAnalyzer\r\n{\r\n    internal static readonly DiagnosticDescriptor MethodWithoutAttributeMustHaveNoParametersRule = new(\r\n        DiagnosticIds.Attributes_GeneralArgumentAttributes_MethodWithoutAttributeMustHaveNoParameters,\r\n        AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.Attributes_GeneralArgumentAttributes_MethodWithoutAttributeMustHaveNoParameters_Title)),\r\n        AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.Attributes_GeneralArgumentAttributes_MethodWithoutAttributeMustHaveNoParameters_MessageFormat)),\r\n        \"Usage\",\r\n        DiagnosticSeverity.Error,\r\n        isEnabledByDefault: true,\r\n        description: BenchmarkDotNetAnalyzerResources.Attributes_GeneralArgumentAttributes_MethodWithoutAttributeMustHaveNoParameters_Description);\r\n\r\n    public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => new DiagnosticDescriptor[]\r\n    {\r\n        MethodWithoutAttributeMustHaveNoParametersRule,\r\n    }.ToImmutableArray();\r\n\r\n    public override void Initialize(AnalysisContext analysisContext)\r\n    {\r\n        analysisContext.EnableConcurrentExecution();\r\n        analysisContext.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);\r\n\r\n        analysisContext.RegisterCompilationStartAction(ctx =>\r\n        {\r\n            // Only run if BenchmarkDotNet.Annotations is referenced\r\n            var benchmarkAttributeTypeSymbol = AnalyzerHelper.GetBenchmarkAttributeTypeSymbol(ctx.Compilation);\r\n            if (benchmarkAttributeTypeSymbol == null)\r\n            {\r\n                return;\r\n            }\r\n\r\n            ctx.RegisterSyntaxNodeAction(AnalyzeMethodDeclaration, SyntaxKind.MethodDeclaration);\r\n        });\r\n    }\r\n\r\n    private static void AnalyzeMethodDeclaration(SyntaxNodeAnalysisContext context)\r\n    {\r\n        if (context.Node is not MethodDeclarationSyntax methodDeclarationSyntax)\r\n        {\r\n            return;\r\n        }\r\n\r\n        var argumentsAttributeTypeSymbol = context.Compilation.GetTypeByMetadataName(\"BenchmarkDotNet.Attributes.ArgumentsAttribute\");\r\n        var argumentsSourceAttributeTypeSymbol = context.Compilation.GetTypeByMetadataName(\"BenchmarkDotNet.Attributes.ArgumentsSourceAttribute\");\r\n\r\n        if (argumentsAttributeTypeSymbol == null || argumentsSourceAttributeTypeSymbol == null)\r\n        {\r\n            return;\r\n        }\r\n\r\n        var hasBenchmarkAttribute = AnalyzerHelper.AttributeListsContainAttribute(AnalyzerHelper.GetBenchmarkAttributeTypeSymbol(context.Compilation), methodDeclarationSyntax.AttributeLists, context.SemanticModel);\r\n        var hasArgumentsSourceAttribute = AnalyzerHelper.AttributeListsContainAttribute(argumentsSourceAttributeTypeSymbol, methodDeclarationSyntax.AttributeLists, context.SemanticModel);\r\n\r\n        var argumentsAttributes = AnalyzerHelper.GetAttributes(argumentsAttributeTypeSymbol, methodDeclarationSyntax.AttributeLists, context.SemanticModel);\r\n        if (argumentsAttributes.Length == 0)\r\n        {\r\n            if (hasBenchmarkAttribute && !hasArgumentsSourceAttribute && methodDeclarationSyntax.ParameterList.Parameters.Count > 0)\r\n            {\r\n                context.ReportDiagnostic(Diagnostic.Create(\r\n                    MethodWithoutAttributeMustHaveNoParametersRule,\r\n                    Location.Create(context.Node.SyntaxTree, methodDeclarationSyntax.ParameterList.Parameters.Span), methodDeclarationSyntax.Identifier.ToString())\r\n                );\r\n            }\r\n        }\r\n    }\r\n}"
  },
  {
    "path": "src/BenchmarkDotNet.Analyzers/Attributes/GeneralParameterAttributesAnalyzer.cs",
    "content": "using Microsoft.CodeAnalysis;\r\nusing Microsoft.CodeAnalysis.CSharp;\r\nusing Microsoft.CodeAnalysis.CSharp.Syntax;\r\nusing Microsoft.CodeAnalysis.Diagnostics;\r\nusing System.Collections.Generic;\r\nusing System.Collections.Immutable;\r\nusing System.Linq;\r\n\r\nnamespace BenchmarkDotNet.Analyzers.Attributes;\r\n\r\n[DiagnosticAnalyzer(LanguageNames.CSharp)]\r\npublic class GeneralParameterAttributesAnalyzer : DiagnosticAnalyzer\r\n{\r\n    internal static readonly DiagnosticDescriptor MutuallyExclusiveOnFieldRule = new(\r\n        DiagnosticIds.Attributes_GeneralParameterAttributes_MutuallyExclusiveOnField,\r\n        AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.Attributes_GeneralParameterAttributes_MutuallyExclusiveOnField_Title)),\r\n        AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.Attributes_GeneralParameterAttributes_MutuallyExclusiveOnField_MessageFormat)),\r\n        \"Usage\",\r\n        DiagnosticSeverity.Error,\r\n        isEnabledByDefault: true,\r\n        description: AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.Attributes_GeneralParameterAttributes_MutuallyExclusiveOnField_Description)));\r\n\r\n    internal static readonly DiagnosticDescriptor MutuallyExclusiveOnPropertyRule = new(\r\n        DiagnosticIds.Attributes_GeneralParameterAttributes_MutuallyExclusiveOnProperty,\r\n        AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.Attributes_GeneralParameterAttributes_MutuallyExclusiveOnProperty_Title)),\r\n        AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.Attributes_GeneralParameterAttributes_MutuallyExclusiveOnProperty_MessageFormat)),\r\n        \"Usage\",\r\n        DiagnosticSeverity.Error,\r\n        isEnabledByDefault: true,\r\n        description: AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.Attributes_GeneralParameterAttributes_MutuallyExclusiveOnProperty_Description)));\r\n\r\n    internal static readonly DiagnosticDescriptor FieldMustBePublic = new(\r\n        DiagnosticIds.Attributes_GeneralParameterAttributes_FieldMustBePublic,\r\n        AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.Attributes_GeneralParameterAttributes_FieldMustBePublic_Title)),\r\n        AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.Attributes_GeneralParameterAttributes_FieldMustBePublic_MessageFormat)),\r\n        \"Usage\",\r\n        DiagnosticSeverity.Error,\r\n        isEnabledByDefault: true,\r\n        description: AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.Attributes_GeneralParameterAttributes_FieldMustBePublic_Description)));\r\n\r\n    internal static readonly DiagnosticDescriptor PropertyMustBePublic = new(\r\n        DiagnosticIds.Attributes_GeneralParameterAttributes_PropertyMustBePublic,\r\n        AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.Attributes_GeneralParameterAttributes_PropertyMustBePublic_Title)),\r\n        AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.Attributes_GeneralParameterAttributes_PropertyMustBePublic_MessageFormat)),\r\n        \"Usage\",\r\n        DiagnosticSeverity.Error,\r\n        isEnabledByDefault: true,\r\n        description: AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.Attributes_GeneralParameterAttributes_PropertyMustBePublic_Description)));\r\n\r\n    internal static readonly DiagnosticDescriptor NotValidOnReadonlyFieldRule = new(\r\n        DiagnosticIds.Attributes_GeneralParameterAttributes_NotValidOnReadonlyField,\r\n        AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.Attributes_GeneralParameterAttributes_NotValidOnReadonlyField_Title)),\r\n        AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.Attributes_GeneralParameterAttributes_NotValidOnReadonlyField_MessageFormat)),\r\n        \"Usage\",\r\n        DiagnosticSeverity.Error,\r\n        isEnabledByDefault: true,\r\n        description: AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.Attributes_GeneralParameterAttributes_NotValidOnReadonlyField_Description)));\r\n\r\n    internal static readonly DiagnosticDescriptor NotValidOnConstantFieldRule = new(\r\n        DiagnosticIds.Attributes_GeneralParameterAttributes_NotValidOnConstantField,\r\n        AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.Attributes_GeneralParameterAttributes_NotValidOnConstantField_Title)),\r\n        AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.Attributes_GeneralParameterAttributes_NotValidOnConstantField_MessageFormat)),\r\n        \"Usage\",\r\n        DiagnosticSeverity.Error,\r\n        isEnabledByDefault: true);\r\n\r\n    internal static readonly DiagnosticDescriptor PropertyMustHavePublicSetterRule = new(\r\n        DiagnosticIds.Attributes_GeneralParameterAttributes_PropertyMustHavePublicSetter,\r\n        AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.Attributes_GeneralParameterAttributes_PropertyMustHavePublicSetter_Title)),\r\n        AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.Attributes_GeneralParameterAttributes_PropertyMustHavePublicSetter_MessageFormat)),\r\n        \"Usage\",\r\n        DiagnosticSeverity.Error,\r\n        isEnabledByDefault: true,\r\n        description: AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.Attributes_GeneralParameterAttributes_PropertyMustHavePublicSetter_Description)));\r\n\r\n    internal static readonly DiagnosticDescriptor PropertyCannotBeInitOnlyRule = new(\r\n        DiagnosticIds.Attributes_GeneralParameterAttributes_PropertyCannotBeInitOnly,\r\n        AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.Attributes_GeneralParameterAttributes_PropertyCannotBeInitOnly_Title)),\r\n        AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.Attributes_GeneralParameterAttributes_PropertyCannotBeInitOnly_MessageFormat)),\r\n        \"Usage\",\r\n        DiagnosticSeverity.Error,\r\n        isEnabledByDefault: true,\r\n        description: AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.Attributes_GeneralParameterAttributes_PropertyCannotBeInitOnly_Description)));\r\n\r\n    internal static readonly DiagnosticDescriptor ParamsSourceCannotUseWriteOnlyPropertyRule = new(\r\n        DiagnosticIds.Attributes_ParamsSourceAttribute_CannotUseWriteOnlyProperty,\r\n        AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.Attributes_ParamsSourceAttribute_CannotUseWriteOnlyProperty_Title)),\r\n        AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.Attributes_ParamsSourceAttribute_CannotUseWriteOnlyProperty_MessageFormat)),\r\n        \"Usage\",\r\n        DiagnosticSeverity.Error,\r\n        isEnabledByDefault: true,\r\n        description: AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.Attributes_ParamsSourceAttribute_CannotUseWriteOnlyProperty_Description)));\r\n\r\n    public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => new DiagnosticDescriptor[]\r\n    {\r\n        MutuallyExclusiveOnFieldRule,\r\n        MutuallyExclusiveOnPropertyRule,\r\n        FieldMustBePublic,\r\n        PropertyMustBePublic,\r\n        NotValidOnReadonlyFieldRule,\r\n        NotValidOnConstantFieldRule,\r\n        PropertyCannotBeInitOnlyRule,\r\n        PropertyMustHavePublicSetterRule,\r\n        ParamsSourceCannotUseWriteOnlyPropertyRule,\r\n    }.ToImmutableArray();\r\n\r\n    public override void Initialize(AnalysisContext analysisContext)\r\n    {\r\n        analysisContext.EnableConcurrentExecution();\r\n        analysisContext.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);\r\n\r\n        analysisContext.RegisterCompilationStartAction(ctx =>\r\n        {\r\n            // Only run if BenchmarkDotNet.Annotations is referenced\r\n            var benchmarkAttributeTypeSymbol = AnalyzerHelper.GetBenchmarkAttributeTypeSymbol(ctx.Compilation);\r\n            if (benchmarkAttributeTypeSymbol == null)\r\n            {\r\n                return;\r\n            }\r\n\r\n            ctx.RegisterSyntaxNodeAction(Analyze, SyntaxKind.Attribute);\r\n        });\r\n    }\r\n\r\n    private static void Analyze(SyntaxNodeAnalysisContext context)\r\n    {\r\n        if (context.Node is not AttributeSyntax attributeSyntax)\r\n        {\r\n            return;\r\n        }\r\n\r\n        if (!AllAttributeTypeSymbolsExist(context, out var paramsAttributeTypeSymbol, out var paramsSourceAttributeTypeSymbol, out var paramsAllValuesAttributeTypeSymbol))\r\n        {\r\n            return;\r\n        }\r\n\r\n        var attributeSyntaxTypeSymbol = context.SemanticModel.GetTypeInfo(attributeSyntax).Type;\r\n        if (attributeSyntaxTypeSymbol == null\r\n            || attributeSyntaxTypeSymbol.TypeKind == TypeKind.Error\r\n            ||\r\n                   (!SymbolEqualityComparer.Default.Equals(attributeSyntaxTypeSymbol, paramsAttributeTypeSymbol)\r\n                 && !SymbolEqualityComparer.Default.Equals(attributeSyntaxTypeSymbol, paramsSourceAttributeTypeSymbol)\r\n                 && !SymbolEqualityComparer.Default.Equals(attributeSyntaxTypeSymbol, paramsAllValuesAttributeTypeSymbol)))\r\n        {\r\n            return;\r\n        }\r\n\r\n        var attributeTarget = attributeSyntax.FirstAncestorOrSelf<SyntaxNode>(n => n is FieldDeclarationSyntax or PropertyDeclarationSyntax);\r\n        if (attributeTarget == null)\r\n        {\r\n            return;\r\n        }\r\n\r\n        ImmutableArray<AttributeSyntax> declaredAttributes;\r\n        bool fieldOrPropertyIsPublic;\r\n        Location? fieldConstModifierLocation = null;\r\n        Location? fieldReadonlyModifierLocation = null;\r\n        string fieldOrPropertyIdentifier;\r\n        Location? propertyInitAccessorKeywordLocation = null;\r\n        Location fieldOrPropertyIdentifierLocation;\r\n        bool propertyIsMissingAssignableSetter = false;\r\n        DiagnosticDescriptor fieldOrPropertyCannotHaveMoreThanOneParameterAttributeAppliedDiagnosticRule;\r\n        DiagnosticDescriptor fieldOrPropertyMustBePublicDiagnosticRule;\r\n\r\n        if (attributeTarget is FieldDeclarationSyntax fieldDeclarationSyntax)\r\n        {\r\n            declaredAttributes = fieldDeclarationSyntax.AttributeLists.SelectMany(als => als.Attributes).ToImmutableArray();\r\n            fieldOrPropertyIsPublic = fieldDeclarationSyntax.Modifiers.Any(SyntaxKind.PublicKeyword);\r\n\r\n            var fieldConstModifierIndex = fieldDeclarationSyntax.Modifiers.IndexOf(SyntaxKind.ConstKeyword);\r\n            fieldConstModifierLocation = fieldConstModifierIndex >= 0 ? fieldDeclarationSyntax.Modifiers[fieldConstModifierIndex].GetLocation() : null;\r\n\r\n            var fieldOrPropertyReadonlyModifierIndex = fieldDeclarationSyntax.Modifiers.IndexOf(SyntaxKind.ReadOnlyKeyword);\r\n            fieldReadonlyModifierLocation = fieldOrPropertyReadonlyModifierIndex >= 0 ? fieldDeclarationSyntax.Modifiers[fieldOrPropertyReadonlyModifierIndex].GetLocation() : null;\r\n\r\n            fieldOrPropertyIdentifier = fieldDeclarationSyntax.Declaration.Variables[0].Identifier.ToString();\r\n            fieldOrPropertyIdentifierLocation = fieldDeclarationSyntax.Declaration.Variables[0].Identifier.GetLocation();\r\n            fieldOrPropertyCannotHaveMoreThanOneParameterAttributeAppliedDiagnosticRule = MutuallyExclusiveOnFieldRule;\r\n            fieldOrPropertyMustBePublicDiagnosticRule = FieldMustBePublic;\r\n        }\r\n        else if (attributeTarget is PropertyDeclarationSyntax propertyDeclarationSyntax)\r\n        {\r\n            declaredAttributes = propertyDeclarationSyntax.AttributeLists.SelectMany(als => als.Attributes).ToImmutableArray();\r\n            fieldOrPropertyIsPublic = propertyDeclarationSyntax.Modifiers.Any(SyntaxKind.PublicKeyword);\r\n            fieldOrPropertyIdentifier = propertyDeclarationSyntax.Identifier.ToString();\r\n\r\n#if CODE_ANALYSIS_3_8\r\n            var propertyInitAccessorIndex = propertyDeclarationSyntax.AccessorList?.Accessors.IndexOf(SyntaxKind.InitAccessorDeclaration);\r\n            propertyInitAccessorKeywordLocation = propertyInitAccessorIndex >= 0 ? propertyDeclarationSyntax.AccessorList!.Accessors[propertyInitAccessorIndex.Value].Keyword.GetLocation() : null;\r\n#endif\r\n\r\n            var propertySetAccessorIndex = propertyDeclarationSyntax.AccessorList?.Accessors.IndexOf(SyntaxKind.SetAccessorDeclaration);\r\n            propertyIsMissingAssignableSetter = !propertySetAccessorIndex.HasValue || propertySetAccessorIndex.Value < 0 || propertyDeclarationSyntax.AccessorList!.Accessors[propertySetAccessorIndex.Value].Modifiers.Any();\r\n\r\n            fieldOrPropertyIdentifierLocation = propertyDeclarationSyntax.Identifier.GetLocation();\r\n            fieldOrPropertyCannotHaveMoreThanOneParameterAttributeAppliedDiagnosticRule = MutuallyExclusiveOnPropertyRule;\r\n            fieldOrPropertyMustBePublicDiagnosticRule = PropertyMustBePublic;\r\n        }\r\n        else\r\n        {\r\n            return;\r\n        }\r\n\r\n        AnalyzeFieldOrPropertySymbol(\r\n            context,\r\n            paramsAttributeTypeSymbol!,\r\n            paramsSourceAttributeTypeSymbol!,\r\n            paramsAllValuesAttributeTypeSymbol!,\r\n            declaredAttributes,\r\n            fieldOrPropertyIsPublic,\r\n            fieldConstModifierLocation,\r\n            fieldReadonlyModifierLocation,\r\n            fieldOrPropertyIdentifier,\r\n            propertyInitAccessorKeywordLocation,\r\n            propertyIsMissingAssignableSetter,\r\n            fieldOrPropertyIdentifierLocation,\r\n            fieldOrPropertyCannotHaveMoreThanOneParameterAttributeAppliedDiagnosticRule,\r\n            fieldOrPropertyMustBePublicDiagnosticRule,\r\n            attributeSyntax,\r\n            attributeTarget);\r\n    }\r\n\r\n    private static void AnalyzeFieldOrPropertySymbol(\r\n        SyntaxNodeAnalysisContext context,\r\n        INamedTypeSymbol paramsAttributeTypeSymbol,\r\n        INamedTypeSymbol paramsSourceAttributeTypeSymbol,\r\n        INamedTypeSymbol paramsAllValuesAttributeTypeSymbol,\r\n        ImmutableArray<AttributeSyntax> declaredAttributes,\r\n        bool fieldOrPropertyIsPublic,\r\n        Location? fieldConstModifierLocation,\r\n        Location? fieldReadonlyModifierLocation,\r\n        string fieldOrPropertyIdentifier,\r\n        Location? propertyInitAccessorKeywordLocation,\r\n        bool propertyIsMissingAssignableSetter,\r\n        Location fieldOrPropertyIdentifierLocation,\r\n        DiagnosticDescriptor fieldOrPropertyCannotHaveMoreThanOneParameterAttributeAppliedDiagnosticRule,\r\n        DiagnosticDescriptor fieldOrPropertyMustBePublicDiagnosticRule,\r\n        AttributeSyntax attributeSyntax,\r\n        SyntaxNode attributeTarget)\r\n    {\r\n        ImmutableArray<INamedTypeSymbol> applicableParameterAttributeTypeSymbols =\r\n        [\r\n            paramsAttributeTypeSymbol,\r\n            paramsSourceAttributeTypeSymbol,\r\n            paramsAllValuesAttributeTypeSymbol\r\n        ];\r\n\r\n        var parameterAttributeTypeSymbols = new HashSet<INamedTypeSymbol>(SymbolEqualityComparer.Default);\r\n\r\n        foreach (var declaredAttributeSyntax in declaredAttributes)\r\n        {\r\n            var declaredAttributeTypeSymbol = context.SemanticModel.GetTypeInfo(declaredAttributeSyntax).Type;\r\n            if (declaredAttributeTypeSymbol != null)\r\n            {\r\n                foreach (var applicableParameterAttributeTypeSymbol in applicableParameterAttributeTypeSymbols)\r\n                {\r\n                    if (SymbolEqualityComparer.Default.Equals(declaredAttributeTypeSymbol, applicableParameterAttributeTypeSymbol))\r\n                    {\r\n                        if (!parameterAttributeTypeSymbols.Add(applicableParameterAttributeTypeSymbol))\r\n                        {\r\n                            return;\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        if (parameterAttributeTypeSymbols.Count == 0)\r\n        {\r\n            return;\r\n        }\r\n\r\n        if (parameterAttributeTypeSymbols.Count != 1)\r\n        {\r\n            context.ReportDiagnostic(Diagnostic.Create(fieldOrPropertyCannotHaveMoreThanOneParameterAttributeAppliedDiagnosticRule,\r\n                attributeSyntax.GetLocation(),\r\n                fieldOrPropertyIdentifier)\r\n            );\r\n\r\n            return;\r\n        }\r\n\r\n        if (fieldConstModifierLocation != null)\r\n        {\r\n            context.ReportDiagnostic(Diagnostic.Create(NotValidOnConstantFieldRule,\r\n                fieldConstModifierLocation,\r\n                attributeSyntax.Name.ToString())\r\n            );\r\n\r\n            return;\r\n        }\r\n\r\n        if (!fieldOrPropertyIsPublic)\r\n        {\r\n            context.ReportDiagnostic(Diagnostic.Create(fieldOrPropertyMustBePublicDiagnosticRule,\r\n                fieldOrPropertyIdentifierLocation,\r\n                fieldOrPropertyIdentifier,\r\n                attributeSyntax.Name.ToString())\r\n            );\r\n        }\r\n\r\n        if (fieldReadonlyModifierLocation != null)\r\n        {\r\n            context.ReportDiagnostic(Diagnostic.Create(NotValidOnReadonlyFieldRule,\r\n                fieldReadonlyModifierLocation,\r\n                fieldOrPropertyIdentifier,\r\n                attributeSyntax.Name.ToString())\r\n            );\r\n        }\r\n\r\n        if (propertyInitAccessorKeywordLocation != null)\r\n        {\r\n            context.ReportDiagnostic(Diagnostic.Create(PropertyCannotBeInitOnlyRule,\r\n                propertyInitAccessorKeywordLocation,\r\n                fieldOrPropertyIdentifier,\r\n                attributeSyntax.Name.ToString())\r\n            );\r\n        }\r\n        else if (propertyIsMissingAssignableSetter)\r\n        {\r\n            context.ReportDiagnostic(Diagnostic.Create(PropertyMustHavePublicSetterRule,\r\n                fieldOrPropertyIdentifierLocation,\r\n                fieldOrPropertyIdentifier,\r\n                attributeSyntax.Name.ToString())\r\n            );\r\n        }\r\n\r\n        if (parameterAttributeTypeSymbols.Contains(paramsSourceAttributeTypeSymbol))\r\n        {\r\n            AnalyzeParamsSourceWriteOnlyProperty(context, attributeSyntax, attributeTarget);\r\n        }\r\n    }\r\n\r\n    private static void AnalyzeParamsSourceWriteOnlyProperty(\r\n        SyntaxNodeAnalysisContext context,\r\n        AttributeSyntax attributeSyntax,\r\n        SyntaxNode attributeTarget)\r\n    {\r\n        ISymbol? symbol = attributeTarget switch\r\n        {\r\n            FieldDeclarationSyntax field => context.SemanticModel.GetDeclaredSymbol(field.Declaration.Variables[0]),\r\n            PropertyDeclarationSyntax property => context.SemanticModel.GetDeclaredSymbol(property),\r\n            _ => null\r\n        };\r\n\r\n        if (symbol == null)\r\n        {\r\n            return;\r\n        }\r\n\r\n        var attributeData = symbol.GetAttributes()\r\n            .FirstOrDefault(attr => attr.ApplicationSyntaxReference?.GetSyntax() == attributeSyntax);\r\n\r\n        if (attributeData == null)\r\n        {\r\n            return;\r\n        }\r\n\r\n        string? sourceName = null;\r\n        ITypeSymbol? targetType = null;\r\n\r\n        // [ParamsSource(\"name\")]\r\n        if (attributeData.ConstructorArguments.Length == 1)\r\n        {\r\n            if (attributeData.ConstructorArguments[0].Kind == TypedConstantKind.Primitive\r\n                && attributeData.ConstructorArguments[0].Value is string name)\r\n            {\r\n                sourceName = name;\r\n            }\r\n            else\r\n            {\r\n                var syntax = (AttributeSyntax)attributeData.ApplicationSyntaxReference!.GetSyntax();\r\n                if (syntax.ArgumentList?.Arguments.Count > 0)\r\n                {\r\n                    sourceName = ExtractNameFromExpression(syntax.ArgumentList.Arguments[0].Expression, context.SemanticModel);\r\n                }\r\n            }\r\n            targetType = GetContainingType(attributeSyntax, context);\r\n        }\r\n        // [ParamsSource(typeof(OtherClass), nameof(OtherClass.Values))]\r\n        else if (attributeData.ConstructorArguments.Length == 2)\r\n        {\r\n            if (attributeData.ConstructorArguments[0].Kind == TypedConstantKind.Type\r\n                && attributeData.ConstructorArguments[0].Value is ITypeSymbol type)\r\n            {\r\n                targetType = type;\r\n            }\r\n\r\n            if (attributeData.ConstructorArguments[1].Kind == TypedConstantKind.Primitive\r\n                && attributeData.ConstructorArguments[1].Value is string name)\r\n            {\r\n                sourceName = name;\r\n            }\r\n            else\r\n            {\r\n                var syntax = (AttributeSyntax)attributeData.ApplicationSyntaxReference!.GetSyntax();\r\n                if (syntax.ArgumentList?.Arguments.Count > 1)\r\n                {\r\n                    sourceName = ExtractNameFromExpression(syntax.ArgumentList.Arguments[1].Expression, context.SemanticModel);\r\n                }\r\n            }\r\n        }\r\n\r\n        if (string.IsNullOrEmpty(sourceName) || targetType == null)\r\n        {\r\n            return;\r\n        }\r\n\r\n        var referencedMember = targetType.GetMembers(sourceName!).FirstOrDefault();\r\n        if (referencedMember is IPropertySymbol propertySymbol\r\n            && propertySymbol.SetMethod != null\r\n            && propertySymbol.GetMethod == null)\r\n        {\r\n            Location? location = null;\r\n            if (attributeSyntax.ArgumentList != null)\r\n            {\r\n                if (attributeData.ConstructorArguments.Length == 1 && attributeSyntax.ArgumentList.Arguments.Count > 0)\r\n                {\r\n                    location = attributeSyntax.ArgumentList.Arguments[0].Expression.GetLocation();\r\n                }\r\n                else if (attributeData.ConstructorArguments.Length == 2 && attributeSyntax.ArgumentList.Arguments.Count > 1)\r\n                {\r\n                    location = attributeSyntax.ArgumentList.Arguments[1].Expression.GetLocation();\r\n                }\r\n            }\r\n            location ??= attributeSyntax.GetLocation();\r\n\r\n            context.ReportDiagnostic(Diagnostic.Create(\r\n                ParamsSourceCannotUseWriteOnlyPropertyRule,\r\n                location,\r\n                sourceName));\r\n        }\r\n    }\r\n\r\n    private static string? ExtractNameFromExpression(ExpressionSyntax expression, SemanticModel semanticModel)\r\n    {\r\n        if (expression is InvocationExpressionSyntax invocation\r\n            && invocation.Expression is IdentifierNameSyntax identifierName\r\n            && identifierName.Identifier.ValueText == \"nameof\"\r\n            && invocation.ArgumentList.Arguments.Count > 0)\r\n        {\r\n            var argumentExpression = invocation.ArgumentList.Arguments[0].Expression;\r\n            var symbolInfo = semanticModel.GetSymbolInfo(argumentExpression);\r\n            if (symbolInfo.Symbol != null)\r\n            {\r\n                return symbolInfo.Symbol.Name;\r\n            }\r\n            if (argumentExpression is IdentifierNameSyntax id)\r\n            {\r\n                return id.Identifier.ValueText;\r\n            }\r\n            if (argumentExpression is MemberAccessExpressionSyntax memberAccess)\r\n            {\r\n                return memberAccess.Name.Identifier.ValueText;\r\n            }\r\n        }\r\n\r\n        if (expression is LiteralExpressionSyntax literal\r\n            && literal.Token.Value is string str)\r\n        {\r\n            return str;\r\n        }\r\n\r\n        return null;\r\n    }\r\n\r\n    private static INamedTypeSymbol? GetContainingType(AttributeSyntax attributeSyntax, SyntaxNodeAnalysisContext context)\r\n    {\r\n        var fieldOrProperty = attributeSyntax.FirstAncestorOrSelf<SyntaxNode>(n => n is FieldDeclarationSyntax or PropertyDeclarationSyntax);\r\n        if (fieldOrProperty == null)\r\n        {\r\n            return null;\r\n        }\r\n\r\n        var containingType = fieldOrProperty.FirstAncestorOrSelf<TypeDeclarationSyntax>();\r\n        if (containingType == null)\r\n        {\r\n            return null;\r\n        }\r\n\r\n        return context.SemanticModel.GetDeclaredSymbol(containingType);\r\n    }\r\n\r\n    private static bool AllAttributeTypeSymbolsExist(\r\n        in SyntaxNodeAnalysisContext context,\r\n        out INamedTypeSymbol? paramsAttributeTypeSymbol,\r\n        out INamedTypeSymbol? paramsSourceAttributeTypeSymbol,\r\n        out INamedTypeSymbol? paramsAllValuesAttributeTypeSymbol)\r\n    {\r\n        paramsAttributeTypeSymbol = context.Compilation.GetTypeByMetadataName(\"BenchmarkDotNet.Attributes.ParamsAttribute\");\r\n        if (paramsAttributeTypeSymbol == null)\r\n        {\r\n            paramsSourceAttributeTypeSymbol = null;\r\n            paramsAllValuesAttributeTypeSymbol = null;\r\n\r\n            return false;\r\n        }\r\n\r\n        paramsSourceAttributeTypeSymbol = context.Compilation.GetTypeByMetadataName(\"BenchmarkDotNet.Attributes.ParamsSourceAttribute\");\r\n        if (paramsSourceAttributeTypeSymbol == null)\r\n        {\r\n            paramsAllValuesAttributeTypeSymbol = null;\r\n\r\n            return false;\r\n        }\r\n\r\n        paramsAllValuesAttributeTypeSymbol = context.Compilation.GetTypeByMetadataName(\"BenchmarkDotNet.Attributes.ParamsAllValuesAttribute\");\r\n        if (paramsAllValuesAttributeTypeSymbol == null)\r\n        {\r\n            return false;\r\n        }\r\n\r\n        return true;\r\n    }\r\n}"
  },
  {
    "path": "src/BenchmarkDotNet.Analyzers/Attributes/ParamsAllValuesAttributeAnalyzer.cs",
    "content": "﻿using Microsoft.CodeAnalysis;\r\nusing Microsoft.CodeAnalysis.CSharp;\r\nusing Microsoft.CodeAnalysis.CSharp.Syntax;\r\nusing Microsoft.CodeAnalysis.Diagnostics;\r\nusing System.Collections.Immutable;\r\nusing System.Linq;\r\n\r\nnamespace BenchmarkDotNet.Analyzers.Attributes;\r\n\r\n[DiagnosticAnalyzer(LanguageNames.CSharp)]\r\npublic class ParamsAllValuesAttributeAnalyzer : DiagnosticAnalyzer\r\n{\r\n    internal static readonly DiagnosticDescriptor NotAllowedOnFlagsEnumPropertyOrFieldTypeRule = new(\r\n        DiagnosticIds.Attributes_ParamsAllValuesAttribute_NotAllowedOnFlagsEnumPropertyOrFieldType,\r\n        AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.Attributes_ParamsAllValuesAttribute_NotAllowedOnFlagsEnumPropertyOrFieldType_Title)),\r\n        AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.Attributes_ParamsAllValuesAttribute_NotAllowedOnFlagsEnumPropertyOrFieldType_MessageFormat)),\r\n        \"Usage\",\r\n        DiagnosticSeverity.Error,\r\n        isEnabledByDefault: true,\r\n        description: AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.Attributes_ParamsAllValuesAttribute_NotAllowedOnFlagsEnumPropertyOrFieldType_Description)));\r\n\r\n    internal static readonly DiagnosticDescriptor PropertyOrFieldTypeMustBeEnumOrBoolRule = new(\r\n        DiagnosticIds.Attributes_ParamsAllValuesAttribute_PropertyOrFieldTypeMustBeEnumOrBool,\r\n        AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.Attributes_ParamsAllValuesAttribute_PropertyOrFieldTypeMustBeEnumOrBool_Title)),\r\n        AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.Attributes_ParamsAllValuesAttribute_PropertyOrFieldTypeMustBeEnumOrBool_MessageFormat)),\r\n        \"Usage\",\r\n        DiagnosticSeverity.Error,\r\n        isEnabledByDefault: true);\r\n\r\n    public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => new DiagnosticDescriptor[]\r\n    {\r\n        NotAllowedOnFlagsEnumPropertyOrFieldTypeRule,\r\n        PropertyOrFieldTypeMustBeEnumOrBoolRule,\r\n    }.ToImmutableArray();\r\n\r\n    public override void Initialize(AnalysisContext analysisContext)\r\n    {\r\n        analysisContext.EnableConcurrentExecution();\r\n        analysisContext.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);\r\n\r\n        analysisContext.RegisterCompilationStartAction(ctx =>\r\n        {\r\n            // Only run if BenchmarkDotNet.Annotations is referenced\r\n            if (GetParamsAllValuesAttributeTypeSymbol(ctx.Compilation) == null)\r\n            {\r\n                return;\r\n            }\r\n\r\n            ctx.RegisterSyntaxNodeAction(Analyze, SyntaxKind.Attribute);\r\n        });\r\n    }\r\n\r\n    private static void Analyze(SyntaxNodeAnalysisContext context)\r\n    {\r\n        if (context.Node is not AttributeSyntax attributeSyntax)\r\n        {\r\n            return;\r\n        }\r\n\r\n        var paramsAllValuesAttributeTypeSymbol = GetParamsAllValuesAttributeTypeSymbol(context.Compilation);\r\n\r\n        var attributeSyntaxTypeSymbol = context.SemanticModel.GetTypeInfo(attributeSyntax).Type;\r\n        if (!SymbolEqualityComparer.Default.Equals(attributeSyntaxTypeSymbol, paramsAllValuesAttributeTypeSymbol))\r\n        {\r\n            return;\r\n        }\r\n\r\n        var attributeTarget = attributeSyntax.FirstAncestorOrSelf<SyntaxNode>(n => n is FieldDeclarationSyntax or PropertyDeclarationSyntax);\r\n        if (attributeTarget == null)\r\n        {\r\n            return;\r\n        }\r\n\r\n        TypeSyntax fieldOrPropertyTypeSyntax;\r\n\r\n        if (attributeTarget is FieldDeclarationSyntax fieldDeclarationSyntax)\r\n        {\r\n            fieldOrPropertyTypeSyntax = fieldDeclarationSyntax.Declaration.Type;\r\n\r\n        }\r\n        else if (attributeTarget is PropertyDeclarationSyntax propertyDeclarationSyntax)\r\n        {\r\n            fieldOrPropertyTypeSyntax = propertyDeclarationSyntax.Type;\r\n        }\r\n        else\r\n        {\r\n            return;\r\n        }\r\n\r\n        AnalyzeFieldOrPropertyTypeSyntax(context, fieldOrPropertyTypeSyntax);\r\n    }\r\n\r\n    private static void AnalyzeFieldOrPropertyTypeSyntax(SyntaxNodeAnalysisContext context, TypeSyntax fieldOrPropertyTypeSyntax)\r\n    {\r\n        if (fieldOrPropertyTypeSyntax is NullableTypeSyntax fieldOrPropertyNullableTypeSyntax)\r\n        {\r\n            fieldOrPropertyTypeSyntax = fieldOrPropertyNullableTypeSyntax.ElementType;\r\n        }\r\n\r\n        var fieldOrPropertyTypeSymbol = context.SemanticModel.GetTypeInfo(fieldOrPropertyTypeSyntax).Type;\r\n        if (fieldOrPropertyTypeSymbol == null || fieldOrPropertyTypeSymbol.TypeKind == TypeKind.Error)\r\n        {\r\n            return;\r\n        }\r\n\r\n        if (fieldOrPropertyTypeSymbol.TypeKind == TypeKind.Enum)\r\n        {\r\n            var flagsAttributeTypeSymbol = context.Compilation.GetTypeByMetadataName(\"System.FlagsAttribute\");\r\n            if (flagsAttributeTypeSymbol == null)\r\n            {\r\n                return;\r\n            }\r\n\r\n            if (fieldOrPropertyTypeSymbol.GetAttributes().Any(ad => SymbolEqualityComparer.Default.Equals(ad.AttributeClass, flagsAttributeTypeSymbol)))\r\n            {\r\n                context.ReportDiagnostic(Diagnostic.Create(NotAllowedOnFlagsEnumPropertyOrFieldTypeRule, fieldOrPropertyTypeSyntax.GetLocation(), fieldOrPropertyTypeSymbol.ToString()));\r\n            }\r\n\r\n            return;\r\n        }\r\n\r\n        if (fieldOrPropertyTypeSymbol.SpecialType != SpecialType.System_Boolean)\r\n        {\r\n            context.ReportDiagnostic(Diagnostic.Create(PropertyOrFieldTypeMustBeEnumOrBoolRule, fieldOrPropertyTypeSyntax.GetLocation()));\r\n        }\r\n    }\r\n\r\n    private static INamedTypeSymbol? GetParamsAllValuesAttributeTypeSymbol(Compilation compilation) => compilation.GetTypeByMetadataName(\"BenchmarkDotNet.Attributes.ParamsAllValuesAttribute\");\r\n}"
  },
  {
    "path": "src/BenchmarkDotNet.Analyzers/Attributes/ParamsAttributeAnalyzer.cs",
    "content": "﻿using Microsoft.CodeAnalysis;\r\nusing Microsoft.CodeAnalysis.CSharp.Syntax;\r\nusing Microsoft.CodeAnalysis.Diagnostics;\r\nusing System.Collections.Immutable;\r\nusing System.Linq;\r\n\r\nnamespace BenchmarkDotNet.Analyzers.Attributes;\r\n\r\n[DiagnosticAnalyzer(LanguageNames.CSharp)]\r\npublic class ParamsAttributeAnalyzer : DiagnosticAnalyzer\r\n{\r\n    internal static readonly DiagnosticDescriptor MustHaveValuesRule = new(\r\n        DiagnosticIds.Attributes_ParamsAttribute_MustHaveValues,\r\n        AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.Attributes_ParamsAttribute_MustHaveValues_Title)),\r\n        AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.Attributes_ParamsAttribute_MustHaveValues_MessageFormat)),\r\n        \"Usage\",\r\n        DiagnosticSeverity.Error,\r\n        isEnabledByDefault: true);\r\n\r\n    internal static readonly DiagnosticDescriptor MustHaveMatchingValueTypeRule = new(\r\n        DiagnosticIds.Attributes_ParamsAttribute_MustHaveMatchingValueType,\r\n        AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.Attributes_ParamsAttribute_MustHaveMatchingValueType_Title)),\r\n        AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.Attributes_ParamsAttribute_MustHaveMatchingValueType_MessageFormat)),\r\n        \"Usage\",\r\n        DiagnosticSeverity.Error,\r\n        isEnabledByDefault: true,\r\n        description: AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.Attributes_ParamsAttribute_MustHaveMatchingValueType_Description)));\r\n\r\n    internal static readonly DiagnosticDescriptor UnnecessarySingleValuePassedToAttributeRule = new(\r\n        DiagnosticIds.Attributes_ParamsAttribute_UnnecessarySingleValuePassedToAttribute,\r\n        AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.Attributes_ParamsAttribute_UnnecessarySingleValuePassedToAttribute_Title)),\r\n        AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.Attributes_ParamsAttribute_UnnecessarySingleValuePassedToAttribute_MessageFormat)),\r\n        \"Usage\",\r\n        DiagnosticSeverity.Info,\r\n        isEnabledByDefault: true);\r\n\r\n    public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => new DiagnosticDescriptor[]\r\n    {\r\n        MustHaveValuesRule,\r\n        MustHaveMatchingValueTypeRule,\r\n        UnnecessarySingleValuePassedToAttributeRule,\r\n    }.ToImmutableArray();\r\n\r\n    public override void Initialize(AnalysisContext analysisContext)\r\n    {\r\n        analysisContext.EnableConcurrentExecution();\r\n        analysisContext.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);\r\n\r\n        analysisContext.RegisterCompilationStartAction(ctx =>\r\n        {\r\n            // Only run if BenchmarkDotNet.Annotations is referenced\r\n            if (GetParamsAttributeTypeSymbol(ctx.Compilation) == null)\r\n            {\r\n                return;\r\n            }\r\n\r\n            ctx.RegisterSymbolAction(Analyze, SymbolKind.Field);\r\n            ctx.RegisterSymbolAction(Analyze, SymbolKind.Property);\r\n        });\r\n    }\r\n\r\n    private void Analyze(SymbolAnalysisContext context)\r\n    {\r\n        ITypeSymbol? fieldOrPropertyType = context.Symbol switch\r\n        {\r\n            IFieldSymbol fieldSymbol => fieldSymbol.Type,\r\n            IPropertySymbol propertySymbol => propertySymbol.Type,\r\n            _ => null\r\n        };\r\n        if (fieldOrPropertyType is null)\r\n        {\r\n            return;\r\n        }\r\n\r\n        var paramsAttributeTypeSymbol = GetParamsAttributeTypeSymbol(context.Compilation);\r\n        var attrs = context.Symbol.GetAttributes();\r\n        var paramsAttributes = attrs.Where(attr => SymbolEqualityComparer.Default.Equals(attr.AttributeClass, paramsAttributeTypeSymbol)).ToImmutableArray();\r\n        if (paramsAttributes.Length != 1)\r\n        {\r\n            // Don't analyze zero or multiple [Params] (multiple is not legal and already handled by GeneralParameterAttributesAnalyzer).\r\n            return;\r\n        }\r\n\r\n        var attr = paramsAttributes[0];\r\n\r\n        // [Params]\r\n        if (attr.ConstructorArguments.Length == 0)\r\n        {\r\n            context.ReportDiagnostic(Diagnostic.Create(MustHaveValuesRule, attr.GetLocation()));\r\n            return;\r\n        }\r\n\r\n        // [Params(null)]\r\n        if (attr.ConstructorArguments[0].IsNull)\r\n        {\r\n            var syntax = (AttributeSyntax)attr.ApplicationSyntaxReference!.GetSyntax();\r\n            AnalyzeAssignableValueType(\r\n                attr.ConstructorArguments[0],\r\n                syntax.ArgumentList!.Arguments[0].Expression,\r\n                fieldOrPropertyType\r\n            );\r\n            return;\r\n        }\r\n\r\n        var actualValues = attr.ConstructorArguments[0].Values;\r\n\r\n        // [Params([ ])]\r\n        if (actualValues.Length == 0)\r\n        {\r\n            context.ReportDiagnostic(Diagnostic.Create(MustHaveValuesRule, attr.GetLocation()));\r\n            return;\r\n        }\r\n\r\n        // [Params(singleValue)]\r\n        if (actualValues.Length == 1)\r\n        {\r\n            context.ReportDiagnostic(Diagnostic.Create(UnnecessarySingleValuePassedToAttributeRule, AnalyzerHelper.GetAttributeParamsArgumentExpression(attr, 0).GetLocation()));\r\n        }\r\n\r\n        // [Params(multiple, values)]\r\n        for (int i = 0; i < actualValues.Length; i++)\r\n        {\r\n            AnalyzeAssignableValueType(\r\n                actualValues[i],\r\n                AnalyzerHelper.GetAttributeParamsArgumentExpression(attr, i),\r\n                fieldOrPropertyType\r\n            );\r\n        }\r\n\r\n        void AnalyzeAssignableValueType(TypedConstant value, ExpressionSyntax expression, ITypeSymbol parameterType)\r\n        {\r\n            // Don't analyze unknown types.\r\n            if (value.Kind == TypedConstantKind.Error || parameterType is IErrorTypeSymbol)\r\n            {\r\n                return;\r\n            }\r\n            if (!AnalyzerHelper.IsAssignable(value, expression, parameterType, context.Compilation))\r\n            {\r\n                context.ReportDiagnostic(Diagnostic.Create(MustHaveMatchingValueTypeRule,\r\n                    expression.GetLocation(),\r\n                    expression.ToString(),\r\n                    parameterType.ToDisplayString(),\r\n                    value.IsNull ? \"null\" : value.Type!.ToDisplayString())\r\n                );\r\n            }\r\n        }\r\n    }\r\n\r\n    private static INamedTypeSymbol? GetParamsAttributeTypeSymbol(Compilation compilation)\r\n        => compilation.GetTypeByMetadataName(\"BenchmarkDotNet.Attributes.ParamsAttribute\");\r\n}"
  },
  {
    "path": "src/BenchmarkDotNet.Analyzers/BenchmarkDotNet.Analyzers.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\r\n  <Import Project=\"..\\..\\build\\common.props\" />\r\n  <PropertyGroup>\r\n    <TargetFramework>netstandard2.0</TargetFramework>\r\n    <IsPackable>false</IsPackable>\r\n    <!-- Avoid ID conflicts with the package project. -->\r\n    <PackageId>BenchmarkDotNet.Analyzers</PackageId>\r\n    <EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules>\r\n    <NoWarn>$(NoWarn);CS1591</NoWarn>\r\n    <!-- Default version used by local builds. This is overridden by the build script. -->\r\n    <MccVersion>5.0</MccVersion>\r\n    <OutputPath>bin\\$(Configuration)\\roslyn$(MccVersion)\\cs</OutputPath>\r\n    <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>\r\n    <DefineConstants Condition=\"'$(MccVersion)' >= '3.8'\">$(DefineConstants);CODE_ANALYSIS_3_8</DefineConstants>\r\n    <DefineConstants Condition=\"'$(MccVersion)' >= '4.8'\">$(DefineConstants);CODE_ANALYSIS_4_8</DefineConstants>\r\n    <DefineConstants Condition=\"'$(MccVersion)' >= '5.0'\">$(DefineConstants);CODE_ANALYSIS_5_0</DefineConstants>\r\n    <!-- Formatting in AnalyzerReleases.Unshipped.md -->\r\n    <NoWarn>$(NoWarn);RS2007</NoWarn>\r\n    <!-- Suppress false positives due to a bug in v3.8.0. -->\r\n    <NoWarn Condition=\"'$(MccVersion)' == '3.8'\">$(NoWarn);RS2002</NoWarn>\r\n    <Nullable>enable</Nullable>\r\n  </PropertyGroup>\r\n  <ItemGroup>\r\n    <!-- We multi-target for different compiler versions. https://github.com/dotnet/roslyn/discussions/81256#discussioncomment-14975130, https://github.com/dotnet/roslyn/blob/main/docs/wiki/NuGet-packages.md#versioning -->\r\n    <!-- C# 7.3 (min version we support) -->\r\n    <PackageReference Include=\"Microsoft.CodeAnalysis.CSharp\" Version=\"[2.8.0]\" Condition=\"'$(MccVersion)' == '2.8'\" />\r\n    <!-- C# 9 -->\r\n    <PackageReference Include=\"Microsoft.CodeAnalysis.CSharp\" Version=\"[3.8.0]\" Condition=\"'$(MccVersion)' == '3.8'\" />\r\n    <!-- C# 12 -->\r\n    <PackageReference Include=\"Microsoft.CodeAnalysis.CSharp\" Version=\"[4.8.0]\" Condition=\"'$(MccVersion)' == '4.8'\" />\r\n    <!-- C# 14 -->\r\n    <PackageReference Include=\"Microsoft.CodeAnalysis.CSharp\" Version=\"[5.0.0,)\" Condition=\"'$(MccVersion)' == '5.0'\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <AdditionalFiles Include=\"AnalyzerReleases.Shipped.md\" />\r\n    <AdditionalFiles Include=\"AnalyzerReleases.Unshipped.md\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <Compile Update=\"BenchmarkDotNetAnalyzerResources.Designer.cs\">\r\n      <DesignTime>True</DesignTime>\r\n      <AutoGen>True</AutoGen>\r\n      <DependentUpon>BenchmarkDotNetAnalyzerResources.resx</DependentUpon>\r\n    </Compile>\r\n    <EmbeddedResource Update=\"BenchmarkDotNetAnalyzerResources.resx\">\r\n      <Generator>ResXFileCodeGenerator</Generator>\r\n      <LastGenOutput>BenchmarkDotNetAnalyzerResources.Designer.cs</LastGenOutput>\r\n    </EmbeddedResource>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <AssemblyAttribute Include=\"System.Runtime.CompilerServices.InternalsVisibleToAttribute\">\r\n      <_Parameter1>BenchmarkDotNet.Analyzers.Tests,PublicKey=00240000048000009400000006020000002400005253413100040000010001002970bbdfca4d129fc74b4845b239973f1b183684f0d7db5e1de7e085917e3656cf94884803cb800d85d5aae5838fb3f8fd1f2829e8208c4f087afcfe970bce44037ba30a66749cd5514b410ca8a35e9c7d6eb86975853c834c9ad25051537f9a05a0c540c5d84f2c7b32ab01619d84367fd424797ba3242f08b0e6ae75f66dad</_Parameter1>\r\n    </AssemblyAttribute>\r\n  </ItemGroup>\r\n  <Import Project=\"..\\..\\build\\common.targets\" />\r\n</Project>\r\n"
  },
  {
    "path": "src/BenchmarkDotNet.Analyzers/BenchmarkDotNetAnalyzerResources.Designer.cs",
    "content": "﻿//------------------------------------------------------------------------------\r\n// <auto-generated>\r\n//     This code was generated by a tool.\r\n//     Runtime Version:4.0.30319.42000\r\n//\r\n//     Changes to this file may cause incorrect behavior and will be lost if\r\n//     the code is regenerated.\r\n// </auto-generated>\r\n//------------------------------------------------------------------------------\r\n\r\nnamespace BenchmarkDotNet.Analyzers {\r\n    using System;\r\n    \r\n    \r\n    /// <summary>\r\n    ///   A strongly-typed resource class, for looking up localized strings, etc.\r\n    /// </summary>\r\n    // This class was auto-generated by the StronglyTypedResourceBuilder\r\n    // class via a tool like ResGen or Visual Studio.\r\n    // To add or remove a member, edit your .ResX file then rerun ResGen\r\n    // with the /str option, or rebuild your VS project.\r\n    [global::System.CodeDom.Compiler.GeneratedCodeAttribute(\"System.Resources.Tools.StronglyTypedResourceBuilder\", \"17.0.0.0\")]\r\n    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]\r\n    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]\r\n    internal class BenchmarkDotNetAnalyzerResources {\r\n        \r\n        private static global::System.Resources.ResourceManager resourceMan;\r\n        \r\n        private static global::System.Globalization.CultureInfo resourceCulture;\r\n        \r\n        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"Microsoft.Performance\", \"CA1811:AvoidUncalledPrivateCode\")]\r\n        internal BenchmarkDotNetAnalyzerResources() {\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Returns the cached ResourceManager instance used by this class.\r\n        /// </summary>\r\n        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]\r\n        internal static global::System.Resources.ResourceManager ResourceManager {\r\n            get {\r\n                if (object.ReferenceEquals(resourceMan, null)) {\r\n                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager(\"BenchmarkDotNet.Analyzers.BenchmarkDotNetAnalyzerResources\", typeof(BenchmarkDotNetAnalyzerResources).Assembly);\r\n                    resourceMan = temp;\r\n                }\r\n                return resourceMan;\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Overrides the current thread's CurrentUICulture property for all\r\n        ///   resource lookups using this strongly typed resource class.\r\n        /// </summary>\r\n        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]\r\n        internal static global::System.Globalization.CultureInfo Culture {\r\n            get {\r\n                return resourceCulture;\r\n            }\r\n            set {\r\n                resourceCulture = value;\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to The number of values passed to an [Arguments] attribute must match the number of parameters declared in the targeted benchmark method.\r\n        /// </summary>\r\n        internal static string Attributes_ArgumentsAttribute_MustHaveMatchingValueCount_Description {\r\n            get {\r\n                return ResourceManager.GetString(\"Attributes_ArgumentsAttribute_MustHaveMatchingValueCount_Description\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to Expected {0} value{1} as declared by the benchmark method &apos;{2}&apos;, but found {3}. Update the attribute usage or method to match..\r\n        /// </summary>\r\n        internal static string Attributes_ArgumentsAttribute_MustHaveMatchingValueCount_MessageFormat {\r\n            get {\r\n                return ResourceManager.GetString(\"Attributes_ArgumentsAttribute_MustHaveMatchingValueCount_MessageFormat\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to Number of values passed to an [Arguments] attribute must match the number of parameters declared in the targeted benchmark method.\r\n        /// </summary>\r\n        internal static string Attributes_ArgumentsAttribute_MustHaveMatchingValueCount_Title {\r\n            get {\r\n                return ResourceManager.GetString(\"Attributes_ArgumentsAttribute_MustHaveMatchingValueCount_Title\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to The values passed to an [Arguments] attribute must match the parameters declared in the targeted benchmark method in both type (or be implicitly convertible to) and order.\r\n        /// </summary>\r\n        internal static string Attributes_ArgumentsAttribute_MustHaveMatchingValueType_Description {\r\n            get {\r\n                return ResourceManager.GetString(\"Attributes_ArgumentsAttribute_MustHaveMatchingValueType_Description\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to Unexpected type for argument value &apos;{0}&apos;. Expected &apos;{1}&apos; but found &apos;{2}&apos;..\r\n        /// </summary>\r\n        internal static string Attributes_ArgumentsAttribute_MustHaveMatchingValueType_MessageFormat {\r\n            get {\r\n                return ResourceManager.GetString(\"Attributes_ArgumentsAttribute_MustHaveMatchingValueType_MessageFormat\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to Values passed to an [Arguments] attribute must match exactly the parameters declared in the targeted benchmark method in both type (or be implicitly convertible to) and order.\r\n        /// </summary>\r\n        internal static string Attributes_ArgumentsAttribute_MustHaveMatchingValueType_Title {\r\n            get {\r\n                return ResourceManager.GetString(\"Attributes_ArgumentsAttribute_MustHaveMatchingValueType_Title\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to The [Arguments(Source)] attribute can only be used on methods annotated with the [Benchmark] attribute.\r\n        /// </summary>\r\n        internal static string Attributes_ArgumentsAttribute_RequiresBenchmarkAttribute_MessageFormat {\r\n            get {\r\n                return ResourceManager.GetString(\"Attributes_ArgumentsAttribute_RequiresBenchmarkAttribute_MessageFormat\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to [Arguments(Source)] attribute can only be used on methods annotated with the [Benchmark] attribute.\r\n        /// </summary>\r\n        internal static string Attributes_ArgumentsAttribute_RequiresBenchmarkAttribute_Title {\r\n            get {\r\n                return ResourceManager.GetString(\"Attributes_ArgumentsAttribute_RequiresBenchmarkAttribute_Title\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to The values passed to an [Arguments] must have parameter(s).\r\n        /// </summary>\r\n        internal static string Attributes_ArgumentsAttribute_RequiresParameters_Description {\r\n            get {\r\n                return ResourceManager.GetString(\"Attributes_ArgumentsAttribute_RequiresParameters_Description\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to Method {0} has no parameters.\r\n        /// </summary>\r\n        internal static string Attributes_ArgumentsAttribute_RequiresParameters_MessageFormat {\r\n            get {\r\n                return ResourceManager.GetString(\"Attributes_ArgumentsAttribute_RequiresParameters_MessageFormat\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to [Arguments(Source)] attribute requires at least 1 parameter.\r\n        /// </summary>\r\n        internal static string Attributes_ArgumentsAttribute_RequiresParameters_Title {\r\n            get {\r\n                return ResourceManager.GetString(\"Attributes_ArgumentsAttribute_RequiresParameters_Title\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to This method declares one or more parameters but is not annotated with either an [ArgumentsSource] attribute or one or more [Arguments] attributes. To ensure correct argument binding, methods with parameters must explicitly be annotated with an [ArgumentsSource] attribute or one or more [Arguments] attributes.\r\n        ///Either add the [ArgumentsSource] or [Arguments] attribute(s) or remove the parameters..\r\n        /// </summary>\r\n        internal static string Attributes_GeneralArgumentAttributes_MethodWithoutAttributeMustHaveNoParameters_Description {\r\n            get {\r\n                return ResourceManager.GetString(\"Attributes_GeneralArgumentAttributes_MethodWithoutAttributeMustHaveNoParameters_D\" +\r\n                        \"escription\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to Benchmark method &apos;{0}&apos; without an [ArgumentsSource] or [Arguments] attribute(s) cannot declare parameters.\r\n        /// </summary>\r\n        internal static string Attributes_GeneralArgumentAttributes_MethodWithoutAttributeMustHaveNoParameters_MessageFormat {\r\n            get {\r\n                return ResourceManager.GetString(\"Attributes_GeneralArgumentAttributes_MethodWithoutAttributeMustHaveNoParameters_M\" +\r\n                        \"essageFormat\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to Benchmark methods without an [ArgumentsSource] or [Arguments] attribute(s) cannot declare parameters.\r\n        /// </summary>\r\n        internal static string Attributes_GeneralArgumentAttributes_MethodWithoutAttributeMustHaveNoParameters_Title {\r\n            get {\r\n                return ResourceManager.GetString(\"Attributes_GeneralArgumentAttributes_MethodWithoutAttributeMustHaveNoParameters_T\" +\r\n                        \"itle\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to A field annotated with a parameter attribute must be public.\r\n        /// </summary>\r\n        internal static string Attributes_GeneralParameterAttributes_FieldMustBePublic_Description {\r\n            get {\r\n                return ResourceManager.GetString(\"Attributes_GeneralParameterAttributes_FieldMustBePublic_Description\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to Field &apos;{0}&apos; annotated with [{1}] must be public.\r\n        /// </summary>\r\n        internal static string Attributes_GeneralParameterAttributes_FieldMustBePublic_MessageFormat {\r\n            get {\r\n                return ResourceManager.GetString(\"Attributes_GeneralParameterAttributes_FieldMustBePublic_MessageFormat\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to Fields annotated with a parameter attribute must be public.\r\n        /// </summary>\r\n        internal static string Attributes_GeneralParameterAttributes_FieldMustBePublic_Title {\r\n            get {\r\n                return ResourceManager.GetString(\"Attributes_GeneralParameterAttributes_FieldMustBePublic_Title\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to Parameter attributes are mutually exclusive; only one of the attributes [Params], [ParamsSource] or [ParamsAllValues] can be applied to a field at any one time.\r\n        /// </summary>\r\n        internal static string Attributes_GeneralParameterAttributes_MutuallyExclusiveOnField_Description {\r\n            get {\r\n                return ResourceManager.GetString(\"Attributes_GeneralParameterAttributes_MutuallyExclusiveOnField_Description\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to Duplicate parameter attribute on field &apos;{0}&apos;.\r\n        /// </summary>\r\n        internal static string Attributes_GeneralParameterAttributes_MutuallyExclusiveOnField_MessageFormat {\r\n            get {\r\n                return ResourceManager.GetString(\"Attributes_GeneralParameterAttributes_MutuallyExclusiveOnField_MessageFormat\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to Only one parameter attribute can be applied to a field.\r\n        /// </summary>\r\n        internal static string Attributes_GeneralParameterAttributes_MutuallyExclusiveOnField_Title {\r\n            get {\r\n                return ResourceManager.GetString(\"Attributes_GeneralParameterAttributes_MutuallyExclusiveOnField_Title\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to Parameter attributes are mutually exclusive; only one of the attributes [Params], [ParamsSource] or [ParamsAllValues] can be applied to a property at any one time.\r\n        /// </summary>\r\n        internal static string Attributes_GeneralParameterAttributes_MutuallyExclusiveOnProperty_Description {\r\n            get {\r\n                return ResourceManager.GetString(\"Attributes_GeneralParameterAttributes_MutuallyExclusiveOnProperty_Description\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to Duplicate parameter attribute on property &apos;{0}&apos;.\r\n        /// </summary>\r\n        internal static string Attributes_GeneralParameterAttributes_MutuallyExclusiveOnProperty_MessageFormat {\r\n            get {\r\n                return ResourceManager.GetString(\"Attributes_GeneralParameterAttributes_MutuallyExclusiveOnProperty_MessageFormat\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to Only one parameter attribute can be applied to a property.\r\n        /// </summary>\r\n        internal static string Attributes_GeneralParameterAttributes_MutuallyExclusiveOnProperty_Title {\r\n            get {\r\n                return ResourceManager.GetString(\"Attributes_GeneralParameterAttributes_MutuallyExclusiveOnProperty_Title\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to Parameter attribute [{0}] is not valid on constants. It is only valid on non-constant field declarations..\r\n        /// </summary>\r\n        internal static string Attributes_GeneralParameterAttributes_NotValidOnConstantField_MessageFormat {\r\n            get {\r\n                return ResourceManager.GetString(\"Attributes_GeneralParameterAttributes_NotValidOnConstantField_MessageFormat\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to Parameter attributes are not valid on constant field declarations.\r\n        /// </summary>\r\n        internal static string Attributes_GeneralParameterAttributes_NotValidOnConstantField_Title {\r\n            get {\r\n                return ResourceManager.GetString(\"Attributes_GeneralParameterAttributes_NotValidOnConstantField_Title\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to Parameter attributes are not valid on fields with a readonly modifier.\r\n        /// </summary>\r\n        internal static string Attributes_GeneralParameterAttributes_NotValidOnReadonlyField_Description {\r\n            get {\r\n                return ResourceManager.GetString(\"Attributes_GeneralParameterAttributes_NotValidOnReadonlyField_Description\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to Modifier &apos;readonly&apos; is not valid on field &apos;{0}&apos; annotated with parameter attribute [{1}].\r\n        /// </summary>\r\n        internal static string Attributes_GeneralParameterAttributes_NotValidOnReadonlyField_MessageFormat {\r\n            get {\r\n                return ResourceManager.GetString(\"Attributes_GeneralParameterAttributes_NotValidOnReadonlyField_MessageFormat\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to Fields annotated with a parameter attribute cannot be read-only.\r\n        /// </summary>\r\n        internal static string Attributes_GeneralParameterAttributes_NotValidOnReadonlyField_Title {\r\n            get {\r\n                return ResourceManager.GetString(\"Attributes_GeneralParameterAttributes_NotValidOnReadonlyField_Title\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to A property annotated with a parameter attribute must have a public, assignable setter i.e. { set; }.\r\n        /// </summary>\r\n        internal static string Attributes_GeneralParameterAttributes_PropertyCannotBeInitOnly_Description {\r\n            get {\r\n                return ResourceManager.GetString(\"Attributes_GeneralParameterAttributes_PropertyCannotBeInitOnly_Description\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to Property &apos;{0}&apos; annotated with [{1}] cannot be init-only.\r\n        /// </summary>\r\n        internal static string Attributes_GeneralParameterAttributes_PropertyCannotBeInitOnly_MessageFormat {\r\n            get {\r\n                return ResourceManager.GetString(\"Attributes_GeneralParameterAttributes_PropertyCannotBeInitOnly_MessageFormat\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to Properties annotated with a parameter attribute cannot have an init-only setter.\r\n        /// </summary>\r\n        internal static string Attributes_GeneralParameterAttributes_PropertyCannotBeInitOnly_Title {\r\n            get {\r\n                return ResourceManager.GetString(\"Attributes_GeneralParameterAttributes_PropertyCannotBeInitOnly_Title\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to A property annotated with a parameter attribute must be public.\r\n        /// </summary>\r\n        internal static string Attributes_GeneralParameterAttributes_PropertyMustBePublic_Description {\r\n            get {\r\n                return ResourceManager.GetString(\"Attributes_GeneralParameterAttributes_PropertyMustBePublic_Description\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to Property &apos;{0}&apos; annotated with [{1}] must be public.\r\n        /// </summary>\r\n        internal static string Attributes_GeneralParameterAttributes_PropertyMustBePublic_MessageFormat {\r\n            get {\r\n                return ResourceManager.GetString(\"Attributes_GeneralParameterAttributes_PropertyMustBePublic_MessageFormat\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to Properties annotated with a parameter attribute must be public.\r\n        /// </summary>\r\n        internal static string Attributes_GeneralParameterAttributes_PropertyMustBePublic_Title {\r\n            get {\r\n                return ResourceManager.GetString(\"Attributes_GeneralParameterAttributes_PropertyMustBePublic_Title\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to A property annotated with a parameter attribute must have a public setter; make sure that the access modifier of the setter is empty and that the property is not an auto-property or an expression-bodied property..\r\n        /// </summary>\r\n        internal static string Attributes_GeneralParameterAttributes_PropertyMustHavePublicSetter_Description {\r\n            get {\r\n                return ResourceManager.GetString(\"Attributes_GeneralParameterAttributes_PropertyMustHavePublicSetter_Description\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to Property &apos;{0}&apos; annotated with [{1}] must have a public setter.\r\n        /// </summary>\r\n        internal static string Attributes_GeneralParameterAttributes_PropertyMustHavePublicSetter_MessageFormat {\r\n            get {\r\n                return ResourceManager.GetString(\"Attributes_GeneralParameterAttributes_PropertyMustHavePublicSetter_MessageFormat\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to Properties annotated with a parameter attribute must have a public setter.\r\n        /// </summary>\r\n        internal static string Attributes_GeneralParameterAttributes_PropertyMustHavePublicSetter_Title {\r\n            get {\r\n                return ResourceManager.GetString(\"Attributes_GeneralParameterAttributes_PropertyMustHavePublicSetter_Title\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to The [ParamsAllValues] attribute cannot be applied to a field or property of an enum type marked with the [Flags] attribute. Use this attribute only with non-flags enum types, as [Flags] enums support bitwise combinations that cannot be exhaustively enumerated..\r\n        /// </summary>\r\n        internal static string Attributes_ParamsAllValuesAttribute_NotAllowedOnFlagsEnumPropertyOrFieldType_Description {\r\n            get {\r\n                return ResourceManager.GetString(\"Attributes_ParamsAllValuesAttribute_NotAllowedOnFlagsEnumPropertyOrFieldType_Desc\" +\r\n                        \"ription\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to Field or property enum type &apos;{0}&apos; is marked with [Flags] and cannot be used with this attribute.\r\n        /// </summary>\r\n        internal static string Attributes_ParamsAllValuesAttribute_NotAllowedOnFlagsEnumPropertyOrFieldType_MessageFormat {\r\n            get {\r\n                return ResourceManager.GetString(\"Attributes_ParamsAllValuesAttribute_NotAllowedOnFlagsEnumPropertyOrFieldType_Mess\" +\r\n                        \"ageFormat\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to The [ParamsAllValues] attribute cannot be applied to fields or properties of enum types marked with [Flags].\r\n        /// </summary>\r\n        internal static string Attributes_ParamsAllValuesAttribute_NotAllowedOnFlagsEnumPropertyOrFieldType_Title {\r\n            get {\r\n                return ResourceManager.GetString(\"Attributes_ParamsAllValuesAttribute_NotAllowedOnFlagsEnumPropertyOrFieldType_Titl\" +\r\n                        \"e\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to The [ParamsAllValues] attribute can only be applied to a field or property of enum or bool type (or nullable of these types).\r\n        /// </summary>\r\n        internal static string Attributes_ParamsAllValuesAttribute_PropertyOrFieldTypeMustBeEnumOrBool_MessageFormat {\r\n            get {\r\n                return ResourceManager.GetString(\"Attributes_ParamsAllValuesAttribute_PropertyOrFieldTypeMustBeEnumOrBool_MessageFo\" +\r\n                        \"rmat\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to The [ParamsAllValues] attribute is only valid on fields or properties of enum or bool type and nullable type for another allowed type.\r\n        /// </summary>\r\n        internal static string Attributes_ParamsAllValuesAttribute_PropertyOrFieldTypeMustBeEnumOrBool_Title {\r\n            get {\r\n                return ResourceManager.GetString(\"Attributes_ParamsAllValuesAttribute_PropertyOrFieldTypeMustBeEnumOrBool_Title\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to The type of each value provided to the [Params] attribute must match the type of (or be implicitly convertible to) the field or property it is applied to.\r\n        /// </summary>\r\n        internal static string Attributes_ParamsAttribute_MustHaveMatchingValueType_Description {\r\n            get {\r\n                return ResourceManager.GetString(\"Attributes_ParamsAttribute_MustHaveMatchingValueType_Description\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to Unexpected type for parameter value &apos;{0}&apos;. Expected &apos;{1}&apos; but found &apos;{2}&apos;..\r\n        /// </summary>\r\n        internal static string Attributes_ParamsAttribute_MustHaveMatchingValueType_MessageFormat {\r\n            get {\r\n                return ResourceManager.GetString(\"Attributes_ParamsAttribute_MustHaveMatchingValueType_MessageFormat\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to Type of all value(s) passed to the [Params] attribute must match the type of (or be implicitly convertible to) the annotated field or property.\r\n        /// </summary>\r\n        internal static string Attributes_ParamsAttribute_MustHaveMatchingValueType_Title {\r\n            get {\r\n                return ResourceManager.GetString(\"Attributes_ParamsAttribute_MustHaveMatchingValueType_Title\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to The [Params] attribute requires at least one value. No values were provided, or an empty array was specified..\r\n        /// </summary>\r\n        internal static string Attributes_ParamsAttribute_MustHaveValues_MessageFormat {\r\n            get {\r\n                return ResourceManager.GetString(\"Attributes_ParamsAttribute_MustHaveValues_MessageFormat\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to The [Params] attribute must include at least one value.\r\n        /// </summary>\r\n        internal static string Attributes_ParamsAttribute_MustHaveValues_Title {\r\n            get {\r\n                return ResourceManager.GetString(\"Attributes_ParamsAttribute_MustHaveValues_Title\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to Providing a single value to the [Params] attribute is unnecessary. This attribute is only useful when provided two or more values..\r\n        /// </summary>\r\n        internal static string Attributes_ParamsAttribute_UnnecessarySingleValuePassedToAttribute_MessageFormat {\r\n            get {\r\n                return ResourceManager.GetString(\"Attributes_ParamsAttribute_UnnecessarySingleValuePassedToAttribute_MessageFormat\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to Unnecessary single value passed to [Params] attribute.\r\n        /// </summary>\r\n        internal static string Attributes_ParamsAttribute_UnnecessarySingleValuePassedToAttribute_Title {\r\n            get {\r\n                return ResourceManager.GetString(\"Attributes_ParamsAttribute_UnnecessarySingleValuePassedToAttribute_Title\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to ParamsSource references a write-only property (a property with only a setter and no getter). Write-only properties cannot be read at runtime and will cause a NullReferenceException. Use a property with a getter or a method instead.\r\n        /// </summary>\r\n        internal static string Attributes_ParamsSourceAttribute_CannotUseWriteOnlyProperty_Description {\r\n            get {\r\n                return ResourceManager.GetString(\"Attributes_ParamsSourceAttribute_CannotUseWriteOnlyProperty_Description\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to ParamsSource cannot reference write-only property &apos;{0}&apos;. Write-only properties cannot be read and will cause a runtime error.\r\n        /// </summary>\r\n        internal static string Attributes_ParamsSourceAttribute_CannotUseWriteOnlyProperty_MessageFormat {\r\n            get {\r\n                return ResourceManager.GetString(\"Attributes_ParamsSourceAttribute_CannotUseWriteOnlyProperty_MessageFormat\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to ParamsSource cannot reference a write-only property.\r\n        /// </summary>\r\n        internal static string Attributes_ParamsSourceAttribute_CannotUseWriteOnlyProperty_Title {\r\n            get {\r\n                return ResourceManager.GetString(\"Attributes_ParamsSourceAttribute_CannotUseWriteOnlyProperty_Title\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to A generic benchmark class referenced in the BenchmarkRunner.Run method must be annotated with at least one [GenericTypeArguments] attribute.\r\n        /// </summary>\r\n        internal static string BenchmarkRunner_Run_GenericTypeArgumentClassMustBeAnnotatedWithAGenericTypeArgumentsAttribute_Description {\r\n            get {\r\n                return ResourceManager.GetString(\"BenchmarkRunner_Run_GenericTypeArgumentClassMustBeAnnotatedWithAGenericTypeArgume\" +\r\n                        \"ntsAttribute_Description\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to Referenced generic benchmark class &apos;{0}&apos; has no [GenericTypeArguments] attribute(s).\r\n        /// </summary>\r\n        internal static string BenchmarkRunner_Run_GenericTypeArgumentClassMustBeAnnotatedWithAGenericTypeArgumentsAttribute_MessageFormat {\r\n            get {\r\n                return ResourceManager.GetString(\"BenchmarkRunner_Run_GenericTypeArgumentClassMustBeAnnotatedWithAGenericTypeArgume\" +\r\n                        \"ntsAttribute_MessageFormat\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to Generic benchmark classes must be annotated with at least one [GenericTypeArguments] attribute.\r\n        /// </summary>\r\n        internal static string BenchmarkRunner_Run_GenericTypeArgumentClassMustBeAnnotatedWithAGenericTypeArgumentsAttribute_Title {\r\n            get {\r\n                return ResourceManager.GetString(\"BenchmarkRunner_Run_GenericTypeArgumentClassMustBeAnnotatedWithAGenericTypeArgume\" +\r\n                        \"ntsAttribute_Title\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to The referenced benchmark class (or any of its inherited classes) must have at least one method annotated with the [Benchmark] attribute.\r\n        /// </summary>\r\n        internal static string BenchmarkRunner_Run_TypeArgumentClassMissingBenchmarkMethods_Description {\r\n            get {\r\n                return ResourceManager.GetString(\"BenchmarkRunner_Run_TypeArgumentClassMissingBenchmarkMethods_Description\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to Intended benchmark class &apos;{0}&apos; (or any of its ancestors) has no method(s) annotated with the [Benchmark] attribute.\r\n        /// </summary>\r\n        internal static string BenchmarkRunner_Run_TypeArgumentClassMissingBenchmarkMethods_MessageFormat {\r\n            get {\r\n                return ResourceManager.GetString(\"BenchmarkRunner_Run_TypeArgumentClassMissingBenchmarkMethods_MessageFormat\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to Benchmark class (or any of its ancestors) has no annotated method(s).\r\n        /// </summary>\r\n        internal static string BenchmarkRunner_Run_TypeArgumentClassMissingBenchmarkMethods_Title {\r\n            get {\r\n                return ResourceManager.GetString(\"BenchmarkRunner_Run_TypeArgumentClassMissingBenchmarkMethods_Title\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to A benchmark class referenced in the BenchmarkRunner.Run method must be non-abstract.\r\n        /// </summary>\r\n        internal static string BenchmarkRunner_Run_TypeArgumentClassMustBeNonAbstract_Description {\r\n            get {\r\n                return ResourceManager.GetString(\"BenchmarkRunner_Run_TypeArgumentClassMustBeNonAbstract_Description\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to Referenced benchmark class &apos;{0}&apos; cannot be abstract.\r\n        /// </summary>\r\n        internal static string BenchmarkRunner_Run_TypeArgumentClassMustBeNonAbstract_MessageFormat {\r\n            get {\r\n                return ResourceManager.GetString(\"BenchmarkRunner_Run_TypeArgumentClassMustBeNonAbstract_MessageFormat\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to Benchmark classes must be non-abstract.\r\n        /// </summary>\r\n        internal static string BenchmarkRunner_Run_TypeArgumentClassMustBeNonAbstract_Title {\r\n            get {\r\n                return ResourceManager.GetString(\"BenchmarkRunner_Run_TypeArgumentClassMustBeNonAbstract_Title\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to Referenced benchmark class &apos;{0}&apos; must be public.\r\n        /// </summary>\r\n        internal static string BenchmarkRunner_Run_TypeArgumentClassMustBePublic_MessageFormat {\r\n            get {\r\n                return ResourceManager.GetString(\"BenchmarkRunner_Run_TypeArgumentClassMustBePublic_MessageFormat\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to Benchmark classes must be public.\r\n        /// </summary>\r\n        internal static string BenchmarkRunner_Run_TypeArgumentClassMustBePublic_Title {\r\n            get {\r\n                return ResourceManager.GetString(\"BenchmarkRunner_Run_TypeArgumentClassMustBePublic_Title\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to A benchmark class referenced in the BenchmarkRunner.Run method must be unsealed.\r\n        /// </summary>\r\n        internal static string BenchmarkRunner_Run_TypeArgumentClassMustBeUnsealed_Description {\r\n            get {\r\n                return ResourceManager.GetString(\"BenchmarkRunner_Run_TypeArgumentClassMustBeUnsealed_Description\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to Referenced benchmark class &apos;{0}&apos; is sealed.\r\n        /// </summary>\r\n        internal static string BenchmarkRunner_Run_TypeArgumentClassMustBeUnsealed_MessageFormat {\r\n            get {\r\n                return ResourceManager.GetString(\"BenchmarkRunner_Run_TypeArgumentClassMustBeUnsealed_MessageFormat\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to Benchmark classes must be unsealed.\r\n        /// </summary>\r\n        internal static string BenchmarkRunner_Run_TypeArgumentClassMustBeUnsealed_Title {\r\n            get {\r\n                return ResourceManager.GetString(\"BenchmarkRunner_Run_TypeArgumentClassMustBeUnsealed_Title\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to A benchmark class must be an instance class.\r\n        /// </summary>\r\n        internal static string General_BenchmarkClass_ClassMustBeNonStatic_Description {\r\n            get {\r\n                return ResourceManager.GetString(\"General_BenchmarkClass_ClassMustBeNonStatic_Description\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to Benchmark class &apos;{0}&apos; cannot be static.\r\n        /// </summary>\r\n        internal static string General_BenchmarkClass_ClassMustBeNonStatic_MessageFormat {\r\n            get {\r\n                return ResourceManager.GetString(\"General_BenchmarkClass_ClassMustBeNonStatic_MessageFormat\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to Benchmark classes must be non-static.\r\n        /// </summary>\r\n        internal static string General_BenchmarkClass_ClassMustBeNonStatic_Title {\r\n            get {\r\n                return ResourceManager.GetString(\"General_BenchmarkClass_ClassMustBeNonStatic_Title\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to A benchmark class annotated with a [GenericTypeArguments] attribute must be generic, having between one to three type parameters.\r\n        /// </summary>\r\n        internal static string General_BenchmarkClass_ClassWithGenericTypeArgumentsAttributeMustBeGeneric_Description {\r\n            get {\r\n                return ResourceManager.GetString(\"General_BenchmarkClass_ClassWithGenericTypeArgumentsAttributeMustBeGeneric_Descri\" +\r\n                        \"ption\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to Attribute [GenericTypeArguments] can only be applied to a generic class.\r\n        /// </summary>\r\n        internal static string General_BenchmarkClass_ClassWithGenericTypeArgumentsAttributeMustBeGeneric_MessageFormat {\r\n            get {\r\n                return ResourceManager.GetString(\"General_BenchmarkClass_ClassWithGenericTypeArgumentsAttributeMustBeGeneric_Messag\" +\r\n                        \"eFormat\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to Benchmark classes annotated with a [GenericTypeArguments] attribute must be generic.\r\n        /// </summary>\r\n        internal static string General_BenchmarkClass_ClassWithGenericTypeArgumentsAttributeMustBeGeneric_Title {\r\n            get {\r\n                return ResourceManager.GetString(\"General_BenchmarkClass_ClassWithGenericTypeArgumentsAttributeMustBeGeneric_Title\", resourceCulture);\r\n            }\r\n        }\r\n      \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to The number of type arguments passed to a [GenericTypeArguments] attribute must match the number of type parameters on the targeted benchmark class.\r\n        /// </summary>\r\n        internal static string General_BenchmarkClass_GenericTypeArgumentsAttributeMustHaveMatchingTypeParameterCount_Description {\r\n            get {\r\n                return ResourceManager.GetString(\"General_BenchmarkClass_GenericTypeArgumentsAttributeMustHaveMatchingTypeParameter\" +\r\n                        \"Count_Description\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to Expected {0} type argument{1} as declared on the benchmark class &apos;{2}&apos;, but found {3}. Update the attribute usage or the type parameter list of the class declaration to match..\r\n        /// </summary>\r\n        internal static string General_BenchmarkClass_GenericTypeArgumentsAttributeMustHaveMatchingTypeParameterCount_MessageFormat {\r\n            get {\r\n                return ResourceManager.GetString(\"General_BenchmarkClass_GenericTypeArgumentsAttributeMustHaveMatchingTypeParameter\" +\r\n                        \"Count_MessageFormat\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to Number of type arguments passed to a [GenericTypeArguments] attribute must match the number of type parameters on the targeted benchmark class.\r\n        /// </summary>\r\n        internal static string General_BenchmarkClass_GenericTypeArgumentsAttributeMustHaveMatchingTypeParameterCount_Title {\r\n            get {\r\n                return ResourceManager.GetString(\"General_BenchmarkClass_GenericTypeArgumentsAttributeMustHaveMatchingTypeParameter\" +\r\n                        \"Count_Title\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to A method annotated with the [Benchmark] attribute must be non-generic.\r\n        /// </summary>\r\n        internal static string General_BenchmarkClass_MethodMustBeNonGeneric_Description {\r\n            get {\r\n                return ResourceManager.GetString(\"General_BenchmarkClass_MethodMustBeNonGeneric_Description\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to The benchmark method &apos;{0}&apos; must be non-generic.\r\n        /// </summary>\r\n        internal static string General_BenchmarkClass_MethodMustBeNonGeneric_MessageFormat {\r\n            get {\r\n                return ResourceManager.GetString(\"General_BenchmarkClass_MethodMustBeNonGeneric_MessageFormat\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to Benchmark methods must be non-generic.\r\n        /// </summary>\r\n        internal static string General_BenchmarkClass_MethodMustBeNonGeneric_Title {\r\n            get {\r\n                return ResourceManager.GetString(\"General_BenchmarkClass_MethodMustBeNonGeneric_Title\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to A method annotated with the [Benchmark] attribute must be public.\r\n        /// </summary>\r\n        internal static string General_BenchmarkClass_MethodMustBePublic_Description {\r\n            get {\r\n                return ResourceManager.GetString(\"General_BenchmarkClass_MethodMustBePublic_Description\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to The benchmark method &apos;{0}&apos; must be public.\r\n        /// </summary>\r\n        internal static string General_BenchmarkClass_MethodMustBePublic_MessageFormat {\r\n            get {\r\n                return ResourceManager.GetString(\"General_BenchmarkClass_MethodMustBePublic_MessageFormat\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to Benchmark methods must be public.\r\n        /// </summary>\r\n        internal static string General_BenchmarkClass_MethodMustBePublic_Title {\r\n            get {\r\n                return ResourceManager.GetString(\"General_BenchmarkClass_MethodMustBePublic_Title\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to Only one benchmark method can be marked as baseline per class.\r\n        /// </summary>\r\n        internal static string General_BenchmarkClass_OnlyOneMethodCanBeBaseline_MessageFormat {\r\n            get {\r\n                return ResourceManager.GetString(\"General_BenchmarkClass_OnlyOneMethodCanBeBaseline_MessageFormat\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to Only one benchmark method can be baseline per class.\r\n        /// </summary>\r\n        internal static string General_BenchmarkClass_OnlyOneMethodCanBeBaseline_Title {\r\n            get {\r\n                return ResourceManager.GetString(\"General_BenchmarkClass_OnlyOneMethodCanBeBaseline_Title\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to Only one benchmark method can be marked as baseline per class and category.\r\n        /// </summary>\r\n        internal static string General_BenchmarkClass_OnlyOneMethodCanBeBaselinePerCategory_MessageFormat {\r\n            get {\r\n                return ResourceManager.GetString(\"General_BenchmarkClass_OnlyOneMethodCanBeBaselinePerCategory_MessageFormat\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to Only one benchmark method can be baseline per class and category.\r\n        /// </summary>\r\n        internal static string General_BenchmarkClass_OnlyOneMethodCanBeBaselinePerCategory_Title {\r\n            get {\r\n                return ResourceManager.GetString(\"General_BenchmarkClass_OnlyOneMethodCanBeBaselinePerCategory_Title\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to Passing a single null argument creates a null params array. Use multiple arguments (e.g., null, &quot;SomeCategory&quot;, ...) or a non-null value instead..\r\n        /// </summary>\r\n        internal static string General_BenchmarkClass_SingleNullArgumentToBenchmarkCategoryAttributeNotAllowed_MessageFormat {\r\n            get {\r\n                return ResourceManager.GetString(\"General_BenchmarkClass_SingleNullArgumentToBenchmarkCategoryAttributeNotAllowed_M\" +\r\n                        \"essageFormat\", resourceCulture);\r\n            }\r\n        }\r\n        \r\n        /// <summary>\r\n        ///   Looks up a localized string similar to Single null argument to the [BenchmarkCategory] attribute results in unintended null array.\r\n        /// </summary>\r\n        internal static string General_BenchmarkClass_SingleNullArgumentToBenchmarkCategoryAttributeNotAllowed_Title {\r\n            get {\r\n                return ResourceManager.GetString(\"General_BenchmarkClass_SingleNullArgumentToBenchmarkCategoryAttributeNotAllowed_T\" +\r\n                        \"itle\", resourceCulture);\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/BenchmarkDotNet.Analyzers/BenchmarkDotNetAnalyzerResources.resx",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<root>\r\n  <!-- \r\n    Microsoft ResX Schema \r\n    \r\n    Version 2.0\r\n    \r\n    The primary goals of this format is to allow a simple XML format \r\n    that is mostly human readable. The generation and parsing of the \r\n    various data types are done through the TypeConverter classes \r\n    associated with the data types.\r\n    \r\n    Example:\r\n    \r\n    ... ado.net/XML headers & schema ...\r\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\r\n    <resheader name=\"version\">2.0</resheader>\r\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\r\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\r\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\r\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\r\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\r\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\r\n    </data>\r\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\r\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\r\n        <comment>This is a comment</comment>\r\n    </data>\r\n                \r\n    There are any number of \"resheader\" rows that contain simple \r\n    name/value pairs.\r\n    \r\n    Each data row contains a name, and value. The row also contains a \r\n    type or mimetype. Type corresponds to a .NET class that support \r\n    text/value conversion through the TypeConverter architecture. \r\n    Classes that don't support this are serialized and stored with the \r\n    mimetype set.\r\n    \r\n    The mimetype is used for serialized objects, and tells the \r\n    ResXResourceReader how to depersist the object. This is currently not \r\n    extensible. For a given mimetype the value must be set accordingly:\r\n    \r\n    Note - application/x-microsoft.net.object.binary.base64 is the format \r\n    that the ResXResourceWriter will generate, however the reader can \r\n    read any of the formats listed below.\r\n    \r\n    mimetype: application/x-microsoft.net.object.binary.base64\r\n    value   : The object must be serialized with \r\n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\r\n            : and then encoded with base64 encoding.\r\n    \r\n    mimetype: application/x-microsoft.net.object.soap.base64\r\n    value   : The object must be serialized with \r\n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\r\n            : and then encoded with base64 encoding.\r\n\r\n    mimetype: application/x-microsoft.net.object.bytearray.base64\r\n    value   : The object must be serialized into a byte array \r\n            : using a System.ComponentModel.TypeConverter\r\n            : and then encoded with base64 encoding.\r\n    -->\r\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\r\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\r\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\r\n      <xsd:complexType>\r\n        <xsd:choice maxOccurs=\"unbounded\">\r\n          <xsd:element name=\"metadata\">\r\n            <xsd:complexType>\r\n              <xsd:sequence>\r\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\r\n              </xsd:sequence>\r\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\r\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\r\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\r\n              <xsd:attribute ref=\"xml:space\" />\r\n            </xsd:complexType>\r\n          </xsd:element>\r\n          <xsd:element name=\"assembly\">\r\n            <xsd:complexType>\r\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\r\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\r\n            </xsd:complexType>\r\n          </xsd:element>\r\n          <xsd:element name=\"data\">\r\n            <xsd:complexType>\r\n              <xsd:sequence>\r\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\r\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\r\n              </xsd:sequence>\r\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\r\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\r\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\r\n              <xsd:attribute ref=\"xml:space\" />\r\n            </xsd:complexType>\r\n          </xsd:element>\r\n          <xsd:element name=\"resheader\">\r\n            <xsd:complexType>\r\n              <xsd:sequence>\r\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\r\n              </xsd:sequence>\r\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\r\n            </xsd:complexType>\r\n          </xsd:element>\r\n        </xsd:choice>\r\n      </xsd:complexType>\r\n    </xsd:element>\r\n  </xsd:schema>\r\n  <resheader name=\"resmimetype\">\r\n    <value>text/microsoft-resx</value>\r\n  </resheader>\r\n  <resheader name=\"version\">\r\n    <value>2.0</value>\r\n  </resheader>\r\n  <resheader name=\"reader\">\r\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\r\n  </resheader>\r\n  <resheader name=\"writer\">\r\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\r\n  </resheader>\r\n  <data name=\"BenchmarkRunner_Run_TypeArgumentClassMissingBenchmarkMethods_Description\" xml:space=\"preserve\">\r\n    <value>The referenced benchmark class (or any of its inherited classes) must have at least one method annotated with the [Benchmark] attribute</value>\r\n  </data>\r\n  <data name=\"BenchmarkRunner_Run_TypeArgumentClassMissingBenchmarkMethods_MessageFormat\" xml:space=\"preserve\">\r\n    <value>Intended benchmark class '{0}' (or any of its ancestors) has no method(s) annotated with the [Benchmark] attribute</value>\r\n  </data>\r\n  <data name=\"BenchmarkRunner_Run_TypeArgumentClassMustBeNonAbstract_MessageFormat\" xml:space=\"preserve\">\r\n    <value>Referenced benchmark class '{0}' cannot be abstract</value>\r\n  </data>\r\n  <data name=\"BenchmarkRunner_Run_TypeArgumentClassMissingBenchmarkMethods_Title\" xml:space=\"preserve\">\r\n    <value>Benchmark class (or any of its ancestors) has no annotated method(s)</value>\r\n  </data>\r\n  <data name=\"BenchmarkRunner_Run_TypeArgumentClassMustBeNonAbstract_Title\" xml:space=\"preserve\">\r\n    <value>Benchmark classes must be non-abstract</value>\r\n  </data>\r\n  <data name=\"General_BenchmarkClass_ClassMustBeNonStatic_Description\" xml:space=\"preserve\">\r\n    <value>A benchmark class must be an instance class</value>\r\n  </data>\r\n  <data name=\"General_BenchmarkClass_ClassMustBeNonStatic_MessageFormat\" xml:space=\"preserve\">\r\n    <value>Benchmark class '{0}' cannot be static</value>\r\n  </data>\r\n  <data name=\"BenchmarkRunner_Run_GenericTypeArgumentClassMustBeAnnotatedWithAGenericTypeArgumentsAttribute_MessageFormat\" xml:space=\"preserve\">\r\n    <value>Referenced generic benchmark class '{0}' has no [GenericTypeArguments] attribute(s)</value>\r\n  </data>\r\n  <data name=\"BenchmarkRunner_Run_GenericTypeArgumentClassMustBeAnnotatedWithAGenericTypeArgumentsAttribute_Description\" xml:space=\"preserve\">\r\n    <value>A generic benchmark class referenced in the BenchmarkRunner.Run method must be annotated with at least one [GenericTypeArguments] attribute</value>\r\n  </data>\r\n  <data name=\"General_BenchmarkClass_ClassMustBeNonStatic_Title\" xml:space=\"preserve\">\r\n    <value>Benchmark classes must be non-static</value>\r\n  </data>\r\n  <data name=\"BenchmarkRunner_Run_GenericTypeArgumentClassMustBeAnnotatedWithAGenericTypeArgumentsAttribute_Title\" xml:space=\"preserve\">\r\n    <value>Generic benchmark classes must be annotated with at least one [GenericTypeArguments] attribute</value>\r\n  </data>\r\n  <data name=\"BenchmarkRunner_Run_TypeArgumentClassMustBePublic_Title\" xml:space=\"preserve\">\r\n    <value>Benchmark classes must be public</value>\r\n  </data>\r\n  <data name=\"BenchmarkRunner_Run_TypeArgumentClassMustBeUnsealed_Description\" xml:space=\"preserve\">\r\n    <value>A benchmark class referenced in the BenchmarkRunner.Run method must be unsealed</value>\r\n  </data>\r\n  <data name=\"BenchmarkRunner_Run_TypeArgumentClassMustBeUnsealed_MessageFormat\" xml:space=\"preserve\">\r\n    <value>Referenced benchmark class '{0}' is sealed</value>\r\n  </data>\r\n  <data name=\"BenchmarkRunner_Run_TypeArgumentClassMustBeUnsealed_Title\" xml:space=\"preserve\">\r\n    <value>Benchmark classes must be unsealed</value>\r\n  </data>\r\n  <data name=\"General_BenchmarkClass_MethodMustBePublic_Description\" xml:space=\"preserve\">\r\n    <value>A method annotated with the [Benchmark] attribute must be public</value>\r\n  </data>\r\n  <data name=\"General_BenchmarkClass_MethodMustBeNonGeneric_Description\" xml:space=\"preserve\">\r\n    <value>A method annotated with the [Benchmark] attribute must be non-generic</value>\r\n  </data>\r\n  <data name=\"General_BenchmarkClass_GenericTypeArgumentsAttributeMustHaveMatchingTypeParameterCount_Description\" xml:space=\"preserve\">\r\n    <value>The number of type arguments passed to a [GenericTypeArguments] attribute must match the number of type parameters on the targeted benchmark class</value>\r\n  </data>\r\n  <data name=\"General_BenchmarkClass_ClassWithGenericTypeArgumentsAttributeMustBeGeneric_Description\" xml:space=\"preserve\">\r\n    <value>A benchmark class annotated with a [GenericTypeArguments] attribute must be generic, having between one to three type parameters</value>\r\n  </data>\r\n  <data name=\"General_BenchmarkClass_MethodMustBePublic_MessageFormat\" xml:space=\"preserve\">\r\n    <value>The benchmark method '{0}' must be public</value>\r\n  </data>\r\n  <data name=\"General_BenchmarkClass_MethodMustBeNonGeneric_MessageFormat\" xml:space=\"preserve\">\r\n    <value>The benchmark method '{0}' must be non-generic</value>\r\n  </data>\r\n  <data name=\"General_BenchmarkClass_GenericTypeArgumentsAttributeMustHaveMatchingTypeParameterCount_MessageFormat\" xml:space=\"preserve\">\r\n    <value>Expected {0} type argument{1} as declared on the benchmark class '{2}', but found {3}. Update the attribute usage or the type parameter list of the class declaration to match.</value>\r\n  </data>\r\n  <data name=\"General_BenchmarkClass_ClassWithGenericTypeArgumentsAttributeMustBeGeneric_MessageFormat\" xml:space=\"preserve\">\r\n    <value>Attribute [GenericTypeArguments] can only be applied to a generic class</value>\r\n  </data>\r\n  <data name=\"General_BenchmarkClass_OnlyOneMethodCanBeBaseline_MessageFormat\" xml:space=\"preserve\">\r\n    <value>Only one benchmark method can be marked as baseline per class</value>\r\n  </data>\r\n  <data name=\"General_BenchmarkClass_OnlyOneMethodCanBeBaselinePerCategory_MessageFormat\" xml:space=\"preserve\">\r\n    <value>Only one benchmark method can be marked as baseline per class and category</value>\r\n  </data>\r\n  <data name=\"General_BenchmarkClass_SingleNullArgumentToBenchmarkCategoryAttributeNotAllowed_MessageFormat\" xml:space=\"preserve\">\r\n    <value>Passing a single null argument creates a null params array. Use multiple arguments (e.g., null, \"SomeCategory\", ...) or a non-null value instead.</value>\r\n  </data>\r\n  <data name=\"General_BenchmarkClass_MethodMustBePublic_Title\" xml:space=\"preserve\">\r\n    <value>Benchmark methods must be public</value>\r\n  </data>\r\n  <data name=\"General_BenchmarkClass_MethodMustBeNonGeneric_Title\" xml:space=\"preserve\">\r\n    <value>Benchmark methods must be non-generic</value>\r\n  </data>\r\n  <data name=\"General_BenchmarkClass_GenericTypeArgumentsAttributeMustHaveMatchingTypeParameterCount_Title\" xml:space=\"preserve\">\r\n    <value>Number of type arguments passed to a [GenericTypeArguments] attribute must match the number of type parameters on the targeted benchmark class</value>\r\n  </data>\r\n  <data name=\"General_BenchmarkClass_ClassWithGenericTypeArgumentsAttributeMustBeGeneric_Title\" xml:space=\"preserve\">\r\n    <value>Benchmark classes annotated with a [GenericTypeArguments] attribute must be generic</value>\r\n  </data>\r\n  <data name=\"General_BenchmarkClass_OnlyOneMethodCanBeBaseline_Title\" xml:space=\"preserve\">\r\n    <value>Only one benchmark method can be baseline per class</value>\r\n  </data>\r\n  <data name=\"General_BenchmarkClass_OnlyOneMethodCanBeBaselinePerCategory_Title\" xml:space=\"preserve\">\r\n    <value>Only one benchmark method can be baseline per class and category</value>\r\n  </data>\r\n  <data name=\"General_BenchmarkClass_SingleNullArgumentToBenchmarkCategoryAttributeNotAllowed_Title\" xml:space=\"preserve\">\r\n    <value>Single null argument to the [BenchmarkCategory] attribute results in unintended null array</value>\r\n  </data>\r\n  <data name=\"Attributes_GeneralParameterAttributes_MutuallyExclusiveOnField_Description\" xml:space=\"preserve\">\r\n    <value>Parameter attributes are mutually exclusive; only one of the attributes [Params], [ParamsSource] or [ParamsAllValues] can be applied to a field at any one time</value>\r\n  </data>\r\n  <data name=\"Attributes_GeneralParameterAttributes_FieldMustBePublic_Description\" xml:space=\"preserve\">\r\n    <value>A field annotated with a parameter attribute must be public</value>\r\n  </data>\r\n  <data name=\"Attributes_GeneralParameterAttributes_PropertyMustBePublic_Description\" xml:space=\"preserve\">\r\n    <value>A property annotated with a parameter attribute must be public</value>\r\n  </data>\r\n  <data name=\"Attributes_GeneralParameterAttributes_PropertyMustHavePublicSetter_Description\" xml:space=\"preserve\">\r\n    <value>A property annotated with a parameter attribute must have a public setter; make sure that the access modifier of the setter is empty and that the property is not an auto-property or an expression-bodied property.</value>\r\n  </data>\r\n  <data name=\"Attributes_ParamsAttribute_MustHaveMatchingValueType_Description\" xml:space=\"preserve\">\r\n    <value>The type of each value provided to the [Params] attribute must match the type of (or be implicitly convertible to) the field or property it is applied to</value>\r\n  </data>\r\n  <data name=\"Attributes_ParamsAllValuesAttribute_NotAllowedOnFlagsEnumPropertyOrFieldType_Description\" xml:space=\"preserve\">\r\n    <value>The [ParamsAllValues] attribute cannot be applied to a field or property of an enum type marked with the [Flags] attribute. Use this attribute only with non-flags enum types, as [Flags] enums support bitwise combinations that cannot be exhaustively enumerated.</value>\r\n  </data>\r\n  <data name=\"Attributes_GeneralParameterAttributes_PropertyCannotBeInitOnly_Description\" xml:space=\"preserve\">\r\n    <value>A property annotated with a parameter attribute must have a public, assignable setter i.e. { set; }</value>\r\n  </data>\r\n  <data name=\"Attributes_GeneralParameterAttributes_MutuallyExclusiveOnProperty_Description\" xml:space=\"preserve\">\r\n    <value>Parameter attributes are mutually exclusive; only one of the attributes [Params], [ParamsSource] or [ParamsAllValues] can be applied to a property at any one time</value>\r\n  </data>\r\n  <data name=\"Attributes_GeneralParameterAttributes_MutuallyExclusiveOnField_MessageFormat\" xml:space=\"preserve\">\r\n    <value>Duplicate parameter attribute on field '{0}'</value>\r\n  </data>\r\n  <data name=\"Attributes_GeneralParameterAttributes_FieldMustBePublic_MessageFormat\" xml:space=\"preserve\">\r\n    <value>Field '{0}' annotated with [{1}] must be public</value>\r\n  </data>\r\n  <data name=\"Attributes_ArgumentsAttribute_MustHaveMatchingValueCount_MessageFormat\" xml:space=\"preserve\">\r\n    <value>Expected {0} value{1} as declared by the benchmark method '{2}', but found {3}. Update the attribute usage or method to match.</value>\r\n  </data>\r\n  <data name=\"Attributes_GeneralArgumentAttributes_MethodWithoutAttributeMustHaveNoParameters_MessageFormat\" xml:space=\"preserve\">\r\n    <value>Benchmark method '{0}' without an [ArgumentsSource] or [Arguments] attribute(s) cannot declare parameters</value>\r\n  </data>\r\n  <data name=\"Attributes_ArgumentsAttribute_MustHaveMatchingValueType_MessageFormat\" xml:space=\"preserve\">\r\n    <value>Unexpected type for argument value '{0}'. Expected '{1}' but found '{2}'.</value>\r\n  </data>\r\n  <data name=\"Attributes_GeneralParameterAttributes_PropertyMustBePublic_MessageFormat\" xml:space=\"preserve\">\r\n    <value>Property '{0}' annotated with [{1}] must be public</value>\r\n  </data>\r\n  <data name=\"Attributes_GeneralParameterAttributes_PropertyMustHavePublicSetter_MessageFormat\" xml:space=\"preserve\">\r\n    <value>Property '{0}' annotated with [{1}] must have a public setter</value>\r\n  </data>\r\n  <data name=\"Attributes_ParamsAttribute_MustHaveValues_MessageFormat\" xml:space=\"preserve\">\r\n    <value>The [Params] attribute requires at least one value. No values were provided, or an empty array was specified.</value>\r\n  </data>\r\n  <data name=\"Attributes_ParamsAttribute_UnnecessarySingleValuePassedToAttribute_MessageFormat\" xml:space=\"preserve\">\r\n    <value>Providing a single value to the [Params] attribute is unnecessary. This attribute is only useful when provided two or more values.</value>\r\n  </data>\r\n  <data name=\"Attributes_ParamsAttribute_MustHaveMatchingValueType_MessageFormat\" xml:space=\"preserve\">\r\n    <value>Unexpected type for parameter value '{0}'. Expected '{1}' but found '{2}'.</value>\r\n  </data>\r\n  <data name=\"Attributes_ParamsAllValuesAttribute_NotAllowedOnFlagsEnumPropertyOrFieldType_MessageFormat\" xml:space=\"preserve\">\r\n    <value>Field or property enum type '{0}' is marked with [Flags] and cannot be used with this attribute</value>\r\n  </data>\r\n  <data name=\"Attributes_ParamsAllValuesAttribute_PropertyOrFieldTypeMustBeEnumOrBool_MessageFormat\" xml:space=\"preserve\">\r\n    <value>The [ParamsAllValues] attribute can only be applied to a field or property of enum or bool type (or nullable of these types)</value>\r\n  </data>\r\n  <data name=\"Attributes_ParamsSourceAttribute_CannotUseWriteOnlyProperty_Title\" xml:space=\"preserve\">\r\n    <value>ParamsSource cannot reference a write-only property</value>\r\n  </data>\r\n  <data name=\"Attributes_ParamsSourceAttribute_CannotUseWriteOnlyProperty_MessageFormat\" xml:space=\"preserve\">\r\n    <value>ParamsSource cannot reference write-only property '{0}'. Write-only properties cannot be read and will cause a runtime error.</value>\r\n  </data>\r\n  <data name=\"Attributes_ParamsSourceAttribute_CannotUseWriteOnlyProperty_Description\" xml:space=\"preserve\">\r\n    <value>ParamsSource references a write-only property (a property with only a setter and no getter). Write-only properties cannot be read at runtime and will cause a NullReferenceException. Use a property with a getter or a method instead.</value>\r\n  </data>\r\n  <data name=\"Attributes_GeneralParameterAttributes_PropertyCannotBeInitOnly_MessageFormat\" xml:space=\"preserve\">\r\n    <value>Property '{0}' annotated with [{1}] cannot be init-only</value>\r\n  </data>\r\n  <data name=\"Attributes_GeneralParameterAttributes_MutuallyExclusiveOnProperty_MessageFormat\" xml:space=\"preserve\">\r\n    <value>Duplicate parameter attribute on property '{0}'</value>\r\n  </data>\r\n  <data name=\"Attributes_GeneralParameterAttributes_MutuallyExclusiveOnField_Title\" xml:space=\"preserve\">\r\n    <value>Only one parameter attribute can be applied to a field</value>\r\n  </data>\r\n  <data name=\"Attributes_GeneralParameterAttributes_FieldMustBePublic_Title\" xml:space=\"preserve\">\r\n    <value>Fields annotated with a parameter attribute must be public</value>\r\n  </data>\r\n  <data name=\"Attributes_ArgumentsAttribute_MustHaveMatchingValueCount_Title\" xml:space=\"preserve\">\r\n    <value>Number of values passed to an [Arguments] attribute must match the number of parameters declared in the targeted benchmark method</value>\r\n  </data>\r\n  <data name=\"Attributes_ArgumentsAttribute_MustHaveMatchingValueType_Title\" xml:space=\"preserve\">\r\n    <value>Values passed to an [Arguments] attribute must match exactly the parameters declared in the targeted benchmark method in both type (or be implicitly convertible to) and order</value>\r\n  </data>\r\n  <data name=\"Attributes_GeneralParameterAttributes_PropertyMustBePublic_Title\" xml:space=\"preserve\">\r\n    <value>Properties annotated with a parameter attribute must be public</value>\r\n  </data>\r\n  <data name=\"Attributes_GeneralParameterAttributes_PropertyMustHavePublicSetter_Title\" xml:space=\"preserve\">\r\n    <value>Properties annotated with a parameter attribute must have a public setter</value>\r\n  </data>\r\n  <data name=\"Attributes_ParamsAttribute_MustHaveValues_Title\" xml:space=\"preserve\">\r\n    <value>The [Params] attribute must include at least one value</value>\r\n  </data>\r\n  <data name=\"Attributes_ParamsAttribute_UnnecessarySingleValuePassedToAttribute_Title\" xml:space=\"preserve\">\r\n    <value>Unnecessary single value passed to [Params] attribute</value>\r\n  </data>\r\n  <data name=\"Attributes_ParamsAttribute_MustHaveMatchingValueType_Title\" xml:space=\"preserve\">\r\n    <value>Type of all value(s) passed to the [Params] attribute must match the type of (or be implicitly convertible to) the annotated field or property</value>\r\n  </data>\r\n  <data name=\"Attributes_ParamsAllValuesAttribute_NotAllowedOnFlagsEnumPropertyOrFieldType_Title\" xml:space=\"preserve\">\r\n    <value>The [ParamsAllValues] attribute cannot be applied to fields or properties of enum types marked with [Flags]</value>\r\n  </data>\r\n  <data name=\"Attributes_ParamsAllValuesAttribute_PropertyOrFieldTypeMustBeEnumOrBool_Title\" xml:space=\"preserve\">\r\n    <value>The [ParamsAllValues] attribute is only valid on fields or properties of enum or bool type and nullable type for another allowed type</value>\r\n  </data>\r\n  <data name=\"Attributes_GeneralParameterAttributes_PropertyCannotBeInitOnly_Title\" xml:space=\"preserve\">\r\n    <value>Properties annotated with a parameter attribute cannot have an init-only setter</value>\r\n  </data>\r\n  <data name=\"Attributes_GeneralParameterAttributes_MutuallyExclusiveOnProperty_Title\" xml:space=\"preserve\">\r\n    <value>Only one parameter attribute can be applied to a property</value>\r\n  </data>\r\n  <data name=\"Attributes_GeneralParameterAttributes_NotValidOnReadonlyField_Description\" xml:space=\"preserve\">\r\n    <value>Parameter attributes are not valid on fields with a readonly modifier</value>\r\n  </data>\r\n  <data name=\"Attributes_GeneralParameterAttributes_NotValidOnReadonlyField_Title\" xml:space=\"preserve\">\r\n    <value>Fields annotated with a parameter attribute cannot be read-only</value>\r\n  </data>\r\n  <data name=\"Attributes_GeneralParameterAttributes_NotValidOnConstantField_Title\" xml:space=\"preserve\">\r\n    <value>Parameter attributes are not valid on constant field declarations</value>\r\n  </data>\r\n  <data name=\"Attributes_GeneralParameterAttributes_NotValidOnReadonlyField_MessageFormat\" xml:space=\"preserve\">\r\n    <value>Modifier 'readonly' is not valid on field '{0}' annotated with parameter attribute [{1}]</value>\r\n  </data>\r\n  <data name=\"Attributes_GeneralParameterAttributes_NotValidOnConstantField_MessageFormat\" xml:space=\"preserve\">\r\n    <value>Parameter attribute [{0}] is not valid on constants. It is only valid on non-constant field declarations.</value>\r\n  </data>\r\n  <data name=\"Attributes_ArgumentsAttribute_MustHaveMatchingValueCount_Description\" xml:space=\"preserve\">\r\n    <value>The number of values passed to an [Arguments] attribute must match the number of parameters declared in the targeted benchmark method</value>\r\n  </data>\r\n  <data name=\"Attributes_GeneralArgumentAttributes_MethodWithoutAttributeMustHaveNoParameters_Description\" xml:space=\"preserve\">\r\n    <value>This method declares one or more parameters but is not annotated with either an [ArgumentsSource] attribute or one or more [Arguments] attributes. To ensure correct argument binding, methods with parameters must explicitly be annotated with an [ArgumentsSource] attribute or one or more [Arguments] attributes.\r\nEither add the [ArgumentsSource] or [Arguments] attribute(s) or remove the parameters.</value>\r\n  </data>\r\n  <data name=\"Attributes_ArgumentsAttribute_MustHaveMatchingValueType_Description\" xml:space=\"preserve\">\r\n    <value>The values passed to an [Arguments] attribute must match the parameters declared in the targeted benchmark method in both type (or be implicitly convertible to) and order</value>\r\n  </data>\r\n  <data name=\"Attributes_ArgumentsAttribute_RequiresBenchmarkAttribute_Title\" xml:space=\"preserve\">\r\n    <value>[Arguments(Source)] attribute can only be used on methods annotated with the [Benchmark] attribute</value>\r\n  </data>\r\n  <data name=\"Attributes_ArgumentsAttribute_RequiresBenchmarkAttribute_MessageFormat\" xml:space=\"preserve\">\r\n    <value>The [Arguments(Source)] attribute can only be used on methods annotated with the [Benchmark] attribute</value>\r\n  </data>\r\n  <data name=\"BenchmarkRunner_Run_TypeArgumentClassMustBeNonAbstract_Description\" xml:space=\"preserve\">\r\n    <value>A benchmark class referenced in the BenchmarkRunner.Run method must be non-abstract</value>\r\n  </data>\r\n  <data name=\"BenchmarkRunner_Run_TypeArgumentClassMustBePublic_MessageFormat\" xml:space=\"preserve\">\r\n    <value>Referenced benchmark class '{0}' must be public</value>\r\n  </data>\r\n  <data name=\"Attributes_GeneralArgumentAttributes_MethodWithoutAttributeMustHaveNoParameters_Title\" xml:space=\"preserve\">\r\n    <value>Benchmark methods without an [ArgumentsSource] or [Arguments] attribute(s) cannot declare parameters</value>\r\n  </data>\r\n  <data name=\"Attributes_ArgumentsAttribute_RequiresParameters_Title\" xml:space=\"preserve\">\r\n    <value>[Arguments(Source)] attribute requires at least 1 parameter</value>\r\n  </data>\r\n  <data name=\"Attributes_ArgumentsAttribute_RequiresParameters_MessageFormat\" xml:space=\"preserve\">\r\n    <value>Method {0} has no parameters</value>\r\n  </data>\r\n  <data name=\"Attributes_ArgumentsAttribute_RequiresParameters_Description\" xml:space=\"preserve\">\r\n    <value>The values passed to an [Arguments] must have parameter(s)</value>\r\n  </data>\r\n</root>"
  },
  {
    "path": "src/BenchmarkDotNet.Analyzers/BenchmarkRunner/RunAnalyzer.cs",
    "content": "﻿using Microsoft.CodeAnalysis;\r\nusing Microsoft.CodeAnalysis.CSharp;\r\nusing Microsoft.CodeAnalysis.CSharp.Syntax;\r\nusing Microsoft.CodeAnalysis.Diagnostics;\r\nusing System.Collections.Immutable;\r\n\r\nnamespace BenchmarkDotNet.Analyzers.BenchmarkRunner;\r\n\r\n[DiagnosticAnalyzer(LanguageNames.CSharp)]\r\npublic class RunAnalyzer : DiagnosticAnalyzer\r\n{\r\n    internal static readonly DiagnosticDescriptor TypeArgumentClassMissingBenchmarkMethodsRule = new(\r\n        DiagnosticIds.BenchmarkRunner_Run_TypeArgumentClassMissingBenchmarkMethods,\r\n        AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.BenchmarkRunner_Run_TypeArgumentClassMissingBenchmarkMethods_Title)),\r\n        AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.BenchmarkRunner_Run_TypeArgumentClassMissingBenchmarkMethods_MessageFormat)),\r\n        \"Usage\",\r\n        DiagnosticSeverity.Error,\r\n        isEnabledByDefault: true,\r\n        description: AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.BenchmarkRunner_Run_TypeArgumentClassMissingBenchmarkMethods_Description)));\r\n\r\n    internal static readonly DiagnosticDescriptor TypeArgumentClassMustBePublicRule = new(\r\n        DiagnosticIds.BenchmarkRunner_Run_TypeArgumentClassMustBePublic,\r\n        AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.BenchmarkRunner_Run_TypeArgumentClassMustBePublic_Title)),\r\n        AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.BenchmarkRunner_Run_TypeArgumentClassMustBePublic_MessageFormat)),\r\n        \"Usage\",\r\n        DiagnosticSeverity.Error,\r\n        isEnabledByDefault: true);\r\n\r\n    internal static readonly DiagnosticDescriptor TypeArgumentClassMustBeUnsealedRule = new(\r\n        DiagnosticIds.BenchmarkRunner_Run_TypeArgumentClassMustBeUnsealed,\r\n        AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.BenchmarkRunner_Run_TypeArgumentClassMustBeUnsealed_Title)),\r\n        AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.BenchmarkRunner_Run_TypeArgumentClassMustBeUnsealed_MessageFormat)),\r\n        \"Usage\",\r\n        DiagnosticSeverity.Error,\r\n        isEnabledByDefault: true,\r\n        description: AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.BenchmarkRunner_Run_TypeArgumentClassMustBeUnsealed_Description)));\r\n\r\n    internal static readonly DiagnosticDescriptor TypeArgumentClassMustBeNonAbstractRule = new(\r\n        DiagnosticIds.BenchmarkRunner_Run_TypeArgumentClassMustBeNonAbstract,\r\n        AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.BenchmarkRunner_Run_TypeArgumentClassMustBeNonAbstract_Title)),\r\n        AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.BenchmarkRunner_Run_TypeArgumentClassMustBeNonAbstract_MessageFormat)),\r\n        \"Usage\",\r\n        DiagnosticSeverity.Error,\r\n        isEnabledByDefault: true,\r\n        description: AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.BenchmarkRunner_Run_TypeArgumentClassMustBeNonAbstract_Description)));\r\n\r\n    internal static readonly DiagnosticDescriptor GenericTypeArgumentClassMustBeAnnotatedWithAGenericTypeArgumentsAttributeRule = new(\r\n        DiagnosticIds.BenchmarkRunner_Run_GenericTypeArgumentClassMustBeAnnotatedWithAGenericTypeArgumentsAttribute,\r\n        AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.BenchmarkRunner_Run_GenericTypeArgumentClassMustBeAnnotatedWithAGenericTypeArgumentsAttribute_Title)),\r\n        AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.BenchmarkRunner_Run_GenericTypeArgumentClassMustBeAnnotatedWithAGenericTypeArgumentsAttribute_MessageFormat)),\r\n        \"Usage\",\r\n        DiagnosticSeverity.Error,\r\n        isEnabledByDefault: true,\r\n        description: AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.BenchmarkRunner_Run_GenericTypeArgumentClassMustBeAnnotatedWithAGenericTypeArgumentsAttribute_Description)));\r\n\r\n\r\n    public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => new DiagnosticDescriptor[]\r\n    {\r\n        TypeArgumentClassMissingBenchmarkMethodsRule,\r\n        TypeArgumentClassMustBePublicRule,\r\n        TypeArgumentClassMustBeUnsealedRule,\r\n        TypeArgumentClassMustBeNonAbstractRule,\r\n        GenericTypeArgumentClassMustBeAnnotatedWithAGenericTypeArgumentsAttributeRule,\r\n    }.ToImmutableArray();\r\n\r\n    public override void Initialize(AnalysisContext analysisContext)\r\n    {\r\n        analysisContext.EnableConcurrentExecution();\r\n        analysisContext.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);\r\n\r\n        analysisContext.RegisterCompilationStartAction(ctx =>\r\n        {\r\n            // Only run if BenchmarkDotNet is referenced\r\n            var benchmarkRunnerTypeSymbol = ctx.Compilation.GetTypeByMetadataName(\"BenchmarkDotNet.Running.BenchmarkRunner\");\r\n            if (benchmarkRunnerTypeSymbol == null)\r\n            {\r\n                return;\r\n            }\r\n\r\n            ctx.RegisterSyntaxNodeAction(Analyze, SyntaxKind.InvocationExpression);\r\n        });\r\n    }\r\n\r\n    private static void Analyze(SyntaxNodeAnalysisContext context)\r\n    {\r\n        if (context.Node is not InvocationExpressionSyntax invocationExpression)\r\n        {\r\n            return;\r\n        }\r\n\r\n        if (invocationExpression.Expression is not MemberAccessExpressionSyntax memberAccessExpression)\r\n        {\r\n            return;\r\n        }\r\n\r\n        if (memberAccessExpression.Expression is not IdentifierNameSyntax identifierNameSyntax)\r\n        {\r\n            return;\r\n        }\r\n\r\n        var benchmarkRunnerTypeSymbol = context.Compilation.GetTypeByMetadataName(\"BenchmarkDotNet.Running.BenchmarkRunner\");\r\n        if (benchmarkRunnerTypeSymbol == null\r\n            || benchmarkRunnerTypeSymbol.TypeKind == TypeKind.Error)\r\n        {\r\n            return;\r\n        }\r\n\r\n        var classMemberAccessTypeSymbol = context.SemanticModel.GetTypeInfo(identifierNameSyntax).Type;\r\n        if (classMemberAccessTypeSymbol is null\r\n            || classMemberAccessTypeSymbol.TypeKind == TypeKind.Error\r\n            || !SymbolEqualityComparer.Default.Equals(classMemberAccessTypeSymbol, benchmarkRunnerTypeSymbol))\r\n        {\r\n            return;\r\n        }\r\n\r\n        if (memberAccessExpression.Name.Identifier.ValueText != \"Run\")\r\n        {\r\n            return;\r\n        }\r\n\r\n        INamedTypeSymbol? benchmarkClassTypeSymbol;\r\n        Location? diagnosticLocation;\r\n\r\n        if (memberAccessExpression.Name is GenericNameSyntax genericMethod)\r\n        {\r\n            if (genericMethod.TypeArgumentList.Arguments.Count != 1)\r\n            {\r\n                return;\r\n            }\r\n\r\n            diagnosticLocation = Location.Create(context.Node.SyntaxTree, genericMethod.TypeArgumentList.Arguments.Span);\r\n            benchmarkClassTypeSymbol = context.SemanticModel.GetTypeInfo(genericMethod.TypeArgumentList.Arguments[0]).Type as INamedTypeSymbol;\r\n        }\r\n        else\r\n        {\r\n            if (invocationExpression.ArgumentList.Arguments.Count == 0)\r\n            {\r\n                return;\r\n            }\r\n\r\n            // TODO: Support analyzing a collection of typeof() expressions\r\n            if (invocationExpression.ArgumentList.Arguments[0].Expression is not TypeOfExpressionSyntax typeOfExpression)\r\n            {\r\n                return;\r\n            }\r\n\r\n            diagnosticLocation = typeOfExpression.Type.GetLocation();\r\n            benchmarkClassTypeSymbol = context.SemanticModel.GetTypeInfo(typeOfExpression.Type).Type as INamedTypeSymbol;\r\n\r\n        }\r\n\r\n        if (benchmarkClassTypeSymbol == null || benchmarkClassTypeSymbol.TypeKind == TypeKind.Error || (benchmarkClassTypeSymbol.IsGenericType && !benchmarkClassTypeSymbol.IsUnboundGenericType))\r\n        {\r\n            return;\r\n        }\r\n\r\n        var benchmarkAttributeTypeSymbol = AnalyzerHelper.GetBenchmarkAttributeTypeSymbol(context.Compilation);\r\n        if (benchmarkAttributeTypeSymbol == null)\r\n        {\r\n            return;\r\n        }\r\n\r\n        if (!HasBenchmarkAttribute())\r\n        {\r\n            ReportDiagnostic(TypeArgumentClassMissingBenchmarkMethodsRule);\r\n        }\r\n\r\n        if (benchmarkClassTypeSymbol.DeclaredAccessibility != Accessibility.Public)\r\n        {\r\n            ReportDiagnostic(TypeArgumentClassMustBePublicRule);\r\n        }\r\n\r\n        if (benchmarkClassTypeSymbol.IsAbstract)\r\n        {\r\n            ReportDiagnostic(TypeArgumentClassMustBeNonAbstractRule);\r\n        }\r\n\r\n        if (benchmarkClassTypeSymbol.IsSealed)\r\n        {\r\n            ReportDiagnostic(TypeArgumentClassMustBeUnsealedRule);\r\n        }\r\n\r\n        if (benchmarkClassTypeSymbol.IsUnboundGenericType\r\n            && !AnalyzerHelper.AttributeListContainsAttribute(\"BenchmarkDotNet.Attributes.GenericTypeArgumentsAttribute\", context.Compilation, benchmarkClassTypeSymbol.GetAttributes()))\r\n        {\r\n            ReportDiagnostic(GenericTypeArgumentClassMustBeAnnotatedWithAGenericTypeArgumentsAttributeRule);\r\n        }\r\n\r\n        return;\r\n\r\n        bool HasBenchmarkAttribute()\r\n        {\r\n            var baseType = benchmarkClassTypeSymbol;\r\n\r\n            while (baseType != null && baseType.SpecialType != SpecialType.System_Object)\r\n            {\r\n                foreach (var member in baseType.GetMembers())\r\n                {\r\n                    if (member is IMethodSymbol { MethodKind: MethodKind.Ordinary })\r\n                    {\r\n                        foreach (var attributeData in member.GetAttributes())\r\n                        {\r\n                            if (attributeData.AttributeClass != null)\r\n                            {\r\n                                if (SymbolEqualityComparer.Default.Equals(attributeData.AttributeClass, benchmarkAttributeTypeSymbol))\r\n                                {\r\n                                    return true;\r\n                                }\r\n                            }\r\n                        }\r\n                    }\r\n                }\r\n\r\n                baseType = baseType.OriginalDefinition.BaseType;\r\n            }\r\n\r\n            return false;\r\n        }\r\n\r\n        void ReportDiagnostic(DiagnosticDescriptor diagnosticDescriptor)\r\n            => context.ReportDiagnostic(Diagnostic.Create(diagnosticDescriptor, diagnosticLocation, AnalyzerHelper.NormalizeTypeName(benchmarkClassTypeSymbol)));\r\n    }\r\n}"
  },
  {
    "path": "src/BenchmarkDotNet.Analyzers/DiagnosticIds.cs",
    "content": "namespace BenchmarkDotNet.Analyzers;\r\n\r\npublic static class DiagnosticIds\r\n{\r\n    public const string BenchmarkRunner_Run_TypeArgumentClassMissingBenchmarkMethods = \"BDN1000\";\r\n    public const string BenchmarkRunner_Run_TypeArgumentClassMustBePublic = \"BDN1001\";\r\n    public const string BenchmarkRunner_Run_TypeArgumentClassMustBeUnsealed = \"BDN1002\";\r\n    public const string BenchmarkRunner_Run_TypeArgumentClassMustBeNonAbstract = \"BDN1003\";\r\n    public const string BenchmarkRunner_Run_GenericTypeArgumentClassMustBeAnnotatedWithAGenericTypeArgumentsAttribute = \"BDN1004\";\r\n    public const string General_BenchmarkClass_ClassWithGenericTypeArgumentsAttributeMustBeGeneric = \"BDN1101\";\r\n    public const string General_BenchmarkClass_GenericTypeArgumentsAttributeMustHaveMatchingTypeParameterCount = \"BDN1102\";\r\n    public const string General_BenchmarkClass_MethodMustBePublic = \"BDN1103\";\r\n    public const string General_BenchmarkClass_MethodMustBeNonGeneric = \"BDN1104\";\r\n    public const string General_BenchmarkClass_ClassMustBeNonStatic = \"BDN1105\";\r\n    public const string General_BenchmarkClass_SingleNullArgumentToBenchmarkCategoryAttributeNotAllowed = \"BDN1106\";\r\n    public const string General_BenchmarkClass_OnlyOneMethodCanBeBaseline = \"BDN1107\";\r\n    public const string General_BenchmarkClass_OnlyOneMethodCanBeBaselinePerCategory = \"BDN1108\";\r\n    public const string Attributes_GeneralParameterAttributes_MutuallyExclusiveOnField = \"BDN1200\";\r\n    public const string Attributes_GeneralParameterAttributes_MutuallyExclusiveOnProperty = \"BDN1201\";\r\n    public const string Attributes_GeneralParameterAttributes_FieldMustBePublic = \"BDN1202\";\r\n    public const string Attributes_GeneralParameterAttributes_PropertyMustBePublic = \"BDN1203\";\r\n    public const string Attributes_GeneralParameterAttributes_NotValidOnReadonlyField = \"BDN1204\";\r\n    public const string Attributes_GeneralParameterAttributes_NotValidOnConstantField = \"BDN1205\";\r\n    public const string Attributes_GeneralParameterAttributes_PropertyCannotBeInitOnly = \"BDN1206\";\r\n    public const string Attributes_GeneralParameterAttributes_PropertyMustHavePublicSetter = \"BDN1207\";\r\n    public const string Attributes_ParamsAttribute_MustHaveValues = \"BDN1300\";\r\n    public const string Attributes_ParamsAttribute_MustHaveMatchingValueType = \"BDN1301\";\r\n    public const string Attributes_ParamsAttribute_UnnecessarySingleValuePassedToAttribute = \"BDN1302\";\r\n    public const string Attributes_ParamsAllValuesAttribute_NotAllowedOnFlagsEnumPropertyOrFieldType = \"BDN1303\";\r\n    public const string Attributes_ParamsAllValuesAttribute_PropertyOrFieldTypeMustBeEnumOrBool = \"BDN1304\";\r\n    public const string Attributes_ParamsSourceAttribute_CannotUseWriteOnlyProperty = \"BDN1305\";\r\n    public const string Attributes_GeneralArgumentAttributes_MethodWithoutAttributeMustHaveNoParameters = \"BDN1400\";\r\n    public const string Attributes_ArgumentsAttribute_RequiresBenchmarkAttribute = \"BDN1500\";\r\n    public const string Attributes_ArgumentsAttribute_MustHaveMatchingValueCount = \"BDN1501\";\r\n    public const string Attributes_ArgumentsAttribute_MustHaveMatchingValueType = \"BDN1502\";\r\n    public const string Attributes_ArgumentsAttribute_RequiresParameters = \"BDN1503\";\r\n}\r\n"
  },
  {
    "path": "src/BenchmarkDotNet.Analyzers/General/BenchmarkClassAnalyzer.cs",
    "content": "﻿using Microsoft.CodeAnalysis;\r\nusing Microsoft.CodeAnalysis.CSharp;\r\nusing Microsoft.CodeAnalysis.CSharp.Syntax;\r\nusing Microsoft.CodeAnalysis.Diagnostics;\r\nusing System;\r\nusing System.Collections.Generic;\r\nusing System.Collections.Immutable;\r\nusing System.Linq;\r\n\r\nnamespace BenchmarkDotNet.Analyzers.General;\r\n\r\n[DiagnosticAnalyzer(LanguageNames.CSharp)]\r\npublic class BenchmarkClassAnalyzer : DiagnosticAnalyzer\r\n{\r\n    internal static readonly DiagnosticDescriptor ClassWithGenericTypeArgumentsAttributeMustBeGenericRule = new(\r\n        DiagnosticIds.General_BenchmarkClass_ClassWithGenericTypeArgumentsAttributeMustBeGeneric,\r\n        AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.General_BenchmarkClass_ClassWithGenericTypeArgumentsAttributeMustBeGeneric_Title)),\r\n        AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.General_BenchmarkClass_ClassWithGenericTypeArgumentsAttributeMustBeGeneric_MessageFormat)),\r\n        \"Usage\",\r\n        DiagnosticSeverity.Error,\r\n        isEnabledByDefault: true,\r\n        description: AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.General_BenchmarkClass_ClassWithGenericTypeArgumentsAttributeMustBeGeneric_Description)));\r\n\r\n    internal static readonly DiagnosticDescriptor GenericTypeArgumentsAttributeMustHaveMatchingTypeParameterCountRule = new(\r\n        DiagnosticIds.General_BenchmarkClass_GenericTypeArgumentsAttributeMustHaveMatchingTypeParameterCount,\r\n        AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.General_BenchmarkClass_GenericTypeArgumentsAttributeMustHaveMatchingTypeParameterCount_Title)),\r\n        AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.General_BenchmarkClass_GenericTypeArgumentsAttributeMustHaveMatchingTypeParameterCount_MessageFormat)),\r\n        \"Usage\",\r\n        DiagnosticSeverity.Error,\r\n        isEnabledByDefault: true,\r\n        description: AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.General_BenchmarkClass_GenericTypeArgumentsAttributeMustHaveMatchingTypeParameterCount_Description)));\r\n\r\n    internal static readonly DiagnosticDescriptor MethodMustBePublicRule = new(\r\n        DiagnosticIds.General_BenchmarkClass_MethodMustBePublic,\r\n        AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.General_BenchmarkClass_MethodMustBePublic_Title)),\r\n        AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.General_BenchmarkClass_MethodMustBePublic_MessageFormat)),\r\n        \"Usage\",\r\n        DiagnosticSeverity.Error,\r\n        isEnabledByDefault: true,\r\n        description: AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.General_BenchmarkClass_MethodMustBePublic_Description)));\r\n\r\n    internal static readonly DiagnosticDescriptor MethodMustBeNonGenericRule = new(\r\n        DiagnosticIds.General_BenchmarkClass_MethodMustBeNonGeneric,\r\n        AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.General_BenchmarkClass_MethodMustBeNonGeneric_Title)),\r\n        AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.General_BenchmarkClass_MethodMustBeNonGeneric_MessageFormat)),\r\n        \"Usage\",\r\n        DiagnosticSeverity.Error,\r\n        isEnabledByDefault: true,\r\n        description: AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.General_BenchmarkClass_MethodMustBeNonGeneric_Description)));\r\n\r\n    internal static readonly DiagnosticDescriptor ClassMustBeNonStaticRule = new(\r\n        DiagnosticIds.General_BenchmarkClass_ClassMustBeNonStatic,\r\n        AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.General_BenchmarkClass_ClassMustBeNonStatic_Title)),\r\n        AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.General_BenchmarkClass_ClassMustBeNonStatic_MessageFormat)),\r\n        \"Usage\",\r\n        DiagnosticSeverity.Error,\r\n        isEnabledByDefault: true,\r\n        description: AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.General_BenchmarkClass_ClassMustBeNonStatic_Description)));\r\n\r\n    internal static readonly DiagnosticDescriptor SingleNullArgumentToBenchmarkCategoryAttributeNotAllowedRule = new(\r\n        DiagnosticIds.General_BenchmarkClass_SingleNullArgumentToBenchmarkCategoryAttributeNotAllowed,\r\n        AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.General_BenchmarkClass_SingleNullArgumentToBenchmarkCategoryAttributeNotAllowed_Title)),\r\n        AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.General_BenchmarkClass_SingleNullArgumentToBenchmarkCategoryAttributeNotAllowed_MessageFormat)),\r\n        \"Usage\",\r\n        DiagnosticSeverity.Error,\r\n        isEnabledByDefault: true);\r\n\r\n    internal static readonly DiagnosticDescriptor OnlyOneMethodCanBeBaselineRule = new(\r\n        DiagnosticIds.General_BenchmarkClass_OnlyOneMethodCanBeBaseline,\r\n        AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.General_BenchmarkClass_OnlyOneMethodCanBeBaseline_Title)),\r\n        AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.General_BenchmarkClass_OnlyOneMethodCanBeBaseline_MessageFormat)),\r\n        \"Usage\",\r\n        DiagnosticSeverity.Error,\r\n        isEnabledByDefault: true);\r\n\r\n    internal static readonly DiagnosticDescriptor OnlyOneMethodCanBeBaselinePerCategoryRule = new(\r\n        DiagnosticIds.General_BenchmarkClass_OnlyOneMethodCanBeBaselinePerCategory,\r\n        AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.General_BenchmarkClass_OnlyOneMethodCanBeBaselinePerCategory_Title)),\r\n        AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.General_BenchmarkClass_OnlyOneMethodCanBeBaselinePerCategory_MessageFormat)),\r\n        \"Usage\",\r\n        DiagnosticSeverity.Warning,\r\n        isEnabledByDefault: true);\r\n\r\n    public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => new DiagnosticDescriptor[]\r\n    {\r\n        ClassWithGenericTypeArgumentsAttributeMustBeGenericRule,\r\n        GenericTypeArgumentsAttributeMustHaveMatchingTypeParameterCountRule,\r\n        MethodMustBePublicRule,\r\n        MethodMustBeNonGenericRule,\r\n        ClassMustBeNonStaticRule,\r\n        SingleNullArgumentToBenchmarkCategoryAttributeNotAllowedRule,\r\n        OnlyOneMethodCanBeBaselineRule,\r\n        OnlyOneMethodCanBeBaselinePerCategoryRule,\r\n    }.ToImmutableArray();\r\n\r\n    public override void Initialize(AnalysisContext analysisContext)\r\n    {\r\n        analysisContext.EnableConcurrentExecution();\r\n        analysisContext.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);\r\n\r\n        analysisContext.RegisterCompilationStartAction(ctx =>\r\n        {\r\n            // Only run if BenchmarkDotNet.Annotations is referenced\r\n            var benchmarkAttributeTypeSymbol = AnalyzerHelper.GetBenchmarkAttributeTypeSymbol(ctx.Compilation);\r\n            if (benchmarkAttributeTypeSymbol == null)\r\n            {\r\n                return;\r\n            }\r\n\r\n            ctx.RegisterSyntaxNodeAction(AnalyzeClassDeclaration, SyntaxKind.ClassDeclaration);\r\n            ctx.RegisterSyntaxNodeAction(AnalyzeAttributeSyntax, SyntaxKind.Attribute);\r\n        });\r\n    }\r\n\r\n    private static void AnalyzeClassDeclaration(SyntaxNodeAnalysisContext context)\r\n    {\r\n        if (context.Node is not ClassDeclarationSyntax classDeclarationSyntax)\r\n        {\r\n            return;\r\n        }\r\n\r\n        var classStaticModifier = null as SyntaxToken?;\r\n        var classAbstractModifier = null as SyntaxToken?;\r\n\r\n        foreach (var modifier in classDeclarationSyntax.Modifiers)\r\n        {\r\n            if (modifier.IsKind(SyntaxKind.StaticKeyword))\r\n            {\r\n                classStaticModifier = modifier;\r\n            }\r\n            else if (modifier.IsKind(SyntaxKind.AbstractKeyword))\r\n            {\r\n                classAbstractModifier = modifier;\r\n            }\r\n        }\r\n\r\n        var genericTypeArgumentsAttributes = AnalyzerHelper.GetAttributes(\"BenchmarkDotNet.Attributes.GenericTypeArgumentsAttribute\", context.Compilation, classDeclarationSyntax.AttributeLists, context.SemanticModel);\r\n        if (genericTypeArgumentsAttributes.Length > 0)\r\n        {\r\n            foreach (var genericTypeArgumentsAttribute in genericTypeArgumentsAttributes)\r\n            {\r\n                if (classDeclarationSyntax.TypeParameterList == null || classDeclarationSyntax.TypeParameterList.Parameters.Count == 0)\r\n                {\r\n                    context.ReportDiagnostic(Diagnostic.Create(ClassWithGenericTypeArgumentsAttributeMustBeGenericRule, genericTypeArgumentsAttribute.GetLocation()));\r\n                }\r\n                else if (genericTypeArgumentsAttribute.ArgumentList is { Arguments.Count: > 0 })\r\n                {\r\n                    if (genericTypeArgumentsAttribute.ArgumentList.Arguments.Count != classDeclarationSyntax.TypeParameterList.Parameters.Count)\r\n                    {\r\n                        context.ReportDiagnostic(Diagnostic.Create(GenericTypeArgumentsAttributeMustHaveMatchingTypeParameterCountRule,\r\n                            Location.Create(context.Node.SyntaxTree, genericTypeArgumentsAttribute.ArgumentList.Arguments.Span),\r\n                            classDeclarationSyntax.TypeParameterList.Parameters.Count,\r\n                            classDeclarationSyntax.TypeParameterList.Parameters.Count == 1 ? \"\" : \"s\",\r\n                            classDeclarationSyntax.Identifier.ToString(),\r\n                            genericTypeArgumentsAttribute.ArgumentList.Arguments.Count)\r\n                        );\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        var benchmarkAttributeTypeSymbol = AnalyzerHelper.GetBenchmarkAttributeTypeSymbol(context.Compilation);\r\n        if (benchmarkAttributeTypeSymbol == null)\r\n        {\r\n            return;\r\n        }\r\n\r\n        var benchmarkCategoryAttributeTypeSymbol = GetBenchmarkCategoryAttributeTypeSymbol(context.Compilation);\r\n        if (benchmarkCategoryAttributeTypeSymbol == null)\r\n        {\r\n            return;\r\n        }\r\n\r\n        var hasBenchmarkMethods = false;\r\n        var nullBenchmarkCategoryBenchmarkAttributeBaselineLocations = new List<Location>();\r\n        var benchmarkCategoryBenchmarkAttributeBaselineLocations = new Dictionary<string, List<Location>>();\r\n\r\n        foreach (var memberDeclarationSyntax in classDeclarationSyntax.Members)\r\n        {\r\n            var hasBenchmarkCategoryCompilerDiagnostics = false;\r\n            var benchmarkCategories = new List<string?>();\r\n            var benchmarkAttributeUsages = new List<AttributeSyntax>();\r\n\r\n            if (memberDeclarationSyntax is MethodDeclarationSyntax methodDeclarationSyntax)\r\n            {\r\n                foreach (var attributeListSyntax in methodDeclarationSyntax.AttributeLists)\r\n                {\r\n                    foreach (var attributeSyntax in attributeListSyntax.Attributes)\r\n                    {\r\n                        var attributeSyntaxTypeSymbol = context.SemanticModel.GetTypeInfo(attributeSyntax).Type;\r\n                        if (attributeSyntaxTypeSymbol == null)\r\n                        {\r\n                            continue;\r\n                        }\r\n\r\n                        if (SymbolEqualityComparer.Default.Equals(attributeSyntaxTypeSymbol, benchmarkAttributeTypeSymbol))\r\n                        {\r\n                            benchmarkAttributeUsages.Add(attributeSyntax);\r\n                        }\r\n                        else if (SymbolEqualityComparer.Default.Equals(attributeSyntaxTypeSymbol, benchmarkCategoryAttributeTypeSymbol))\r\n                        {\r\n                            if (attributeSyntax.ArgumentList is { Arguments.Count: 1 })\r\n                            {\r\n                                // Check if this is an explicit params array creation\r\n\r\n                                Optional<object?> constantValue;\r\n\r\n#if CODE_ANALYSIS_4_8\r\n                                // Collection expression\r\n                                if (attributeSyntax.ArgumentList.Arguments[0].Expression is CollectionExpressionSyntax collectionExpressionSyntax)\r\n                                {\r\n                                    foreach (var collectionElementSyntax in collectionExpressionSyntax.Elements)\r\n                                    {\r\n                                        if (collectionElementSyntax is ExpressionElementSyntax expressionElementSyntax)\r\n                                        {\r\n                                            constantValue = context.SemanticModel.GetConstantValue(expressionElementSyntax.Expression);\r\n                                            if (constantValue.HasValue)\r\n                                            {\r\n                                                if (constantValue.Value is string benchmarkCategoryValue)\r\n                                                {\r\n                                                    benchmarkCategories.Add(benchmarkCategoryValue);\r\n                                                }\r\n                                                else if (constantValue.Value is null)\r\n                                                {\r\n                                                    benchmarkCategories.Add(null);\r\n                                                }\r\n                                            }\r\n                                            else\r\n                                            {\r\n                                                hasBenchmarkCategoryCompilerDiagnostics = true;\r\n\r\n                                                break;\r\n                                            }\r\n                                        }\r\n                                    }\r\n\r\n                                    continue;\r\n                                }\r\n#endif\r\n\r\n                                // Array creation expression\r\n\r\n                                var attributeArgumentSyntaxValueType = context.SemanticModel.GetTypeInfo(attributeSyntax.ArgumentList.Arguments[0].Expression).Type;\r\n                                if (attributeArgumentSyntaxValueType is IArrayTypeSymbol arrayTypeSymbol)\r\n                                {\r\n                                    if (arrayTypeSymbol.ElementType.SpecialType == SpecialType.System_String)\r\n                                    {\r\n                                        if (attributeSyntax.ArgumentList.Arguments[0].Expression is ArrayCreationExpressionSyntax arrayCreationExpressionSyntax)\r\n                                        {\r\n                                            if (arrayCreationExpressionSyntax.Initializer != null)\r\n                                            {\r\n                                                foreach (var expressionSyntax in arrayCreationExpressionSyntax.Initializer.Expressions)\r\n                                                {\r\n                                                    constantValue = context.SemanticModel.GetConstantValue(expressionSyntax);\r\n                                                    if (constantValue.HasValue)\r\n                                                    {\r\n                                                        if (constantValue.Value is string benchmarkCategoryValue)\r\n                                                        {\r\n                                                            benchmarkCategories.Add(benchmarkCategoryValue);\r\n                                                        }\r\n                                                        else if (constantValue.Value is null)\r\n                                                        {\r\n                                                            benchmarkCategories.Add(null);\r\n                                                        }\r\n                                                    }\r\n                                                    else\r\n                                                    {\r\n                                                        hasBenchmarkCategoryCompilerDiagnostics = true;\r\n\r\n                                                        break;\r\n                                                    }\r\n                                                }\r\n                                            }\r\n                                        }\r\n                                    }\r\n\r\n                                    continue;\r\n                                }\r\n\r\n                                // Params value\r\n\r\n                                constantValue = context.SemanticModel.GetConstantValue(attributeSyntax.ArgumentList.Arguments[0].Expression);\r\n                                if (constantValue.HasValue)\r\n                                {\r\n                                    if (constantValue.Value is null)\r\n                                    {\r\n                                        hasBenchmarkCategoryCompilerDiagnostics = true;\r\n                                    }\r\n                                    else if (constantValue.Value is string benchmarkCategoryValue)\r\n                                    {\r\n                                        benchmarkCategories.Add(benchmarkCategoryValue);\r\n                                    }\r\n                                }\r\n                            }\r\n                            else if (attributeSyntax.ArgumentList is { Arguments.Count: > 1 })\r\n                            {\r\n                                // Params values\r\n\r\n                                foreach (var parameterValueAttributeArgumentSyntax in attributeSyntax.ArgumentList.Arguments)\r\n                                {\r\n                                    var constantValue = context.SemanticModel.GetConstantValue(parameterValueAttributeArgumentSyntax.Expression);\r\n                                    if (constantValue.HasValue)\r\n                                    {\r\n                                        if (constantValue.Value is string benchmarkCategoryValue)\r\n                                        {\r\n                                            benchmarkCategories.Add(benchmarkCategoryValue);\r\n                                        }\r\n                                        else if (constantValue.Value is null)\r\n                                        {\r\n                                            benchmarkCategories.Add(null);\r\n                                        }\r\n                                    }\r\n                                    else\r\n                                    {\r\n                                        hasBenchmarkCategoryCompilerDiagnostics = true;\r\n\r\n                                        break;\r\n                                    }\r\n                                }\r\n                            }\r\n                        }\r\n                    }\r\n                }\r\n\r\n                if (benchmarkAttributeUsages.Count == 1)\r\n                {\r\n                    hasBenchmarkMethods = true;\r\n\r\n                    if (!methodDeclarationSyntax.Modifiers.Any(SyntaxKind.PublicKeyword))\r\n                    {\r\n                        context.ReportDiagnostic(Diagnostic.Create(MethodMustBePublicRule, methodDeclarationSyntax.Identifier.GetLocation(), methodDeclarationSyntax.Identifier.ToString()));\r\n                    }\r\n\r\n                    if (methodDeclarationSyntax.TypeParameterList != null)\r\n                    {\r\n                        context.ReportDiagnostic(Diagnostic.Create(MethodMustBeNonGenericRule, methodDeclarationSyntax.TypeParameterList.GetLocation(), methodDeclarationSyntax.Identifier.ToString()));\r\n                    }\r\n\r\n                    if (!hasBenchmarkCategoryCompilerDiagnostics)\r\n                    {\r\n                        if (benchmarkCategories.Count > 0 && benchmarkAttributeUsages[0].ArgumentList != null)\r\n                        {\r\n                            foreach (var attributeArgumentSyntax in benchmarkAttributeUsages[0].ArgumentList!.Arguments)\r\n                            {\r\n                                if (attributeArgumentSyntax.NameEquals != null && attributeArgumentSyntax.NameEquals.Name.Identifier.ValueText == \"Baseline\")\r\n                                {\r\n                                    var constantValue = context.SemanticModel.GetConstantValue(attributeArgumentSyntax.Expression);\r\n                                    if (constantValue is { HasValue: true, Value: true })\r\n                                    {\r\n                                        var benchmarkCategoryFormatted = FormatBenchmarkCategory(benchmarkCategories);\r\n                                        var baselineLocation = attributeArgumentSyntax.GetLocation();\r\n\r\n                                        if (benchmarkCategoryBenchmarkAttributeBaselineLocations.TryGetValue(benchmarkCategoryFormatted, out var baselineLocationsPerUniqueBenchmarkCategory))\r\n                                        {\r\n                                            baselineLocationsPerUniqueBenchmarkCategory.Add(baselineLocation);\r\n                                        }\r\n                                        else\r\n                                        {\r\n                                            benchmarkCategoryBenchmarkAttributeBaselineLocations[benchmarkCategoryFormatted] = [baselineLocation];\r\n                                        }\r\n                                    }\r\n                                }\r\n                            }\r\n                        }\r\n                        else\r\n                        {\r\n                            if (benchmarkAttributeUsages[0].ArgumentList != null)\r\n                            {\r\n                                foreach (var attributeArgumentSyntax in benchmarkAttributeUsages[0].ArgumentList!.Arguments)\r\n                                {\r\n                                    if (attributeArgumentSyntax.NameEquals != null && attributeArgumentSyntax.NameEquals.Name.Identifier.ValueText == \"Baseline\")\r\n                                    {\r\n                                        var constantValue = context.SemanticModel.GetConstantValue(attributeArgumentSyntax.Expression);\r\n                                        if (constantValue is { HasValue: true, Value: true })\r\n                                        {\r\n                                            nullBenchmarkCategoryBenchmarkAttributeBaselineLocations.Add(attributeArgumentSyntax.GetLocation());\r\n                                        }\r\n                                    }\r\n                                }\r\n                            }\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        if (hasBenchmarkMethods)\r\n        {\r\n            if (classStaticModifier.HasValue)\r\n            {\r\n                context.ReportDiagnostic(Diagnostic.Create(ClassMustBeNonStaticRule, classStaticModifier.Value.GetLocation(), classDeclarationSyntax.Identifier.ToString()));\r\n            }\r\n\r\n            if (nullBenchmarkCategoryBenchmarkAttributeBaselineLocations.Count >= 2)\r\n            {\r\n                foreach (var baselineLocation in nullBenchmarkCategoryBenchmarkAttributeBaselineLocations)\r\n                {\r\n                    context.ReportDiagnostic(Diagnostic.Create(OnlyOneMethodCanBeBaselineRule, baselineLocation));\r\n                }\r\n            }\r\n\r\n            var singularBenchmarkCategoryBenchmarkAttributeBaselineLocations = new Dictionary<string, List<Location>>(benchmarkCategoryBenchmarkAttributeBaselineLocations);\r\n\r\n            foreach (var (benchmarkCategory, baselineLocations) in benchmarkCategoryBenchmarkAttributeBaselineLocations)\r\n            {\r\n                if (baselineLocations.Count > 1)\r\n                {\r\n                    foreach (var baselineLocation in baselineLocations)\r\n                    {\r\n                        context.ReportDiagnostic(Diagnostic.Create(OnlyOneMethodCanBeBaselinePerCategoryRule, baselineLocation));\r\n                    }\r\n\r\n                    singularBenchmarkCategoryBenchmarkAttributeBaselineLocations.Remove(benchmarkCategory);\r\n                }\r\n            }\r\n\r\n            if (nullBenchmarkCategoryBenchmarkAttributeBaselineLocations.Count == 1 || singularBenchmarkCategoryBenchmarkAttributeBaselineLocations.Count > 0)\r\n            {\r\n                var hasDuplicateBaselineBenchmarkMethodNullCategories = false;\r\n                var duplicateBaselineBenchmarkMethodCategories = new HashSet<string>();\r\n\r\n                var benchmarkClassTypeSymbol = context.SemanticModel.GetDeclaredSymbol(classDeclarationSyntax);\r\n                if (benchmarkClassTypeSymbol is { TypeKind: TypeKind.Class })\r\n                {\r\n                    var baseType = benchmarkClassTypeSymbol.OriginalDefinition.BaseType;\r\n\r\n                    while (baseType != null && baseType.SpecialType != SpecialType.System_Object)\r\n                    {\r\n                        foreach (var member in baseType.GetMembers())\r\n                        {\r\n                            var hasBenchmarkCategoryCompilerDiagnostics = false;\r\n                            var benchmarkCategories = new List<string?>();\r\n                            var benchmarkAttributeUsages = new List<AttributeData>();\r\n\r\n                            if (member is IMethodSymbol { MethodKind: MethodKind.Ordinary } methodSymbol)\r\n                            {\r\n                                var methodAttributes = methodSymbol.GetAttributes();\r\n\r\n                                foreach (var attribute in methodAttributes)\r\n                                {\r\n                                    if (SymbolEqualityComparer.Default.Equals(attribute.AttributeClass, benchmarkAttributeTypeSymbol))\r\n                                    {\r\n                                        benchmarkAttributeUsages.Add(attribute);\r\n                                    }\r\n                                    else if (SymbolEqualityComparer.Default.Equals(attribute.AttributeClass, benchmarkCategoryAttributeTypeSymbol))\r\n                                    {\r\n                                        foreach (var benchmarkCategoriesArray in attribute.ConstructorArguments)\r\n                                        {\r\n                                            if (!benchmarkCategoriesArray.IsNull)\r\n                                            {\r\n                                                foreach (var benchmarkCategory in benchmarkCategoriesArray.Values)\r\n                                                {\r\n                                                    if (benchmarkCategory.Kind == TypedConstantKind.Primitive)\r\n                                                    {\r\n                                                        if (benchmarkCategory.Value == null)\r\n                                                        {\r\n                                                            benchmarkCategories.Add(null);\r\n                                                        }\r\n                                                        else if (benchmarkCategory.Value is string benchmarkCategoryValue)\r\n                                                        {\r\n                                                            benchmarkCategories.Add(benchmarkCategoryValue);\r\n                                                        }\r\n                                                    }\r\n                                                    else\r\n                                                    {\r\n                                                        hasBenchmarkCategoryCompilerDiagnostics = true;\r\n\r\n                                                        break;\r\n                                                    }\r\n                                                }\r\n                                            }\r\n                                        }\r\n                                    }\r\n                                }\r\n                            }\r\n\r\n                            if (benchmarkAttributeUsages.Count == 1)\r\n                            {\r\n                                if (!hasBenchmarkCategoryCompilerDiagnostics)\r\n                                {\r\n                                    if (benchmarkCategories.Count > 0)\r\n                                    {\r\n                                        var benchmarkCategoryFormatted = FormatBenchmarkCategory(benchmarkCategories);\r\n                                        if (singularBenchmarkCategoryBenchmarkAttributeBaselineLocations.ContainsKey(benchmarkCategoryFormatted))\r\n                                        {\r\n                                            if (!duplicateBaselineBenchmarkMethodCategories.Contains(benchmarkCategoryFormatted))\r\n                                            {\r\n                                                if (benchmarkAttributeUsages[0].NamedArguments.Any(na => na is { Key: \"Baseline\", Value.Value: true }))\r\n                                                {\r\n                                                    duplicateBaselineBenchmarkMethodCategories.Add(benchmarkCategoryFormatted);\r\n                                                }\r\n                                            }\r\n                                        }\r\n                                    }\r\n                                    else\r\n                                    {\r\n                                        if (nullBenchmarkCategoryBenchmarkAttributeBaselineLocations.Count == 1\r\n                                            && !hasDuplicateBaselineBenchmarkMethodNullCategories\r\n                                            && benchmarkAttributeUsages[0].NamedArguments.Any(na => na is { Key: \"Baseline\", Value.Value: true }))\r\n                                        {\r\n                                            hasDuplicateBaselineBenchmarkMethodNullCategories = true;\r\n                                        }\r\n                                    }\r\n                                }\r\n                            }\r\n                        }\r\n\r\n                        baseType = baseType.OriginalDefinition.BaseType;\r\n                    }\r\n                }\r\n\r\n                if (nullBenchmarkCategoryBenchmarkAttributeBaselineLocations.Count == 1 && hasDuplicateBaselineBenchmarkMethodNullCategories)\r\n                {\r\n                    context.ReportDiagnostic(Diagnostic.Create(OnlyOneMethodCanBeBaselineRule, nullBenchmarkCategoryBenchmarkAttributeBaselineLocations[0]));\r\n                }\r\n\r\n                foreach (var duplicateBaselineBenchmarkMethodCategory in duplicateBaselineBenchmarkMethodCategories)\r\n                {\r\n                    if (singularBenchmarkCategoryBenchmarkAttributeBaselineLocations.TryGetValue(duplicateBaselineBenchmarkMethodCategory, out var baselineLocations))\r\n                    {\r\n                        context.ReportDiagnostic(Diagnostic.Create(OnlyOneMethodCanBeBaselinePerCategoryRule, baselineLocations[0]));\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    private static void AnalyzeAttributeSyntax(SyntaxNodeAnalysisContext context)\r\n    {\r\n        if (context.Node is not AttributeSyntax attributeSyntax)\r\n        {\r\n            return;\r\n        }\r\n\r\n        var benchmarkCategoryAttributeTypeSymbol = GetBenchmarkCategoryAttributeTypeSymbol(context.Compilation);\r\n\r\n        var attributeTypeSymbol = context.SemanticModel.GetTypeInfo(attributeSyntax).Type;\r\n        if (SymbolEqualityComparer.Default.Equals(attributeTypeSymbol, benchmarkCategoryAttributeTypeSymbol))\r\n        {\r\n            if (attributeSyntax.ArgumentList is { Arguments.Count: 1 })\r\n            {\r\n                var argumentSyntax = attributeSyntax.ArgumentList.Arguments[0];\r\n\r\n                var constantValue = context.SemanticModel.GetConstantValue(argumentSyntax.Expression);\r\n                if (constantValue is { HasValue: true, Value: null })\r\n                {\r\n                    context.ReportDiagnostic(Diagnostic.Create(SingleNullArgumentToBenchmarkCategoryAttributeNotAllowedRule, argumentSyntax.GetLocation()));\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    private static INamedTypeSymbol? GetBenchmarkCategoryAttributeTypeSymbol(Compilation compilation) => compilation.GetTypeByMetadataName(\"BenchmarkDotNet.Attributes.BenchmarkCategoryAttribute\");\r\n\r\n    private static string FormatBenchmarkCategory(List<string?> benchmarkCategories)\r\n    {\r\n        // Default ICategoryDiscoverer implementation: DefaultCategoryDiscoverer\r\n\r\n        return string.Join(\",\", benchmarkCategories.Distinct(StringComparer.OrdinalIgnoreCase));\r\n    }\r\n}"
  },
  {
    "path": "src/BenchmarkDotNet.Annotations/Attributes/ArgumentsAttribute.cs",
    "content": "﻿using JetBrains.Annotations;\nusing System;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]\n    public class ArgumentsAttribute : PriorityAttribute\n    {\n        public object?[] Values { get; }\n\n        // CLS-Compliant Code requires a constructor without an array in the argument list\n        [PublicAPI]\n        public ArgumentsAttribute() => Values = [];\n\n        public ArgumentsAttribute(params object?[]? values)\n            => Values = values ?? [null]; // when users do Arguments(null) they mean one, null argument\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet.Annotations/Attributes/ArgumentsSourceAttribute.cs",
    "content": "using System;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]\n    public class ArgumentsSourceAttribute : PriorityAttribute\n    {\n        public string Name { get; }\n        public Type? Type { get; }\n\n        public ArgumentsSourceAttribute(string name)\n        {\n            Name = name;\n            Type = null;\n        }\n\n        public ArgumentsSourceAttribute(Type type, string name)\n        {\n            Name = name;\n            Type = type;\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet.Annotations/Attributes/BenchmarkAttribute.cs",
    "content": "﻿using System;\nusing System.Runtime.CompilerServices;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    [AttributeUsage(AttributeTargets.Method)]\n    [MeansImplicitUse]\n    public class BenchmarkAttribute : Attribute\n    {\n        public BenchmarkAttribute([CallerLineNumber] int sourceCodeLineNumber = 0, [CallerFilePath] string sourceCodeFile = \"\")\n        {\n            SourceCodeLineNumber = sourceCodeLineNumber;\n            SourceCodeFile = sourceCodeFile;\n        }\n\n        public string? Description { get; set; }\n\n        public bool Baseline { get; set; }\n\n        public int OperationsPerInvoke { get; set; } = 1;\n\n        public int SourceCodeLineNumber { get; }\n\n        public string SourceCodeFile { get; }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet.Annotations/Attributes/BenchmarkCategoryAttribute.cs",
    "content": "using JetBrains.Annotations;\nusing System;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Assembly, AllowMultiple = true)]\n    public class BenchmarkCategoryAttribute : Attribute\n    {\n        public string[] Categories { get; }\n\n        // CLS-Compliant Code requires a constructor without an array in the argument list\n        [PublicAPI] protected BenchmarkCategoryAttribute() => Categories = [];\n\n        public BenchmarkCategoryAttribute(params string[] categories) => Categories = categories;\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet.Annotations/Attributes/GenericTypeArgumentsAttribute.cs",
    "content": "﻿using System;\nusing System.Diagnostics.CodeAnalysis;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]\n    public class GenericTypeArgumentsAttribute : Attribute\n    {\n        public Type[] GenericTypeArguments { get; }\n\n        public GenericTypeArgumentsAttribute([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type type)\n            => GenericTypeArguments = [type];\n\n        public GenericTypeArgumentsAttribute(\n            [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type type1,\n            [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type type2)\n            => GenericTypeArguments = [type1, type2];\n\n        public GenericTypeArgumentsAttribute(\n            [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type type1,\n            [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type type2,\n            [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type type3)\n            => GenericTypeArguments = [type1, type2, type3];\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet.Annotations/Attributes/GlobalCleanupAttribute.cs",
    "content": "using System;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    /// <summary>\n    /// Marks method to be executed after all benchmark iterations.\n    /// <remarks>It's going to be executed only once, after all benchmark runs.</remarks>\n    /// </summary>\n    [AttributeUsage(AttributeTargets.Method)]\n    [MeansImplicitUse]\n    public class GlobalCleanupAttribute : TargetedAttribute\n    {\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet.Annotations/Attributes/GlobalSetupAttribute.cs",
    "content": "using System;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    /// <summary>\n    /// Marks method to be executed before all benchmark iterations.\n    /// <remarks>It's going to be executed only once, just before warm up.</remarks>\n    /// </summary>\n    [AttributeUsage(AttributeTargets.Method)]\n    [MeansImplicitUse]\n    public class GlobalSetupAttribute : TargetedAttribute\n    {\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet.Annotations/Attributes/IterationCleanupAttribute.cs",
    "content": "using System;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    /// <summary>\n    /// Marks method to be executed after each benchmark iteration. This should NOT be used for microbenchmarks - please see the docs.\n    /// </summary>\n    [AttributeUsage(AttributeTargets.Method)]\n    [MeansImplicitUse]\n    public class IterationCleanupAttribute : TargetedAttribute\n    {\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet.Annotations/Attributes/IterationSetupAttribute.cs",
    "content": "using System;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    /// <summary>\n    /// Marks method to be executed before each benchmark iteration. This should NOT be used for microbenchmarks - please see the docs.\n    /// </summary>\n    [AttributeUsage(AttributeTargets.Method)]\n    [MeansImplicitUse]\n    public class IterationSetupAttribute : TargetedAttribute\n    {\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet.Annotations/Attributes/ParamsAllValuesAttribute.cs",
    "content": "﻿using System;\nnamespace BenchmarkDotNet.Attributes\n{\n    [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]\n    public class ParamsAllValuesAttribute : PriorityAttribute\n    {\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet.Annotations/Attributes/ParamsAttribute.cs",
    "content": "﻿using System;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]\n    public class ParamsAttribute : PriorityAttribute\n    {\n        public object?[] Values { get; protected set; }\n\n        // CLS-Compliant Code requires a constructor without an array in the argument list\n        public ParamsAttribute() => Values = [];\n\n        public ParamsAttribute(params object?[]? values)\n            => Values = values ?? [null]; // when users do Params(null) they mean one, null argument\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet.Annotations/Attributes/ParamsSourceAttribute.cs",
    "content": "using System;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]\n    public class ParamsSourceAttribute : PriorityAttribute\n    {\n        public string Name { get; }\n        public Type? Type { get; }\n\n        public ParamsSourceAttribute(string name)\n        {\n            Name = name;\n            Type = null;\n        }\n\n        public ParamsSourceAttribute(Type type, string name)\n        {\n            Name = name;\n            Type = type;\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet.Annotations/Attributes/PriorityAttribute.cs",
    "content": "﻿using System;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    public abstract class PriorityAttribute : Attribute\n    {\n        /// <summary>\n        /// Defines display order of column in the same category.\n        /// </summary>\n        public int Priority { get; set; } = 0;\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet.Annotations/Attributes/TargetedAttribute.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing System.Reflection;\n\nnamespace BenchmarkDotNet.Attributes\n{\n    /// <summary>\n    /// Base class for attributes that are targeted at one or more method(s)\n    /// </summary>\n    public abstract class TargetedAttribute : Attribute\n    {\n        public string[] Targets { get; set; } = [];\n\n        /// <summary>\n        /// Target method for attribute\n        /// </summary>\n        public string Target\n        {\n            get => throw new InvalidOperationException(\"Please use Targets property\"); // kept to keep compiler happy \"Named attribute arguments must be fields which are not readonly, static, or const, or read-write properties which are public and not static.\"\n            set => Targets = string.IsNullOrEmpty(value) ? [] : value.Split(','); // , is for backward compat\n        }\n\n        public bool Match(MethodInfo method) => Targets.Length == 0 || Targets.Contains(method.Name);\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet.Annotations/BenchmarkDotNet.Annotations.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\n  <Import Project=\"..\\..\\build\\common.props\" />\n  <PropertyGroup>\n    <AssemblyTitle>Basic BenchmarkDotNet attributes that can be used to annotate your benchmarks</AssemblyTitle>\n    <TargetFrameworks>netstandard2.0</TargetFrameworks>\n    <NoWarn>$(NoWarn);1701;1702;1705;1591;3005;NU1702;NU5100;CA1825</NoWarn>\n    <AssemblyName>BenchmarkDotNet.Annotations</AssemblyName>\n    <PackageId>BenchmarkDotNet.Annotations</PackageId>\n    <RootNamespace>BenchmarkDotNet</RootNamespace>\n    <!-- needed for docfx xref resolver -->\n    <ProduceReferenceAssembly>True</ProduceReferenceAssembly>\n  </PropertyGroup>\n  <!-- Settings for PolySharp -->\n  <PropertyGroup>\n    <PolySharpIncludeGeneratedTypes>\n      System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute,\n      System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes\n    </PolySharpIncludeGeneratedTypes>\n  </PropertyGroup>\n  <ItemGroup>\n    <PackageReference Include=\"PolySharp\" Version=\"1.15.0\">\n      <PrivateAssets>all</PrivateAssets>\n      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\n    </PackageReference>\n  </ItemGroup>\n  <ItemGroup>\n    <Compile Include=\"..\\BenchmarkDotNet\\Helpers\\CodeAnnotations.cs\" Link=\"Attributes\\CodeAnnotations.cs\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <Content Include=\"..\\BenchmarkDotNet.Analyzers\\bin\\$(Configuration)\\**\\*.dll\" Pack=\"true\" PackagePath=\"analyzers/dotnet/\" Visible=\"false\" />\n  </ItemGroup>\n  \n  <Choose>\n    <When Condition=\"'$(IsFullPack)' == 'true'\">\n      <ItemGroup>\n        <!-- Include the BenchmarkDotNet.Weaver dlls in tasks without making it an explicit dependency. -->\n        <Content Include=\"$(MSBuildThisFileDirectory)..\\BenchmarkDotNet.Weaver\\bin\\Release\\$(TargetFramework)\\**\\*.dll\" Pack=\"true\" PackagePath=\"tasks/$(TargetFramework)\" />\n        <Content Include=\"$(MSBuildThisFileDirectory)buildTransitive\\**\\*.targets\" Pack=\"true\" PackagePath=\"buildTransitive\" />\n      </ItemGroup>\n    </When>\n    <Otherwise>\n      <!-- PackageReference for transitive weaver dependency for ProjectReferences to this. -->\n      <ItemGroup>\n        <PackageReference Include=\"BenchmarkDotNet.Weaver\" Version=\"$(Version)$(WeaverVersionSuffix)\" />\n      </ItemGroup>\n    </Otherwise>\n  </Choose>\n  <Import Project=\"..\\..\\build\\common.targets\" />\n</Project>"
  },
  {
    "path": "src/BenchmarkDotNet.Annotations/Jobs/RuntimeMoniker.cs",
    "content": "using System;\n\nnamespace BenchmarkDotNet.Jobs\n{\n    public enum RuntimeMoniker\n    {\n        /// <summary>\n        /// the same Runtime as the host Process (default setting)\n        /// </summary>\n        HostProcess = 0,\n\n        /// <summary>\n        /// not recognized, possibly a new version of .NET Core\n        /// </summary>\n        NotRecognized,\n\n        /// <summary>\n        /// Mono\n        /// </summary>\n        Mono,\n\n        /// <summary>\n        /// .NET 4.6.1\n        /// </summary>\n        Net461,\n\n        /// <summary>\n        /// .NET 4.6.2\n        /// </summary>\n        Net462,\n\n        /// <summary>\n        /// .NET 4.7\n        /// </summary>\n        Net47,\n\n        /// <summary>\n        /// .NET 4.7.1\n        /// </summary>\n        Net471,\n\n        /// <summary>\n        /// .NET 4.7.2\n        /// </summary>\n        Net472,\n\n        /// <summary>\n        /// .NET 4.8\n        /// </summary>\n        Net48,\n\n        /// <summary>\n        /// .NET 4.8.1\n        /// </summary>\n        Net481,\n\n        /// <summary>\n        /// .NET Core 2.0\n        /// </summary>\n        NetCoreApp20,\n\n        /// <summary>\n        /// .NET Core 2.1\n        /// </summary>\n        NetCoreApp21,\n\n        /// <summary>\n        /// .NET Core 2.2\n        /// </summary>\n        NetCoreApp22,\n\n        /// <summary>\n        /// .NET Core 3.0\n        /// </summary>\n        NetCoreApp30,\n\n        /// <summary>\n        /// .NET Core 3.1\n        /// </summary>\n        NetCoreApp31,\n\n        /// <summary>\n        /// .NET 5.0\n        /// </summary>\n        Net50, // it's after NetCoreApp50 in the enum definition because the value of enumeration is used for framework version comparison using > < operators\n\n        /// <summary>\n        /// .NET 6.0\n        /// </summary>\n        Net60,\n\n        /// <summary>\n        /// .NET 7.0\n        /// </summary>\n        Net70,\n\n        /// <summary>\n        /// .NET 8.0\n        /// </summary>\n        Net80,\n\n        /// <summary>\n        /// .NET 9.0\n        /// </summary>\n        Net90,\n\n        /// <summary>\n        /// .NET 10.0\n        /// </summary>\n        Net10_0,\n\n        /// <summary>\n        /// .NET 11.0\n        /// </summary>\n        Net11_0,\n\n        /// <summary>\n        /// NativeAOT compiled as net6.0\n        /// </summary>\n        NativeAot60,\n\n        /// <summary>\n        /// NativeAOT compiled as net7.0\n        /// </summary>\n        NativeAot70,\n\n        /// <summary>\n        /// NativeAOT compiled as net8.0\n        /// </summary>\n        NativeAot80,\n\n        /// <summary>\n        /// NativeAOT compiled as net9.0\n        /// </summary>\n        NativeAot90,\n\n        /// <summary>\n        /// NativeAOT compiled as net10.0\n        /// </summary>\n        NativeAot10_0,\n\n        /// <summary>\n        /// NativeAOT compiled as net11.0\n        /// </summary>\n        NativeAot11_0,\n\n        /// <summary>\n        /// WebAssembly with net8.0\n        /// </summary>\n        WasmNet80,\n\n        /// <summary>\n        /// WebAssembly with net9.0\n        /// </summary>\n        WasmNet90,\n\n        /// <summary>\n        /// WebAssembly with net10.0\n        /// </summary>\n        WasmNet10_0,\n\n        /// <summary>\n        /// WebAssembly with net11.0\n        /// </summary>\n        WasmNet11_0,\n\n        /// <summary>\n        /// Mono with the Ahead of Time LLVM Compiler backend\n        /// </summary>\n        MonoAOTLLVM,\n\n        /// <summary>\n        /// Mono with the Ahead of Time LLVM Compiler backend and net6.0\n        /// </summary>\n        MonoAOTLLVMNet60,\n\n        /// <summary>\n        /// Mono with the Ahead of Time LLVM Compiler backend and net7.0\n        /// </summary>\n        MonoAOTLLVMNet70,\n\n        /// <summary>\n        /// Mono with the Ahead of Time LLVM Compiler backend and net8.0\n        /// </summary>\n        MonoAOTLLVMNet80,\n\n        /// <summary>\n        /// Mono with the Ahead of Time LLVM Compiler backend and net9.0\n        /// </summary>\n        MonoAOTLLVMNet90,\n\n        /// <summary>\n        /// Mono with the Ahead of Time LLVM Compiler backend and net10.0\n        /// </summary>\n        MonoAOTLLVMNet10_0,\n\n        /// <summary>\n        /// Mono with the Ahead of Time LLVM Compiler backend and net11.0\n        /// </summary>\n        MonoAOTLLVMNet11_0,\n\n        /// <summary>\n        /// .NET 6 using MonoVM (not CLR which is the default)\n        /// </summary>\n        Mono60,\n\n        /// <summary>\n        /// .NET 7 using MonoVM (not CLR which is the default)\n        /// </summary>\n        Mono70,\n\n        /// <summary>\n        /// .NET 8 using MonoVM (not CLR which is the default)\n        /// </summary>\n        Mono80,\n\n        /// <summary>\n        /// .NET 8 CLR with composite ReadyToRun compilation\n        /// </summary>\n        R2R80,\n\n        /// <summary>\n        /// .NET 9 CLR with composite ReadyToRun compilation\n        /// </summary>\n        R2R90,\n\n        /// <summary>\n        /// .NET 10 CLR with composite ReadyToRun compilation\n        /// </summary>\n        R2R10_0,\n\n        /// <summary>\n        /// .NET 11 CLR with composite ReadyToRun compilation\n        /// </summary>\n        R2R11_0,\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet.Annotations/buildTransitive/netstandard2.0/BenchmarkDotNet.Annotations.targets",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup>\n    <Reference Include=\"BenchmarkDotNet.Annotations\">\n      <HintPath>$(MSBuildThisFileDirectory)..\\..\\lib\\netstandard2.0\\BenchmarkDotNet.Annotations.dll</HintPath>\n    </Reference>\n  </ItemGroup>\n\n  <UsingTask TaskName=\"BenchmarkDotNet.Weaver.WeaveAssemblyTask\" AssemblyFile=\"$(MSBuildThisFileDirectory)..\\..\\tasks\\netstandard2.0\\BenchmarkDotNet.Weaver.dll\" />\n\n  <Target Name=\"WeaveAssemblies\" AfterTargets=\"AfterBuild\" >\n    <WeaveAssemblyTask TargetAssembly=\"$(TargetDir)$(TargetFileName)\" ReferencePaths=\"@(ReferencePath)\" />\n  </Target>\n</Project>"
  },
  {
    "path": "src/BenchmarkDotNet.Diagnostics.Windows/BenchmarkDotNet.Diagnostics.Windows.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\n  <Import Project=\"..\\..\\build\\common.props\" />\n  <PropertyGroup>\n    <Description>Powerful .NET library for benchmarking (Diagnostic Tools for Windows)</Description>\n    <AssemblyTitle>BenchmarkDotNet.Diagnostics.Windows</AssemblyTitle>\n    <TargetFramework>netstandard2.0</TargetFramework>\n    <NoWarn>1701;1702;1705;1591;3001;3003;3002;3009</NoWarn>\n    <AssemblyName>BenchmarkDotNet.Diagnostics.Windows</AssemblyName>\n    <PackageId>BenchmarkDotNet.Diagnostics.Windows</PackageId>\n  </PropertyGroup>\n  <ItemGroup>\n    <ProjectReference Include=\"..\\BenchmarkDotNet\\BenchmarkDotNet.csproj\" />\n  </ItemGroup>\n  <ItemGroup>\n    <PackageReference Include=\"Microsoft.Diagnostics.Tracing.TraceEvent\" Version=\"3.1.30\" PrivateAssets=\"contentfiles;analyzers\" />\n  </ItemGroup>\n  <Import Project=\"..\\..\\build\\common.targets\" />\n</Project>\n"
  },
  {
    "path": "src/BenchmarkDotNet.Diagnostics.Windows/ConcurrencyVisualizerProfiler.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing BenchmarkDotNet.Analysers;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Diagnosers;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Exporters;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Validators;\nusing JetBrains.Annotations;\nusing Microsoft.Diagnostics.Tracing;\nusing Microsoft.Diagnostics.Tracing.Parsers;\nusing Microsoft.Diagnostics.Tracing.Parsers.Kernel;\nusing Microsoft.Diagnostics.Tracing.Session;\n\nnamespace BenchmarkDotNet.Diagnostics.Windows\n{\n    /// <summary>\n    /// a plugin which uses EtwProfiler to mimic the behavior of CVCollectionService.exe to produce not only an ETW trace file\n    /// but also a CVTrace file which can be opened by Concurrency Visualizer plugin from Visual Studio\n    /// </summary>\n    public class ConcurrencyVisualizerProfiler : IProfiler\n    {\n        // following constants come from the decompiled \"Microsoft.ConcurrencyVisualizer.Common.MarkerProviderConstants\"\n        private static readonly Guid PlinqId = new Guid(\"159eeeec-4a14-4418-a8fe-faabcd987887\"); // \"System.Linq.Parallel\";\n        private static readonly Guid TplDataflowId = new Guid(\"16f53577-e41d-43d4-b47e-c17025bf4025\"); // \"System.Threading.Tasks.Dataflow\";\n        private static readonly Guid TplSynchronizationId = new Guid(\"ec631d38-466b-4290-9306-834971ba0217\"); // \"System.Threading.Synchronization\";\n        private static readonly Guid ManagedConcurrentCollectionsId = new Guid(\"35167F8E-49B2-4B96-AB86-435B59336B5E\"); // \"System.Collections.Concurrent\";\n        private static readonly Guid ConcurrencyVisualizerMarkersId = new Guid(\"8D4925AB-505A-483b-A7E0-6F824A07A6F0\"); // \"ConcurrencyVisualizer.Markers\";\n\n        private readonly EtwProfiler etwProfiler;\n        private readonly Dictionary<BenchmarkCase, string> benchmarkToCvTraceFile = [];\n        private readonly Dictionary<BenchmarkCase, int> benchmarkToProcessId = [];\n\n        [PublicAPI] // parameterless ctor required by DiagnosersLoader to support creating this profiler via console line args\n        public ConcurrencyVisualizerProfiler() => etwProfiler = new EtwProfiler(CreateDefaultConfig());\n\n        [PublicAPI]\n        public ConcurrencyVisualizerProfiler(EtwProfilerConfig config) => etwProfiler = new EtwProfiler(config);\n\n        public string ShortName => \"CV\";\n\n        public IEnumerable<string> Ids => [nameof(ConcurrencyVisualizerProfiler)];\n\n        public IEnumerable<IExporter> Exporters => [];\n\n        public IEnumerable<IAnalyser> Analysers => [];\n\n        public void DisplayResults(ILogger logger)\n        {\n            if (!benchmarkToCvTraceFile.Any())\n                return;\n\n            logger.WriteLineInfo($\"Exported {benchmarkToCvTraceFile.Count} CV trace file(s). Example:\");\n            logger.WriteLineInfo(benchmarkToCvTraceFile.Values.First());\n            logger.WriteLineInfo(\"DO remember that this Diagnoser just tries to mimic the CVCollectionCmd.exe and you need to have Visual Studio with Concurrency Visualizer plugin installed to visualize the data.\");\n        }\n\n        public void Handle(HostSignal signal, DiagnoserActionParameters parameters)\n        {\n            etwProfiler.Handle(signal, parameters);\n\n            // we need to remember process Id because we loose it when the process exits\n            if (signal == HostSignal.AfterAll)\n                benchmarkToProcessId[parameters.BenchmarkCase] = parameters.ProcessId;\n            else if (signal == HostSignal.AfterProcessExit)\n                benchmarkToCvTraceFile[parameters.BenchmarkCase] = CreateCvTraceFile(parameters);\n        }\n\n        public RunMode GetRunMode(BenchmarkCase benchmarkCase) => etwProfiler.GetRunMode(benchmarkCase);\n\n        public IEnumerable<Metric> ProcessResults(DiagnoserResults results) => etwProfiler.ProcessResults(results);\n\n        public IEnumerable<ValidationError> Validate(ValidationParameters validationParameters) => etwProfiler.Validate(validationParameters);\n\n        private static EtwProfilerConfig CreateDefaultConfig()\n        {\n            var kernelKeywords = KernelTraceEventParser.Keywords.ImageLoad | KernelTraceEventParser.Keywords.Profile; // same as for EtwProfiler\n\n            // following keywords come from decompiled \"GetLocalTraceProviders\" of CVCollectionService.exe\n            // we don't use KernelTraceEventParser.Keywords.Dispatcher because it blows the CV Visualizer in VS, same goes for KernelTraceEventParser.Keywords.ThreadTime which I tried to experiment with\n            kernelKeywords |= KernelTraceEventParser.Keywords.Process | KernelTraceEventParser.Keywords.Thread | KernelTraceEventParser.Keywords.ContextSwitch;\n\n            // following events were not enabled by default but I believe that they are important\n            kernelKeywords |= KernelTraceEventParser.Keywords.DiskFileIO | KernelTraceEventParser.Keywords.DiskIO | KernelTraceEventParser.Keywords.DiskIOInit;\n            kernelKeywords |= KernelTraceEventParser.Keywords.FileIO | KernelTraceEventParser.Keywords.FileIOInit;\n\n            var providers = new (Guid providerGuid, TraceEventLevel providerLevel, ulong keywords, TraceEventProviderOptions? options)[]\n            {\n                // following keywords come from decompiled CVCollectionService.exe\n                (ConcurrencyVisualizerMarkersId, TraceEventLevel.Verbose, EtwProfilerConfig.MatchAnyKeywords, new TraceEventProviderOptions { StacksEnabled = false }),\n                (TplDataflowId, TraceEventLevel.Informational, EtwProfilerConfig.MatchAnyKeywords, new TraceEventProviderOptions { StacksEnabled = false }),\n                (TplSynchronizationId, TraceEventLevel.Informational, EtwProfilerConfig.MatchAnyKeywords, new TraceEventProviderOptions { StacksEnabled = false }),\n                (ManagedConcurrentCollectionsId, TraceEventLevel.Informational, EtwProfilerConfig.MatchAnyKeywords, new TraceEventProviderOptions { StacksEnabled = false }),\n                (PlinqId, TraceEventLevel.Informational, EtwProfilerConfig.MatchAnyKeywords, new TraceEventProviderOptions { StacksEnabled = false }),\n                (ThreadPoolTraceEventParser.ProviderGuid, TraceEventLevel.Informational, EtwProfilerConfig.MatchAnyKeywords, new TraceEventProviderOptions { StacksEnabled = false }),\n                (TplEtwProviderTraceEventParser.ProviderGuid, TraceEventLevel.Informational, (ulong)TplEtwProviderTraceEventParser.Keywords.Default, new TraceEventProviderOptions { StacksEnabled = false }), // do NOT set it to verbose (VS crashes)\n                // following values come from xunit-performance, were selected by the .NET Runtime Team\n                (ClrTraceEventParser.ProviderGuid, TraceEventLevel.Verbose,\n                    (ulong) (ClrTraceEventParser.Keywords.Exception\n                             | ClrTraceEventParser.Keywords.GC\n                             | ClrTraceEventParser.Keywords.Jit\n                             | ClrTraceEventParser.Keywords.JitTracing // for the inlining events\n                             | ClrTraceEventParser.Keywords.Loader\n                             | ClrTraceEventParser.Keywords.NGen\n                             | ClrTraceEventParser.Keywords.Threading // extra\n                             | ClrTraceEventParser.Keywords.ThreadTransfer), // extra\n                    new TraceEventProviderOptions { StacksEnabled = false }) // stacks are too expensive for our purposes\n            };\n\n            return new EtwProfilerConfig(\n                performExtraBenchmarksRun: false,\n                kernelKeywords: kernelKeywords,\n                providers: providers);\n        }\n\n        private string CreateCvTraceFile(DiagnoserActionParameters parameters)\n        {\n            var traceFilePath = etwProfiler.BenchmarkToEtlFile[parameters.BenchmarkCase];\n            var processId = benchmarkToProcessId[parameters.BenchmarkCase];\n\n            var directoryPath = Path.GetDirectoryName(traceFilePath);\n            var cvPathFile = Path.ChangeExtension(traceFilePath, \".CvTrace\");\n            var traceFileName = Path.GetFileName(traceFilePath);\n\n            File.WriteAllText(cvPathFile,\n$@\"<?xml version=\"\"1.0\"\"?>\n<ConcurrencyTrace xmlns:xsi=\"\"http://www.w3.org/2001/XMLSchema-instance\"\" xmlns:xsd=\"\"http://www.w3.org/2001/XMLSchema\"\" MajorVersion=\"\"1\"\" MinorVersion=\"\"0\"\">\n  <Config MajorVersion=\"\"1\"\" MinorVersion=\"\"0\"\">\n    <DeleteEtlsAfterAnalysis>false</DeleteEtlsAfterAnalysis>\n    <TraceLocation>{directoryPath}</TraceLocation>\n    <Markers>\n      <MarkerProvider Name=\"\"ConcurrencyVisualizer.Markers\"\" Guid=\"\"{ConcurrencyVisualizerMarkersId}\"\" Level=\"\"Low\"\" />\n      <MarkerProvider Name=\"\"System.Threading.Tasks\"\" Guid=\"\"{TplEtwProviderTraceEventParser.ProviderGuid}\"\" Level=\"\"Normal\"\" />\n      <MarkerProvider Name=\"\"System.Threading.Tasks.Dataflow\"\" Guid=\"\"{TplDataflowId}\"\" Level=\"\"Normal\"\" />\n      <MarkerProvider Name=\"\"System.Threading\"\" Guid=\"\"{TplSynchronizationId}\"\" Level=\"\"Normal\"\" />\n      <MarkerProvider Name=\"\"System.Collections.Concurrent\"\" Guid=\"\"{ManagedConcurrentCollectionsId}\"\" Level=\"\"Normal\"\" />\n      <MarkerProvider Name=\"\"System.Linq.Parallel\"\" Guid=\"\"{PlinqId}\"\" Level=\"\"Normal\"\" />\n    </Markers>\n    <FilterConfig>\n      <CollectClrEvents>true</CollectClrEvents>\n      <ClrCollectionOptions>None</ClrCollectionOptions>\n      <CollectSampleEvents>true</CollectSampleEvents>\n      <CollectGpuEvents>false</CollectGpuEvents>\n      <CollectFileIO>true</CollectFileIO>\n    </FilterConfig>\n    <UserBufferSettings>\n      <BufferFlushTimer>0</BufferFlushTimer>\n      <BufferSize>256</BufferSize>\n      <MinimumBuffers>512</MinimumBuffers>\n      <MaximumBuffers>1024</MaximumBuffers>\n    </UserBufferSettings>\n    <KernelBufferSettings>\n      <BufferFlushTimer>0</BufferFlushTimer>\n      <BufferSize>256</BufferSize>\n      <MinimumBuffers>512</MinimumBuffers>\n      <MaximumBuffers>1024</MaximumBuffers>\n    </KernelBufferSettings>\n    {GenerateCodeInfo(parameters)}\n  </Config>\n  <Pid>{processId}</Pid>\n  <EtwSourceFileNames>\n    <EtwSourceFile>{traceFileName}</EtwSourceFile>\n  </EtwSourceFileNames>\n  <TraceProcesses />\n  <NtToDosMaps>\n    <NtToDosNameMap NtName=\"\"\\??\\\"\" DosName=\"\"\"\" />\n    <NtToDosNameMap NtName=\"\"\\SystemRoot\\\"\" DosName=\"\"C:\\WINDOWS\\\"\" />\n    <NtToDosNameMap NtName=\"\"\\Windows\\\"\" DosName=\"\"C:\\WINDOWS\\\"\" />\n  </NtToDosMaps>\n</ConcurrencyTrace>\n\");\n\n            return cvPathFile;\n        }\n\n        private string GenerateCodeInfo(DiagnoserActionParameters parameters)\n        {\n            if (!parameters.Config.Options.IsSet(ConfigOptions.KeepBenchmarkFiles))\n                return \"<JustMyCode />\";\n\n            var folderWithDlls = Path.GetDirectoryName(parameters.BenchmarkCase.Descriptor.Type.Assembly.Location);\n\n            return $\"<JustMyCode><MyCodeDirectory>{folderWithDlls}</MyCodeDirectory></JustMyCode>\";\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet.Diagnostics.Windows/Configs/ConcurrencyVisualizerProfilerAttribute.cs",
    "content": "﻿using System;\nusing BenchmarkDotNet.Configs;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Diagnostics.Windows.Configs\n{\n    [PublicAPI]\n    [AttributeUsage(AttributeTargets.Class)]\n    public class ConcurrencyVisualizerProfilerAttribute : Attribute, IConfigSource\n    {\n        public ConcurrencyVisualizerProfilerAttribute() => Config = ManualConfig.CreateEmpty().AddDiagnoser(new ConcurrencyVisualizerProfiler());\n\n        public IConfig Config { get; }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet.Diagnostics.Windows/Configs/EtwProfilerAttribute.cs",
    "content": "﻿using System;\nusing BenchmarkDotNet.Configs;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Diagnostics.Windows.Configs\n{\n    [PublicAPI]\n    [AttributeUsage(AttributeTargets.Class)]\n    public class EtwProfilerAttribute : Attribute, IConfigSource\n    {\n        /// <param name=\"performExtraBenchmarksRun\">if set to true, benchmarks will be executed on more time with the profiler attached. If set to false, there will be no extra run but the results will contain overhead. True by default.</param>\n        /// <param name=\"bufferSizeInMb\">ETW session buffer size, in MB. 256 by default</param>\n        public EtwProfilerAttribute(bool performExtraBenchmarksRun = true, int bufferSizeInMb = 256)\n        {\n            Config = ManualConfig.CreateEmpty().AddDiagnoser(new EtwProfiler(new EtwProfilerConfig(performExtraBenchmarksRun, bufferSizeInMb)));\n        }\n\n        public IConfig Config { get; }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet.Diagnostics.Windows/Configs/InliningDiagnoserAttribute.cs",
    "content": "﻿using System;\nusing BenchmarkDotNet.Configs;\n\nnamespace BenchmarkDotNet.Diagnostics.Windows.Configs\n{\n    [AttributeUsage(AttributeTargets.Class)]\n    public class InliningDiagnoserAttribute : Attribute, IConfigSource\n    {\n        /// <param name=\"logFailuresOnly\">only the methods that failed to get inlined. True by default.</param>\n        /// <param name=\"filterByNamespace\">only the methods from declaring type's namespace. Set to false if you want to see all Jit inlining events. True by default.</param>\n        public InliningDiagnoserAttribute(bool logFailuresOnly = true, bool filterByNamespace = true)\n        {\n            Config = ManualConfig.CreateEmpty().AddDiagnoser(new InliningDiagnoser(logFailuresOnly, filterByNamespace));\n        }\n\n        public InliningDiagnoserAttribute(bool logFailuresOnly = true, string[]? allowedNamespaces = null)\n        {\n            Config = ManualConfig.CreateEmpty().AddDiagnoser(new InliningDiagnoser(logFailuresOnly, allowedNamespaces));\n        }\n\n        public IConfig Config { get; }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet.Diagnostics.Windows/Configs/JitStatsDiagnoserAttribute.cs",
    "content": "﻿using System;\nusing BenchmarkDotNet.Configs;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Diagnostics.Windows.Configs\n{\n    [PublicAPI]\n    [AttributeUsage(AttributeTargets.Class)]\n    public class JitStatsDiagnoserAttribute : Attribute, IConfigSource\n    {\n        public JitStatsDiagnoserAttribute()\n        {\n            Config = ManualConfig.CreateEmpty().AddDiagnoser(new JitStatsDiagnoser());\n        }\n\n        public IConfig Config { get; }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet.Diagnostics.Windows/Configs/NativeMemoryProfilerAttribute.cs",
    "content": "﻿using System;\nusing BenchmarkDotNet.Configs;\nusing JetBrains.Annotations;\n\nnamespace BenchmarkDotNet.Diagnostics.Windows.Configs\n{\n    [PublicAPI]\n    [AttributeUsage(AttributeTargets.Class)]\n    public class NativeMemoryProfilerAttribute : Attribute, IConfigSource\n    {\n        public NativeMemoryProfilerAttribute()\n        {\n            Config = ManualConfig.CreateEmpty().AddDiagnoser(new NativeMemoryProfiler());\n        }\n\n        public IConfig Config { get; }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet.Diagnostics.Windows/Configs/TailCallDiagnoserAttribute.cs",
    "content": "﻿using BenchmarkDotNet.Configs;\nusing System;\n\nnamespace BenchmarkDotNet.Diagnostics.Windows.Configs\n{\n    [AttributeUsage(AttributeTargets.Class)]\n    public class TailCallDiagnoserAttribute : Attribute, IConfigSource\n    {\n        public IConfig Config { get; }\n\n        /// <param name=\"logFailuresOnly\">only the methods that failed to get tail called. True by default.</param>\n        /// <param name=\"filterByNamespace\">only the methods from declaring type's namespace. Set to false if you want to see all Jit tail events. True by default.</param>\n        public TailCallDiagnoserAttribute(bool logFailuresOnly = true, bool filterByNamespace = true)\n        {\n            Config = ManualConfig.CreateEmpty().AddDiagnoser(new TailCallDiagnoser(logFailuresOnly, filterByNamespace));\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet.Diagnostics.Windows/EtwDiagnoser.cs",
    "content": "﻿using System;\nusing System.Collections.Concurrent;\nusing BenchmarkDotNet.Parameters;\nusing BenchmarkDotNet.Running;\nusing System.Collections.Generic;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing BenchmarkDotNet.Analysers;\nusing BenchmarkDotNet.Diagnosers;\nusing BenchmarkDotNet.Exporters;\nusing BenchmarkDotNet.Helpers;\nusing BenchmarkDotNet.Loggers;\nusing Microsoft.Diagnostics.Tracing;\nusing Microsoft.Diagnostics.Tracing.Parsers;\nusing Microsoft.Diagnostics.Tracing.Session;\n\nnamespace BenchmarkDotNet.Diagnostics.Windows\n{\n    public abstract class EtwDiagnoser<TStats> : DisposeAtProcessTermination where TStats : new()\n    {\n        internal readonly LogCapture Logger = new LogCapture();\n        protected readonly Dictionary<BenchmarkCase, int> BenchmarkToProcess = [];\n        protected readonly ConcurrentDictionary<int, TStats> StatsPerProcess = [];\n\n        public virtual RunMode GetRunMode(BenchmarkCase benchmarkCase) => RunMode.ExtraRun;\n\n        public virtual IEnumerable<IExporter> Exporters => [];\n        public virtual IEnumerable<IAnalyser> Analysers => [];\n\n        protected TraceEventSession Session { get; private set; } = default!;\n\n        protected abstract ulong EventType { get; }\n\n        protected abstract string SessionNamePrefix { get; }\n\n        protected void Start(DiagnoserActionParameters parameters)\n        {\n            Clear();\n\n            BenchmarkToProcess.Add(parameters.BenchmarkCase, parameters.ProcessId);\n            StatsPerProcess.TryAdd(parameters.ProcessId, GetInitializedStats(parameters));\n\n            Session = CreateSession(parameters.BenchmarkCase);\n\n            EnableProvider();\n\n            AttachToEvents(Session, parameters.BenchmarkCase);\n\n            // The ETW collection thread starts receiving events immediately, but we only\n            // start aggregating them after ProcessStarted is called and we know which process\n            // (or processes) we should be monitoring. Communication between the benchmark thread\n            // and the ETW collection thread is through the statsPerProcess concurrent dictionary\n            // and through the TraceEventSession class, which is thread-safe.\n            var task = Task.Factory.StartNew((Action)(() => Session.Source.Process()), TaskCreationOptions.LongRunning);\n\n            // wait until the processing has started, block by then so we don't loose any\n            // information (very important for jit-related things)\n            WaitUntilStarted(task);\n        }\n\n        protected virtual TStats GetInitializedStats(DiagnoserActionParameters parameters) => new TStats();\n\n        protected virtual TraceEventSession CreateSession(BenchmarkCase benchmarkCase)\n             => new TraceEventSession(GetSessionName(SessionNamePrefix, benchmarkCase, benchmarkCase.Parameters));\n\n        protected virtual void EnableProvider()\n        {\n            Session.EnableProvider(\n                ClrTraceEventParser.ProviderGuid,\n                TraceEventLevel.Verbose,\n                EventType);\n        }\n\n        protected abstract void AttachToEvents(TraceEventSession traceEventSession, BenchmarkCase benchmarkCase);\n\n        protected void Stop()\n        {\n            WaitForDelayedEvents();\n            Dispose();\n        }\n\n        public override void Dispose()\n        {\n            Session?.Dispose();\n            base.Dispose();\n        }\n\n        private void Clear()\n        {\n            BenchmarkToProcess.Clear();\n            StatsPerProcess.Clear();\n        }\n\n        private static string GetSessionName(string prefix, BenchmarkCase benchmarkCase, ParameterInstances? parameters = null)\n        {\n            if (parameters != null && parameters.Items.Count > 0)\n                return $\"{prefix}-{benchmarkCase.FolderInfo}-{parameters.FolderInfo}\";\n            return $\"{prefix}-{benchmarkCase.FolderInfo}\";\n        }\n\n        private static void WaitUntilStarted(Task task)\n        {\n            while (task.Status == TaskStatus.Created\n                || task.Status == TaskStatus.WaitingForActivation\n                || task.Status == TaskStatus.WaitingToRun)\n            {\n                Thread.Sleep(10);\n            }\n        }\n\n        /// <summary>\n        /// ETW real-time sessions receive events with a slight delay. Typically it\n        /// shouldn't be more than a few seconds. This increases the likelihood that\n        /// all relevant events are processed by the collection thread by the time we\n        /// are done with the benchmark.\n        /// </summary>\n        private static void WaitForDelayedEvents()\n        {\n            Thread.Sleep(TimeSpan.FromSeconds(3));\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet.Diagnostics.Windows/EtwProfiler.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Collections.Immutable;\nusing System.IO;\nusing System.Linq;\nusing System.Threading;\nusing BenchmarkDotNet.Analysers;\nusing BenchmarkDotNet.Diagnosers;\nusing BenchmarkDotNet.Diagnostics.Windows.Tracing;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Exporters;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Validators;\nusing JetBrains.Annotations;\nusing Microsoft.Diagnostics.Tracing.Session;\n\nnamespace BenchmarkDotNet.Diagnostics.Windows\n{\n    public class EtwProfiler : IDiagnoser, IHardwareCountersDiagnoser, IProfiler\n    {\n        private readonly EtwProfilerConfig config;\n        private readonly RunMode runMode;\n        private readonly Dictionary<BenchmarkCase, string> benchmarkToEtlFile;\n        private readonly Dictionary<BenchmarkCase, PreciseMachineCounter[]> benchmarkToCounters;\n\n        private Session kernelSession = default!;\n        private Session userSession = default!;\n        private Session heapSession = default!;\n\n        [PublicAPI] // parameterless ctor required by DiagnosersLoader to support creating this profiler via console line args\n        public EtwProfiler() : this(new EtwProfilerConfig(performExtraBenchmarksRun: false)) { }\n\n        [PublicAPI]\n        public EtwProfiler(EtwProfilerConfig config)\n        {\n            this.config = config;\n            runMode = config.PerformExtraBenchmarksRun ? RunMode.ExtraRun : RunMode.NoOverhead;\n            benchmarkToEtlFile = [];\n            benchmarkToCounters = [];\n            CreationTime = DateTime.Now;\n        }\n\n        public string ShortName => \"ETW\";\n\n        public IEnumerable<string> Ids => [nameof(EtwProfiler)];\n\n        public IEnumerable<IExporter> Exporters => [];\n\n        public IEnumerable<IAnalyser> Analysers => [];\n\n        public IReadOnlyDictionary<BenchmarkCase, PmcStats> Results => BuildPmcStats();\n\n        internal IReadOnlyDictionary<BenchmarkCase, string> BenchmarkToEtlFile => benchmarkToEtlFile;\n\n        private DateTime CreationTime { get; }\n\n        public RunMode GetRunMode(BenchmarkCase benchmarkCase) => runMode;\n\n        public IEnumerable<ValidationError> Validate(ValidationParameters validationParameters)\n            => HardwareCounters.Validate(validationParameters, mandatory: false);\n\n        public void Handle(HostSignal signal, DiagnoserActionParameters parameters)\n        {\n            // it's crucial to start the trace before the process starts and stop it after the benchmarked process stops to have all of the necessary events in the trace file!\n            if (signal == HostSignal.BeforeProcessStart)\n                Start(parameters);\n            else if (signal == HostSignal.AfterProcessExit)\n                Stop(parameters);\n        }\n\n        public IEnumerable<Metric> ProcessResults(DiagnoserResults results)\n        {\n            if (!benchmarkToEtlFile.TryGetValue(results.BenchmarkCase, out var traceFilePath))\n                return [];\n\n            // currently TraceLogParser parsers the counters metrics only. So if there are no counters configured, it makes no sense to parse the file\n            if (!benchmarkToCounters.TryGetValue(results.BenchmarkCase, out var counters) || counters.IsEmpty())\n                return [];\n\n            return TraceLogParser.Parse(traceFilePath, counters);\n        }\n\n        public void DisplayResults(ILogger logger)\n        {\n            if (!benchmarkToEtlFile.Any())\n                return;\n\n            logger.WriteLineInfo($\"Exported {benchmarkToEtlFile.Count} trace file(s). Example:\");\n            logger.WriteLineInfo(benchmarkToEtlFile.Values.First());\n        }\n\n        private void Start(DiagnoserActionParameters parameters)\n        {\n            var counters = benchmarkToCounters[parameters.BenchmarkCase] = parameters.Config\n                .GetHardwareCounters()\n                .Select(counter => HardwareCounters.FromCounter(counter, config.IntervalSelectors.TryGetValue(counter, out var selector) ? selector : GetInterval))\n                .ToArray();\n\n            if (counters.Any()) // we need to enable the counters before starting the kernel session\n                HardwareCounters.Enable(counters);\n\n            try\n            {\n                kernelSession = new KernelSession(parameters, config, CreationTime).EnableProviders();\n                if (config.CreateHeapSession)\n                    heapSession = new HeapSession(parameters, config, CreationTime).EnableProviders();\n                userSession = new UserSession(parameters, config, CreationTime).EnableProviders();\n            }\n            catch (Exception)\n            {\n                userSession?.Dispose();\n                heapSession?.Dispose();\n                kernelSession?.Dispose();\n\n                throw;\n            }\n        }\n\n        private void Stop(DiagnoserActionParameters parameters)\n        {\n            WaitForDelayedEvents();\n            string userSessionFile = userSession.FilePath;\n            kernelSession.Dispose();\n            heapSession?.Dispose();\n            userSession.Dispose();\n\n            // Merge the 'primary' etl file X.etl (userSession) with any files that match .clr*.etl .user*.etl. and .kernel.etl.\n            TraceEventSession.MergeInPlace(userSessionFile, TextWriter.Null);\n\n            benchmarkToEtlFile[parameters.BenchmarkCase] = userSessionFile;\n        }\n\n        private static int GetInterval(ProfileSourceInfo info) => Math.Min(info.MaxInterval, Math.Max(info.MinInterval, info.Interval));\n\n        /// <summary>\n        /// ETW sessions receive events with a slight delay.\n        /// This increases the likelihood that all relevant events are processed by the collection thread by the time we are done with the benchmark.\n        /// </summary>\n        private static void WaitForDelayedEvents() => Thread.Sleep(TimeSpan.FromMilliseconds(500));\n\n        private IReadOnlyDictionary<BenchmarkCase, PmcStats> BuildPmcStats()\n        {\n            var builder = ImmutableDictionary.CreateBuilder<BenchmarkCase, PmcStats>();\n\n            foreach (var benchmarkToCounter in benchmarkToCounters)\n            {\n                var uniqueCounters = benchmarkToCounter.Value.Select(x => x.Counter).Distinct().ToImmutableArray();\n\n                var pmcStats = new PmcStats(\n                    uniqueCounters,\n                    counter => benchmarkToCounter.Value.Single(pmc => pmc.Counter == counter)\n                );\n\n                builder.Add(benchmarkToCounter.Key, pmcStats);\n            }\n\n            return builder.ToImmutable();\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet.Diagnostics.Windows/EtwProfilerConfig.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing BenchmarkDotNet.Diagnosers;\nusing Microsoft.Diagnostics.Tracing;\nusing Microsoft.Diagnostics.Tracing.Parsers;\nusing Microsoft.Diagnostics.Tracing.Session;\n\nnamespace BenchmarkDotNet.Diagnostics.Windows\n{\n    public class EtwProfilerConfig\n    {\n        public const ulong MatchAnyKeywords = ulong.MaxValue;\n\n        public bool PerformExtraBenchmarksRun { get; }\n\n        public int BufferSizeInMb { get; }\n\n        public float CpuSampleIntervalInMilliseconds { get; }\n\n        public KernelTraceEventParser.Keywords KernelKeywords { get; }\n\n        public KernelTraceEventParser.Keywords KernelStackKeywords { get; }\n\n        public IReadOnlyDictionary<HardwareCounter, Func<ProfileSourceInfo, int>> IntervalSelectors { get; }\n\n        public IReadOnlyCollection<(Guid providerGuid, TraceEventLevel providerLevel, ulong keywords, TraceEventProviderOptions? options)> Providers { get; }\n\n        public bool CreateHeapSession { get; }\n\n        /// <param name=\"performExtraBenchmarksRun\">if set to true, benchmarks will be executed one more time with the profiler attached. If set to false, there will be no extra run but the results will contain overhead. True by default.</param>\n        /// <param name=\"bufferSizeInMb\">ETW session buffer size, in MB. 256 by default</param>\n        /// <param name=\"cpuSampleIntervalInMilliseconds\">The rate at which CPU samples are collected. By default this is 1 (once a millisecond per CPU). There is a lower bound on this (typically 0.125 ms)</param>\n        /// <param name=\"intervalSelectors\">interval per hardware counter, if not provided then default values will be used.</param>\n        /// <param name=\"kernelKeywords\">kernel session keywords, ImageLoad (for native stack frames) and Profile (for CPU Stacks) are the defaults</param>\n        /// <param name=\"kernelStackKeywords\">This is passed to TraceEventSession.EnableKernelProvider to enable particular sets of events. See https://docs.microsoft.com/windows/win32/api/evntrace/ns-evntrace-event_trace_properties#members for more information on them.</param>\n        /// <param name=\"providers\">providers that should be enabled, if not provided then default values will be used</param>\n        /// <param name=\"createHeapSession\">value indicating whether to create heap session. False by default, used internally by NativeMemoryProfiler.</param>\n        public EtwProfilerConfig(\n            bool performExtraBenchmarksRun = true,\n            int bufferSizeInMb = 256,\n            float cpuSampleIntervalInMilliseconds = 1.0f,\n            KernelTraceEventParser.Keywords kernelKeywords = KernelTraceEventParser.Keywords.ImageLoad | KernelTraceEventParser.Keywords.Profile,\n            KernelTraceEventParser.Keywords kernelStackKeywords = KernelTraceEventParser.Keywords.Profile,\n            IReadOnlyDictionary<HardwareCounter, Func<ProfileSourceInfo, int>>? intervalSelectors = null,\n            IReadOnlyCollection<(Guid providerGuid, TraceEventLevel providerLevel, ulong keywords, TraceEventProviderOptions? options)>? providers = null,\n            bool createHeapSession = false)\n        {\n            CreateHeapSession = createHeapSession;\n            KernelKeywords = kernelKeywords;\n            KernelStackKeywords = kernelStackKeywords;\n            PerformExtraBenchmarksRun = performExtraBenchmarksRun;\n            BufferSizeInMb = bufferSizeInMb;\n            CpuSampleIntervalInMilliseconds = cpuSampleIntervalInMilliseconds;\n            IntervalSelectors = intervalSelectors ?? new Dictionary<HardwareCounter, Func<ProfileSourceInfo, int>>\n            {\n                // following values come from xunit-performance, were selected based on a many trace files from benchmark runs\n                // to keep good balance between accuracy and trace file size\n                { HardwareCounter.InstructionRetired, _ => 1_000_000 },\n                { HardwareCounter.BranchMispredictions, _ => 1_000 },\n                { HardwareCounter.CacheMisses, _ => 1_000 }\n            };\n            Providers = providers ??\n            [\n                // following values come from xunit-performance, were selected by the .NET Runtime Team\n                (ClrTraceEventParser.ProviderGuid, TraceEventLevel.Verbose,\n                    (ulong) (ClrTraceEventParser.Keywords.Exception\n                             | ClrTraceEventParser.Keywords.GC\n                             | ClrTraceEventParser.Keywords.Jit\n                             | ClrTraceEventParser.Keywords.JitTracing // for the inlining events\n                             | ClrTraceEventParser.Keywords.JittedMethodILToNativeMap // Fix NativeMemoryProfiler for .Net Framework\n                             | ClrTraceEventParser.Keywords.Loader\n                             | ClrTraceEventParser.Keywords.NGen),\n                    new TraceEventProviderOptions { StacksEnabled = false }), // stacks are too expensive for our purposes\n                (new Guid(\"0866B2B8-5CEF-5DB9-2612-0C0FFD814A44\"), TraceEventLevel.Informational, MatchAnyKeywords, null) // ArrayPool events\n            ];\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet.Diagnostics.Windows/HardwareCounters.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing BenchmarkDotNet.Detectors;\nusing BenchmarkDotNet.Diagnosers;\nusing BenchmarkDotNet.Portability;\nusing BenchmarkDotNet.Toolchains.InProcess.Emit;\nusing BenchmarkDotNet.Validators;\nusing Microsoft.Diagnostics.Tracing.Session;\n\nnamespace BenchmarkDotNet.Diagnostics.Windows\n{\n    public static class HardwareCounters\n    {\n        private static readonly Dictionary<HardwareCounter, string> EtwTranslations\n            = new Dictionary<HardwareCounter, string>\n            {\n                { HardwareCounter.Timer, \"Timer\" },\n                { HardwareCounter.TotalIssues, \"TotalIssues\" },\n                { HardwareCounter.BranchInstructions, \"BranchInstructions\" },\n                { HardwareCounter.CacheMisses, \"CacheMisses\" },\n                { HardwareCounter.BranchMispredictions, \"BranchMispredictions\" },\n                { HardwareCounter.TotalCycles, \"TotalCycles\" },\n                { HardwareCounter.UnhaltedCoreCycles, \"UnhaltedCoreCycles\" },\n                { HardwareCounter.InstructionRetired, \"InstructionRetired\" },\n                { HardwareCounter.UnhaltedReferenceCycles, \"UnhaltedReferenceCycles\" },\n                { HardwareCounter.LlcReference, \"LLCReference\" },\n                { HardwareCounter.LlcMisses, \"LLCMisses\" },\n                { HardwareCounter.BranchInstructionRetired, \"BranchInstructionRetired\" },\n                { HardwareCounter.BranchMispredictsRetired, \"BranchMispredictsRetired\" }\n            };\n\n        public static IEnumerable<ValidationError> Validate(ValidationParameters validationParameters, bool mandatory)\n        {\n            if (!OsDetector.IsWindows())\n            {\n                yield return new ValidationError(true, \"Hardware Counters and EtwProfiler are supported only on Windows\");\n                yield break;\n            }\n\n            if (!validationParameters.Config.GetHardwareCounters().Any() && mandatory)\n            {\n                yield return new ValidationError(true, \"No Hardware Counters defined, probably a bug\");\n                yield break;\n            }\n\n            if (TraceEventSession.IsElevated() != true)\n                yield return new ValidationError(true, \"Must be elevated (Admin) to use ETW Kernel Session (required for Hardware Counters and EtwProfiler).\");\n\n            var availableCpuCounters = TraceEventProfileSources.GetInfo();\n\n            foreach (var hardwareCounter in validationParameters.Config.GetHardwareCounters())\n            {\n                if (!EtwTranslations.TryGetValue(hardwareCounter, out string counterName))\n                {\n                    yield return new ValidationError(true,\n                        $\"Counter {hardwareCounter} not recognized. \" +\n                        $\"Please make sure that you are using counter available on your machine. \" +\n                        $\"You can get the list of available counters by running `tracelog.exe -profilesources Help`\");\n                    continue;\n                }\n\n                if (!availableCpuCounters.ContainsKey(counterName))\n                    yield return new ValidationError(true, $\"The counter {counterName} is not available. Please make sure you are Windows 8+ without Hyper-V\");\n            }\n\n            foreach (var benchmark in validationParameters.Benchmarks)\n            {\n                if (benchmark.Job.Infrastructure.TryGetToolchain(out var toolchain) && toolchain is InProcessEmitToolchain)\n                {\n                    yield return new ValidationError(true, \"Hardware Counters and EtwProfiler are not supported for InProcessToolchain.\", benchmark);\n                }\n            }\n        }\n\n        internal static PreciseMachineCounter FromCounter(HardwareCounter counter, Func<ProfileSourceInfo, int> intervalSelector)\n        {\n            var profileSource = TraceEventProfileSources.GetInfo()[EtwTranslations[counter]]; // it can't fail, diagnoser validates that first\n\n            return new PreciseMachineCounter(profileSource.ID, profileSource.Name, counter, intervalSelector(profileSource));\n        }\n\n        internal static void Enable(IEnumerable<PreciseMachineCounter> counters)\n        {\n            TraceEventProfileSources.Set( // it's a must have to get the events enabled!!\n                counters.Select(counter => counter.ProfileSourceId).ToArray(),\n                counters.Select(counter => counter.Interval).ToArray());\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet.Diagnostics.Windows/InliningDiagnoser.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Linq;\nusing BenchmarkDotNet.Diagnosers;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Running;\nusing Microsoft.Diagnostics.Tracing.Session;\n\nnamespace BenchmarkDotNet.Diagnostics.Windows\n{\n    public class InliningDiagnoser : JitDiagnoser<object>, IProfiler\n    {\n        private static readonly string LogSeparator = new string('-', 20);\n\n        private readonly bool logFailuresOnly = true;\n        private readonly bool filterByNamespace = true;\n        private readonly string[]? allowedNamespaces = null;\n        private string defaultNamespace = default!;\n\n        // ReSharper disable once EmptyConstructor parameterless ctor is mandatory for DiagnosersLoader.CreateDiagnoser\n        public InliningDiagnoser() { }\n\n        /// <summary>\n        /// creates new InliningDiagnoser\n        /// </summary>\n        /// <param name=\"logFailuresOnly\">only the methods that failed to get inlined. True by default.</param>\n        /// <param name=\"filterByNamespace\">only the methods from declaring type's namespace. Set to false if you want to see all Jit inlining events. True by default.</param>\n        public InliningDiagnoser(bool logFailuresOnly = true, bool filterByNamespace = true)\n        {\n            this.logFailuresOnly = logFailuresOnly;\n            this.filterByNamespace = filterByNamespace;\n        }\n\n        /// <summary>\n        /// creates new InliningDiagnoser\n        /// </summary>\n        /// <param name=\"logFailuresOnly\">only the methods that failed to get inlined. True by default.</param>\n        /// <param name=\"allowedNamespaces\">list of namespaces from which inlining message should be print.</param>\n        public InliningDiagnoser(bool logFailuresOnly = true, string[]? allowedNamespaces = null)\n        {\n            this.logFailuresOnly = logFailuresOnly;\n            this.allowedNamespaces = allowedNamespaces;\n            this.filterByNamespace = true;\n        }\n\n        public override IEnumerable<string> Ids => [nameof(InliningDiagnoser)];\n\n        public string ShortName => \"inlining\";\n\n        protected override void AttachToEvents(TraceEventSession session, BenchmarkCase benchmarkCase)\n        {\n            defaultNamespace = benchmarkCase.Descriptor.WorkloadMethod.DeclaringType.Namespace;\n\n            Logger.WriteLine();\n            Logger.WriteLineHeader(LogSeparator);\n            Logger.WriteLineInfo($\"{benchmarkCase.DisplayInfo}\");\n            Logger.WriteLineHeader(LogSeparator);\n\n            session.Source.Clr.MethodInliningSucceeded += jitData =>\n            {\n                // Inliner = the parent method (the inliner calls the inlinee)\n                // Inlinee = the method that is going to be \"inlined\" inside the inliner (it's caller)\n                if (StatsPerProcess.TryGetValue(jitData.ProcessID, out _))\n                {\n                    var shouldPrint = !logFailuresOnly\n                        && ShouldPrintEventInfo(jitData.InlinerNamespace, jitData.InlineeNamespace);\n\n                    if (shouldPrint)\n                    {\n                        Logger.WriteLineHelp($\"Inliner: {jitData.InlinerNamespace}.{jitData.InlinerName} - {jitData.InlinerNameSignature}\");\n                        Logger.WriteLineHelp($\"Inlinee: {jitData.InlineeNamespace}.{jitData.InlineeName} - {jitData.InlineeNameSignature}\");\n                        Logger.WriteLineHeader(LogSeparator);\n                    }\n                }\n            };\n\n            session.Source.Clr.MethodInliningFailed += jitData =>\n            {\n                if (StatsPerProcess.TryGetValue(jitData.ProcessID, out _)\n                    && ShouldPrintEventInfo(jitData.InlinerNamespace, jitData.InlineeNamespace))\n                {\n                    Logger.WriteLineError($\"Inliner: {jitData.InlinerNamespace}.{jitData.InlinerName} - {jitData.InlinerNameSignature}\");\n                    Logger.WriteLineError($\"Inlinee: {jitData.InlineeNamespace}.{jitData.InlineeName} - {jitData.InlineeNameSignature}\");\n                    // See https://blogs.msdn.microsoft.com/clrcodegeneration/2009/10/21/jit-etw-inlining-event-fail-reasons/\n                    Logger.WriteLineError($\"Fail Reason: {jitData.FailReason}\");\n                    Logger.WriteLineHeader(LogSeparator);\n                }\n            };\n\n            session.Source.Clr.MethodInliningFailedAnsi += jitData => // this is new event exposed by .NET Core 2.2 https://github.com/dotnet/coreclr/commit/95a9055dbe5f6233f75ee2d7b6194e18cc4977fd\n            {\n                if (StatsPerProcess.TryGetValue(jitData.ProcessID, out _)\n                    && ShouldPrintEventInfo(jitData.InlinerNamespace, jitData.InlineeNamespace))\n                {\n                    Logger.WriteLineError($\"Inliner: {jitData.InlinerNamespace}.{jitData.InlinerName} - {jitData.InlinerNameSignature}\");\n                    Logger.WriteLineError($\"Inlinee: {jitData.InlineeNamespace}.{jitData.InlineeName} - {jitData.InlineeNameSignature}\");\n                    // See https://blogs.msdn.microsoft.com/clrcodegeneration/2009/10/21/jit-etw-inlining-event-fail-reasons/\n                    Logger.WriteLineError($\"Fail Reason: {jitData.FailReason}\");\n                    Logger.WriteLineHeader(LogSeparator);\n                }\n            };\n        }\n\n        private bool ShouldPrintEventInfo(string inlinerNamespace, string inlineeNamespace)\n            => !filterByNamespace ||\n                (allowedNamespaces?.Any(x=> inlineeNamespace.StartsWith(x) || inlinerNamespace.StartsWith(x))\n                    ?? (inlinerNamespace.StartsWith(defaultNamespace)) || inlineeNamespace.StartsWith(defaultNamespace));\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet.Diagnostics.Windows/JitDiagnoser.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing BenchmarkDotNet.Detectors;\nusing BenchmarkDotNet.Diagnosers;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Portability;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Validators;\nusing Microsoft.Diagnostics.Tracing.Parsers;\n\nnamespace BenchmarkDotNet.Diagnostics.Windows\n{\n    public abstract class JitDiagnoser<TStats> : EtwDiagnoser<TStats>, IDiagnoser where TStats : new()\n    {\n        protected override ulong EventType => (ulong)ClrTraceEventParser.Keywords.JitTracing;\n\n        protected override string SessionNamePrefix => \"JitTracing\";\n\n        public override RunMode GetRunMode(BenchmarkCase benchmarkCase) => RunMode.NoOverhead;\n\n        public abstract IEnumerable<string> Ids { get; }\n\n        public void Handle(HostSignal signal, DiagnoserActionParameters parameters)\n        {\n            if (signal == HostSignal.BeforeAnythingElse)\n                Start(parameters);\n            else if (signal == HostSignal.AfterAll)\n                Stop();\n        }\n\n        public virtual IEnumerable<Metric> ProcessResults(DiagnoserResults results) => [];\n\n        public IEnumerable<ValidationError> Validate(ValidationParameters validationParameters)\n        {\n            if (!OsDetector.IsWindows())\n            {\n                yield return new ValidationError(true, $\"{GetType().Name} is supported only on Windows\");\n            }\n        }\n\n        public void DisplayResults(ILogger outputLogger)\n        {\n            if (Logger.CapturedOutput.Count > 0)\n                outputLogger.WriteLineHeader(new string('-', 20));\n            foreach (var line in Logger.CapturedOutput)\n                outputLogger.Write(line.Kind, line.Text);\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet.Diagnostics.Windows/JitStatsDiagnoser.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Threading;\nusing BenchmarkDotNet.Columns;\nusing BenchmarkDotNet.Diagnosers;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Running;\nusing Microsoft.Diagnostics.Tracing.Parsers;\nusing Microsoft.Diagnostics.Tracing.Session;\nusing Perfolizer.Metrology;\n\nnamespace BenchmarkDotNet.Diagnostics.Windows\n{\n    public class JitStatsDiagnoser : JitDiagnoser<JitStats>, IProfiler\n    {\n        public override IEnumerable<string> Ids => [nameof(JitStatsDiagnoser)];\n\n        public string ShortName => \"jit\";\n\n        protected override ulong EventType => (ulong)(ClrTraceEventParser.Keywords.Jit | ClrTraceEventParser.Keywords.Compilation);\n\n        public override IEnumerable<Metric> ProcessResults(DiagnoserResults results)\n        {\n            if (BenchmarkToProcess.TryGetValue(results.BenchmarkCase, out int pid))\n            {\n                if (StatsPerProcess.TryGetValue(pid, out JitStats jitStats))\n                {\n                    yield return new Metric(MethodsJittedDescriptor.Instance, jitStats.MethodsCompiled);\n                    yield return new Metric(MethodsTieredDescriptor.Instance, jitStats.MethodsTiered);\n                    yield return new Metric(JitAllocatedMemoryDescriptor.Instance, jitStats.MemoryAllocated);\n                }\n            }\n        }\n\n        protected override void AttachToEvents(TraceEventSession session, BenchmarkCase benchmarkCase)\n        {\n            session.Source.Clr.MethodJittingStarted += methodData =>\n            {\n                if (StatsPerProcess.TryGetValue(methodData.ProcessID, out JitStats jitStats))\n                {\n                    Interlocked.Increment(ref jitStats.MethodsCompiled);\n                }\n            };\n\n            session.Source.Clr.MethodMemoryAllocatedForJitCode += memoryAllocated =>\n            {\n                if (StatsPerProcess.TryGetValue(memoryAllocated.ProcessID, out JitStats jitStats))\n                {\n                    Interlocked.Add(ref jitStats.MemoryAllocated, memoryAllocated.AllocatedSizeForJitCode);\n                }\n            };\n\n            session.Source.Clr.TieredCompilationBackgroundJitStop += tieredData =>\n            {\n                if (StatsPerProcess.TryGetValue(tieredData.ProcessID, out JitStats jitStats))\n                {\n                    Interlocked.Add(ref jitStats.MethodsTiered, tieredData.JittedMethodCount);\n                }\n            };\n        }\n\n        private sealed class MethodsJittedDescriptor : IMetricDescriptor\n        {\n            internal static readonly MethodsJittedDescriptor Instance = new();\n\n            public string Id => nameof(MethodsJittedDescriptor);\n            public string DisplayName => \"Methods JITted\";\n            public string Legend => \"Total number of methods JITted during entire benchmark execution (including warmup).\";\n            public bool TheGreaterTheBetter => false;\n            public string NumberFormat => \"N0\";\n            public UnitType UnitType => UnitType.Dimensionless;\n            public string Unit => \"Count\";\n            public int PriorityInCategory => 0;\n            public bool GetIsAvailable(Metric metric) => true;\n        }\n\n        private sealed class MethodsTieredDescriptor : IMetricDescriptor\n        {\n            internal static readonly MethodsTieredDescriptor Instance = new();\n\n            public string Id => nameof(MethodsTieredDescriptor);\n            public string DisplayName => \"Methods Tiered\";\n            public string Legend => \"Total number of methods re-compiled by Tiered JIT during entire benchmark execution (including warmup).\";\n            public bool TheGreaterTheBetter => false;\n            public string NumberFormat => \"N0\";\n            public UnitType UnitType => UnitType.Dimensionless;\n            public string Unit => \"Count\";\n            public int PriorityInCategory => 0;\n            public bool GetIsAvailable(Metric metric) => true;\n        }\n\n        private sealed class JitAllocatedMemoryDescriptor : IMetricDescriptor\n        {\n            internal static readonly JitAllocatedMemoryDescriptor Instance = new();\n\n            public string Id => nameof(JitAllocatedMemoryDescriptor);\n            public string DisplayName => \"JIT allocated memory\";\n            public string Legend => \"Total memory allocated by the JIT during entire benchmark execution (including warmup).\";\n            public bool TheGreaterTheBetter => false;\n            public string NumberFormat => \"N0\";\n            public UnitType UnitType => UnitType.Size;\n            public string Unit => SizeUnit.B.Abbreviation;\n            public int PriorityInCategory => 0;\n            public bool GetIsAvailable(Metric metric) => true;\n        }\n    }\n\n    public sealed class JitStats\n    {\n        public long MethodsCompiled;\n        public long MethodsTiered;\n        public long MemoryAllocated;\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet.Diagnostics.Windows/NativeMemoryProfiler.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing BenchmarkDotNet.Analysers;\nusing BenchmarkDotNet.Diagnosers;\nusing BenchmarkDotNet.Diagnostics.Windows.Tracing;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Exporters;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Validators;\nusing JetBrains.Annotations;\nusing Microsoft.Diagnostics.Tracing.Parsers;\n\nnamespace BenchmarkDotNet.Diagnostics.Windows\n{\n    public class NativeMemoryProfiler : IProfiler\n    {\n        private readonly LogCapture logger = new LogCapture();\n\n        private readonly EtwProfiler etwProfiler;\n\n        public string ShortName => \"NativeMemory\";\n\n        [PublicAPI] // parameterless ctor required by DiagnosersLoader to support creating this profiler via console line args\n        public NativeMemoryProfiler() => etwProfiler = new EtwProfiler(CreateDefaultConfig());\n\n        public IEnumerable<string> Ids => [nameof(NativeMemoryProfiler)];\n\n        public IEnumerable<IExporter> Exporters => [];\n\n        public IEnumerable<IAnalyser> Analysers => [];\n\n        public void DisplayResults(ILogger resultLogger)\n        {\n            if (etwProfiler.BenchmarkToEtlFile.Any())\n            {\n                resultLogger.WriteLineInfo($\"Exported {etwProfiler.BenchmarkToEtlFile.Count} trace file(s). Example:\");\n                resultLogger.WriteLineInfo(etwProfiler.BenchmarkToEtlFile.Values.First());\n            }\n\n            foreach (var line in logger.CapturedOutput)\n                resultLogger.Write(line.Kind, line.Text);\n        }\n\n        public void Handle(HostSignal signal, DiagnoserActionParameters parameters) => etwProfiler.Handle(signal, parameters);\n\n        public RunMode GetRunMode(BenchmarkCase benchmarkCase) => etwProfiler.GetRunMode(benchmarkCase);\n\n        public IEnumerable<Metric> ProcessResults(DiagnoserResults results)\n        {\n            if (!etwProfiler.BenchmarkToEtlFile.TryGetValue(results.BenchmarkCase, out var traceFilePath))\n                return [];\n\n            return new NativeMemoryLogParser(traceFilePath, results.BenchmarkCase, logger, results.BuildResult.ArtifactsPaths.ProgramName).Parse();\n        }\n\n        public IEnumerable<ValidationError> Validate(ValidationParameters validationParameters) => etwProfiler.Validate(validationParameters);\n\n        private static EtwProfilerConfig CreateDefaultConfig()\n        {\n            // We add VirtualAlloc because we want to catch low level VirtualAlloc and VirtualFree calls.\n            // We should add also VAMap which means that we want to log mapping of files into memory.\n            var kernelKeywords = KernelTraceEventParser.Keywords.VirtualAlloc | KernelTraceEventParser.Keywords.VAMap;\n\n            return new EtwProfilerConfig(\n                performExtraBenchmarksRun: true,\n                kernelKeywords: kernelKeywords,\n                createHeapSession: true);\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet.Diagnostics.Windows/Properties/AssemblyInfo.cs",
    "content": "﻿using System;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\nusing BenchmarkDotNet.Properties;\n\n[assembly: Guid(\"7bbae514-895c-4ca5-95ba-b2a1a0c2e0af\")]\n\n[assembly: CLSCompliant(true)]\n\n[assembly: InternalsVisibleTo(\"BenchmarkDotNet.IntegrationTests,PublicKey=\" + BenchmarkDotNetInfo.PublicKey)]\n"
  },
  {
    "path": "src/BenchmarkDotNet.Diagnostics.Windows/Sessions.cs",
    "content": "using System;\nusing System.ComponentModel;\nusing System.IO;\nusing System.Linq;\nusing BenchmarkDotNet.Diagnosers;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Exporters;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Helpers;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Running;\nusing Microsoft.Diagnostics.Tracing;\nusing Microsoft.Diagnostics.Tracing.Parsers;\nusing Microsoft.Diagnostics.Tracing.Session;\n\nnamespace BenchmarkDotNet.Diagnostics.Windows\n{\n    internal class HeapSession : Session\n    {\n        public HeapSession(DiagnoserActionParameters details, EtwProfilerConfig config, DateTime creationTime)\n            : base(GetSessionName(details.BenchmarkCase) + \"Heap\", details, config, creationTime)\n        {\n        }\n\n        protected override string FileExtension => \"userheap.etl\";\n\n        internal override Session EnableProviders()\n        {\n            var osHeapExe = Path.GetFileName(Path.ChangeExtension(Details.Process!.StartInfo.FileName, \".exe\"));\n            TraceEventSession.EnableWindowsHeapProvider(osHeapExe);\n            return this;\n        }\n    }\n\n    internal class UserSession : Session\n    {\n        public UserSession(DiagnoserActionParameters details, EtwProfilerConfig config, DateTime creationTime)\n            : base(GetSessionName(details.BenchmarkCase), details, config, creationTime)\n        {\n        }\n\n        protected override string FileExtension => \"etl\";\n\n        internal override Session EnableProviders()\n        {\n            TraceEventSession.EnableProvider(EngineEventSource.Log.Name, TraceEventLevel.Informational); // mandatory provider to enable Engine events\n\n            foreach (var provider in Config.Providers)\n            {\n                TraceEventSession.EnableProvider(provider.providerGuid, provider.providerLevel, provider.keywords, provider.options);\n            }\n\n            return this;\n        }\n    }\n\n    internal class KernelSession : Session\n    {\n        public KernelSession(DiagnoserActionParameters details, EtwProfilerConfig config, DateTime creationTime)\n            : base(KernelTraceEventParser.KernelSessionName, details, config, creationTime)\n        {\n        }\n\n        protected override string FileExtension => \"kernel.etl\";\n\n        internal override Session EnableProviders()\n        {\n            var keywords = Config.KernelKeywords\n                | KernelTraceEventParser.Keywords.ImageLoad // handles stack frames from native modules, SUPER IMPORTANT!\n                | KernelTraceEventParser.Keywords.Profile; // CPU stacks\n\n            if (Details.Config.GetHardwareCounters().Any())\n                keywords |= KernelTraceEventParser.Keywords.PMCProfile; // Precise Machine Counters\n\n            TraceEventSession.StackCompression = true;\n\n            try\n            {\n                TraceEventSession.EnableKernelProvider(keywords, Config.KernelStackKeywords);\n            }\n            catch (Win32Exception)\n            {\n                Details.Config.GetCompositeLogger().WriteLineError(\n                    \"Please install the latest Microsoft.Diagnostics.Tracing.TraceEvent package in the project with benchmarks so MSBuild can copy the native dependencies of TraceEvent to the output folder.\");\n\n                throw;\n            }\n\n            return this;\n        }\n    }\n\n    internal abstract class Session : DisposeAtProcessTermination\n    {\n        private const int MaxSessionNameLength = 128;\n\n        protected abstract string FileExtension { get; }\n\n        protected TraceEventSession TraceEventSession { get; }\n\n        protected DiagnoserActionParameters Details { get; }\n\n        protected EtwProfilerConfig Config { get; }\n\n        internal string FilePath { get; }\n\n        protected Session(string sessionName, DiagnoserActionParameters details, EtwProfilerConfig config, DateTime creationTime)\n        {\n            Details = details;\n            Config = config;\n            FilePath = ArtifactFileNameHelper.GetTraceFilePath(details, creationTime, FileExtension).EnsureFolderExists();\n            TraceEventSession = new TraceEventSession(sessionName, FilePath)\n            {\n                BufferSizeMB = config.BufferSizeInMb,\n                CpuSampleIntervalMSec = config.CpuSampleIntervalInMilliseconds,\n            };\n        }\n\n        public override void Dispose()\n        {\n            TraceEventSession.Dispose();\n            base.Dispose();\n        }\n\n        internal abstract Session EnableProviders();\n\n        protected static string GetSessionName(BenchmarkCase benchmarkCase)\n        {\n            string benchmarkName = FullNameProvider.GetBenchmarkName(benchmarkCase);\n            if (benchmarkName.Length <= MaxSessionNameLength)\n                return benchmarkName;\n\n            // session name is not really used by humans, we can just give it the hashcode value\n            return $\"BenchmarkDotNet.EtwProfiler.Session_{Hashing.HashString(benchmarkName)}\";\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet.Diagnostics.Windows/TailCallDiagnoser.cs",
    "content": "﻿using System.Collections.Generic;\nusing BenchmarkDotNet.Running;\nusing Microsoft.Diagnostics.Tracing.Session;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Diagnosers;\n\nnamespace BenchmarkDotNet.Diagnostics.Windows\n{\n    /// <summary>\n    /// See <see href=\"https://blogs.msdn.microsoft.com/clrcodegeneration/2009/05/11/jit-etw-tracing-in-net-framework-4/\">MSDN blog post about JIT tracing events</see>\n    /// and <see href=\"https://georgeplotnikov.github.io/articles/tale-tail-call-dotnet\">detailed blog post by George Plotnikov</see> for more info\n    /// </summary>\n    public class TailCallDiagnoser : JitDiagnoser<object>, IProfiler\n    {\n        private static readonly string LogSeparator = new string('-', 20);\n\n        private readonly bool logFailuresOnly = true;\n        private readonly bool filterByNamespace = true;\n        private string expectedNamespace = default!;\n\n        public TailCallDiagnoser() { }\n\n        /// <summary>\n        /// creates the new TailCallDiagnoser instance\n        /// </summary>\n        /// <param name=\"logFailuresOnly\">only the methods that failed to get tail called. True by default.</param>\n        /// <param name=\"filterByNamespace\">only the methods from declaring type's namespace. Set to false if you want to see all Jit tail events. True by default.</param>\n        public TailCallDiagnoser(bool logFailuresOnly = true, bool filterByNamespace = true)\n        {\n            this.logFailuresOnly = logFailuresOnly;\n            this.filterByNamespace = filterByNamespace;\n        }\n\n        public override IEnumerable<string> Ids => [nameof(TailCallDiagnoser)];\n\n        public string ShortName => \"tail\";\n\n        protected override void AttachToEvents(TraceEventSession traceEventSession, BenchmarkCase benchmarkCase)\n        {\n            expectedNamespace = benchmarkCase.Descriptor.WorkloadMethod.DeclaringType.Namespace ?? benchmarkCase.Descriptor.WorkloadMethod.DeclaringType.FullName;\n\n            Logger.WriteLine();\n            Logger.WriteLineHeader(LogSeparator);\n            Logger.WriteLineInfo($\"{benchmarkCase.DisplayInfo}\");\n            Logger.WriteLineHeader(LogSeparator);\n\n            traceEventSession.Source.Clr.MethodTailCallSucceeded += jitData =>\n            {\n                if (!logFailuresOnly && ShouldPrintEventInfo(jitData.CallerNamespace, jitData.CalleeNamespace))\n                {\n                    if (StatsPerProcess.TryGetValue(jitData.ProcessID, out object ignored))\n                    {\n                        Logger.WriteLineHelp($\"Caller: {jitData.CallerNamespace}.{jitData.CallerName} - {jitData.CallerNameSignature}\");\n                        Logger.WriteLineHelp($\"Callee: {jitData.CalleeNamespace}.{jitData.CalleeName} - {jitData.CalleeNameSignature}\");\n                        Logger.WriteLineHelp($\"Tail prefix: {jitData.TailPrefix}\");\n                        Logger.WriteLineHelp($\"Tail call type: {jitData.TailCallType}\");\n                        Logger.WriteLineHeader(LogSeparator);\n                    }\n                }\n            };\n            traceEventSession.Source.Clr.MethodTailCallFailed += jitData =>\n            {\n                if (ShouldPrintEventInfo(jitData.CallerNamespace, jitData.CalleeNamespace))\n                {\n                    if (StatsPerProcess.TryGetValue(jitData.ProcessID, out object ignored))\n                    {\n                        Logger.WriteLineHelp($\"Caller: {jitData.CallerNamespace}.{jitData.CallerName} - {jitData.CallerNameSignature}\");\n                        Logger.WriteLineHelp($\"Callee: {jitData.CalleeNamespace}.{jitData.CalleeName} - {jitData.CalleeNameSignature}\");\n                        Logger.WriteLineError($\"Fail Reason: {jitData.FailReason}\");\n                        Logger.WriteLineHeader(LogSeparator);\n                    }\n                }\n            };\n            traceEventSession.Source.Clr.MethodTailCallFailedAnsi += jitData => // this is new event exposed by .NET Core 2.2 https://github.com/dotnet/coreclr/commit/95a9055dbe5f6233f75ee2d7b6194e18cc4977fd\n            {\n                if (ShouldPrintEventInfo(jitData.CallerNamespace, jitData.CalleeNamespace))\n                {\n                    if (StatsPerProcess.TryGetValue(jitData.ProcessID, out object ignored))\n                    {\n                        Logger.WriteLineHelp($\"Caller: {jitData.CallerNamespace}.{jitData.CallerName} - {jitData.CallerNameSignature}\");\n                        Logger.WriteLineHelp($\"Callee: {jitData.CalleeNamespace}.{jitData.CalleeName} - {jitData.CalleeNameSignature}\");\n                        Logger.WriteLineError($\"Fail Reason: {jitData.FailReason}\");\n                        Logger.WriteLineHeader(LogSeparator);\n                    }\n                }\n            };\n        }\n\n        private bool ShouldPrintEventInfo(string callerNamespace, string calleeNamespace) =>\n            !filterByNamespace\n                    || (!string.IsNullOrEmpty(callerNamespace) && callerNamespace.StartsWith(expectedNamespace))\n                    || (!string.IsNullOrEmpty(calleeNamespace) && calleeNamespace.StartsWith(expectedNamespace));\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet.Diagnostics.Windows/Tracing/BenchmarkEvent.cs",
    "content": "﻿using System;\nusing System.Text;\nusing Microsoft.Diagnostics.Tracing;\n\nnamespace BenchmarkDotNet.Diagnostics.Windows.Tracing\n{\n    public sealed class BenchmarkEvent : TraceEvent\n    {\n        public string BenchmarkName => GetUnicodeStringAt(0);\n\n        private event Action<BenchmarkEvent> target;\n\n        internal BenchmarkEvent(Action<BenchmarkEvent> target, int eventID, int task, string taskName, Guid taskGuid, int opcode, string opcodeName, Guid providerGuid, string providerName)\n            : base(eventID, task, taskName, taskGuid, opcode, opcodeName, providerGuid, providerName)\n        {\n            this.target = target;\n        }\n\n        protected override Delegate Target\n        {\n            get => target;\n            set => target = (Action<BenchmarkEvent>)value;\n        }\n\n        public override string[] PayloadNames => payloadNames ?? (payloadNames = [nameof(BenchmarkName)]);\n\n        public override StringBuilder ToXml(StringBuilder sb)\n        {\n            Prefix(sb);\n            XmlAttrib(sb, nameof(BenchmarkName), BenchmarkName);\n            sb.Append(\"/>\");\n\n            return sb;\n        }\n\n        public override object? PayloadValue(int index) => index == 0 ? BenchmarkName : null;\n\n        protected override void Dispatch() => target?.Invoke(this);\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet.Diagnostics.Windows/Tracing/EngineEventLogParser.cs",
    "content": "﻿using System;\nusing System.Diagnostics.Tracing;\nusing BenchmarkDotNet.Engines;\nusing Microsoft.Diagnostics.Tracing;\nusing Microsoft.Diagnostics.Tracing.Session;\n\nnamespace BenchmarkDotNet.Diagnostics.Windows.Tracing\n{\n    public sealed class EngineEventLogParser : TraceEventParser\n    {\n        private static volatile TraceEvent[]? templates;\n\n        public EngineEventLogParser(TraceEventSource source, bool dontRegister = false) : base(source, dontRegister) { }\n\n        private static string ProviderName => EngineEventSource.Log.Name;\n\n        private static Guid ProviderGuid => TraceEventProviders.GetEventSourceGuidFromName(ProviderName);\n\n        public event Action<IterationEvent> BenchmarkStart\n        {\n            add => source.RegisterEventTemplate(BenchmarkStartTemplate(value));\n            remove => source.UnregisterEventTemplate(value, EngineEventSource.BenchmarkStartEventId, ProviderGuid);\n        }\n\n        public event Action<IterationEvent> BenchmarkStop\n        {\n            add => source.RegisterEventTemplate(BenchmarkStopTemplate(value));\n            remove => source.UnregisterEventTemplate(value, EngineEventSource.BenchmarkStopEventId, ProviderGuid);\n        }\n\n        public event Action<IterationEvent> OverheadJittingStart\n        {\n            add => source.RegisterEventTemplate(OverheadJittingStartTemplate(value));\n            remove => source.UnregisterEventTemplate(value, EngineEventSource.OverheadJittingStartEventId, ProviderGuid);\n        }\n\n        public event Action<IterationEvent> OverheadJittingStop\n        {\n            add => source.RegisterEventTemplate(OverheadJittingStopTemplate(value));\n            remove => source.UnregisterEventTemplate(value, EngineEventSource.OverheadJittingStopEventId, ProviderGuid);\n        }\n\n        public event Action<IterationEvent> WorkloadJittingStart\n        {\n            add => source.RegisterEventTemplate(WorkloadJittingStartTemplate(value));\n            remove => source.UnregisterEventTemplate(value, EngineEventSource.WorkloadJittingStartEventId, ProviderGuid);\n        }\n\n        public event Action<IterationEvent> WorkloadJittingStop\n        {\n            add => source.RegisterEventTemplate(WorkloadJittingStopTemplate(value));\n            remove => source.UnregisterEventTemplate(value, EngineEventSource.WorkloadJittingStopEventId, ProviderGuid);\n        }\n\n        public event Action<IterationEvent> WorkloadPilotStart\n        {\n            add => source.RegisterEventTemplate(WorkloadPilotStartTemplate(value));\n            remove => source.UnregisterEventTemplate(value, EngineEventSource.WorkloadPilotStartEventId, ProviderGuid);\n        }\n\n        public event Action<IterationEvent> WorkloadPilotStop\n        {\n            add => source.RegisterEventTemplate(WorkloadPilotStopTemplate(value));\n            remove => source.UnregisterEventTemplate(value, EngineEventSource.WorkloadPilotStopEventId, ProviderGuid);\n        }\n\n        public event Action<IterationEvent> OverheadWarmupStart\n        {\n            add => source.RegisterEventTemplate(OverheadWarmupStartTemplate(value));\n            remove => source.UnregisterEventTemplate(value, EngineEventSource.OverheadWarmupStartEventId, ProviderGuid);\n        }\n\n        public event Action<IterationEvent> OverheadWarmupStop\n        {\n            add => source.RegisterEventTemplate(OverheadWarmupStopTemplate(value));\n            remove => source.UnregisterEventTemplate(value, EngineEventSource.OverheadWarmupStopEventId, ProviderGuid);\n        }\n\n        public event Action<IterationEvent> WorkloadWarmupStart\n        {\n            add => source.RegisterEventTemplate(WorkloadWarmupStartTemplate(value));\n            remove => source.UnregisterEventTemplate(value, EngineEventSource.WorkloadWarmupStartEventId, ProviderGuid);\n        }\n\n        public event Action<IterationEvent> WorkloadWarmupStop\n        {\n            add => source.RegisterEventTemplate(WorkloadWarmupStopTemplate(value));\n            remove => source.UnregisterEventTemplate(value, EngineEventSource.WorkloadWarmupStopEventId, ProviderGuid);\n        }\n\n        public event Action<IterationEvent> OverheadActualStart\n        {\n            add => source.RegisterEventTemplate(OverheadActualStartTemplate(value));\n            remove => source.UnregisterEventTemplate(value, EngineEventSource.OverheadActualStartEventId, ProviderGuid);\n        }\n\n        public event Action<IterationEvent> OverheadActualStop\n        {\n            add => source.RegisterEventTemplate(OverheadActualStopTemplate(value));\n            remove => source.UnregisterEventTemplate(value, EngineEventSource.OverheadActualStopEventId, ProviderGuid);\n        }\n\n        public event Action<IterationEvent> WorkloadActualStart\n        {\n            add => source.RegisterEventTemplate(WorkloadActualStartTemplate(value));\n            remove => source.UnregisterEventTemplate(value, EngineEventSource.WorkloadActualStartEventId, ProviderGuid);\n        }\n\n        public event Action<IterationEvent> WorkloadActualStop\n        {\n            add => source.RegisterEventTemplate(WorkloadActualStopTemplate(value));\n            remove => source.UnregisterEventTemplate(value, EngineEventSource.WorkloadActualStopEventId, ProviderGuid);\n        }\n\n        protected override string GetProviderName() { return ProviderName; }\n\n        private static IterationEvent BenchmarkStartTemplate(Action<IterationEvent>? action)\n        {                  // action, eventid, taskid, taskName, taskGuid, opcode, opcodeName, providerGuid, providerName\n            return new IterationEvent(action, EngineEventSource.BenchmarkStartEventId, (int)EngineEventSource.Tasks.Benchmark, nameof(EngineEventSource.Tasks.Benchmark), Guid.Empty, (int)EventOpcode.Start, nameof(EventOpcode.Start), ProviderGuid, ProviderName);\n        }\n\n        private static IterationEvent BenchmarkStopTemplate(Action<IterationEvent>? action)\n        {                  // action, eventid, taskid, taskName, taskGuid, opcode, opcodeName, providerGuid, providerName\n            return new IterationEvent(action, EngineEventSource.BenchmarkStopEventId, (int)EngineEventSource.Tasks.Benchmark, nameof(EngineEventSource.Tasks.Benchmark), Guid.Empty, (int)EventOpcode.Stop, nameof(EventOpcode.Stop), ProviderGuid, ProviderName);\n        }\n\n        private static IterationEvent OverheadJittingStartTemplate(Action<IterationEvent>? action)\n            => CreateIterationStartTemplate(action, EngineEventSource.OverheadJittingStartEventId, EngineEventSource.Tasks.OverheadJitting);\n\n        private static IterationEvent OverheadJittingStopTemplate(Action<IterationEvent>? action)\n            => CreateIterationStopTemplate(action, EngineEventSource.OverheadJittingStopEventId, EngineEventSource.Tasks.OverheadJitting);\n\n        private static IterationEvent WorkloadJittingStartTemplate(Action<IterationEvent>? action)\n            => CreateIterationStartTemplate(action, EngineEventSource.WorkloadJittingStartEventId, EngineEventSource.Tasks.WorkloadJitting);\n\n        private static IterationEvent WorkloadJittingStopTemplate(Action<IterationEvent>? action)\n            => CreateIterationStopTemplate(action, EngineEventSource.WorkloadJittingStopEventId, EngineEventSource.Tasks.WorkloadJitting);\n\n        private static IterationEvent WorkloadPilotStartTemplate(Action<IterationEvent>? action)\n            => CreateIterationStartTemplate(action, EngineEventSource.WorkloadPilotStartEventId, EngineEventSource.Tasks.WorkloadPilot);\n\n        private static IterationEvent WorkloadPilotStopTemplate(Action<IterationEvent>? action)\n            => CreateIterationStopTemplate(action, EngineEventSource.WorkloadPilotStopEventId, EngineEventSource.Tasks.WorkloadPilot);\n\n        private static IterationEvent OverheadWarmupStartTemplate(Action<IterationEvent>? action)\n            => CreateIterationStartTemplate(action, EngineEventSource.OverheadWarmupStartEventId, EngineEventSource.Tasks.OverheadWarmup);\n\n        private static IterationEvent OverheadWarmupStopTemplate(Action<IterationEvent>? action)\n            => CreateIterationStopTemplate(action, EngineEventSource.OverheadWarmupStopEventId, EngineEventSource.Tasks.OverheadWarmup);\n\n        private static IterationEvent WorkloadWarmupStartTemplate(Action<IterationEvent>? action)\n            => CreateIterationStartTemplate(action, EngineEventSource.WorkloadWarmupStartEventId, EngineEventSource.Tasks.WorkloadWarmup);\n\n        private static IterationEvent WorkloadWarmupStopTemplate(Action<IterationEvent>? action)\n            => CreateIterationStopTemplate(action, EngineEventSource.WorkloadWarmupStopEventId, EngineEventSource.Tasks.WorkloadWarmup);\n\n        private static IterationEvent OverheadActualStartTemplate(Action<IterationEvent>? action)\n            => CreateIterationStartTemplate(action, EngineEventSource.OverheadActualStartEventId, EngineEventSource.Tasks.OverheadActual);\n\n        private static IterationEvent OverheadActualStopTemplate(Action<IterationEvent>? action)\n            => CreateIterationStopTemplate(action, EngineEventSource.OverheadActualStopEventId, EngineEventSource.Tasks.OverheadActual);\n\n        private static IterationEvent WorkloadActualStartTemplate(Action<IterationEvent>? action)\n            => CreateIterationStartTemplate(action, EngineEventSource.WorkloadActualStartEventId, EngineEventSource.Tasks.WorkloadActual);\n\n        private static IterationEvent WorkloadActualStopTemplate(Action<IterationEvent>? action)\n            => CreateIterationStopTemplate(action, EngineEventSource.WorkloadActualStopEventId, EngineEventSource.Tasks.WorkloadActual);\n\n        private static IterationEvent CreateIterationStartTemplate(Action<IterationEvent>? action, int eventId, EventTask eventTask)\n        {                  // action, eventid, taskid, taskName, taskGuid, opcode, opcodeName, providerGuid, providerName\n            return new IterationEvent(action, eventId, (int)eventTask, eventTask.ToString(), Guid.Empty, (int)EventOpcode.Start, nameof(EventOpcode.Start), ProviderGuid, ProviderName);\n        }\n\n        private static IterationEvent CreateIterationStopTemplate(Action<IterationEvent>? action, int eventId, EventTask eventTask)\n        {                  // action, eventid, taskid, taskName, taskGuid, opcode, opcodeName, providerGuid, providerName\n            return new IterationEvent(action, eventId, (int)eventTask, eventTask.ToString(), Guid.Empty, (int)EventOpcode.Stop, nameof(EventOpcode.Stop), ProviderGuid, ProviderName);\n        }\n\n        protected override void EnumerateTemplates(Func<string, string, EventFilterResponse>? eventsToObserve, Action<TraceEvent> callback)\n        {\n            if (templates == null)\n            {\n                var templates = new TraceEvent[16];\n                templates[0] = BenchmarkStartTemplate(null);\n                templates[1] = BenchmarkStopTemplate(null);\n                templates[2] = OverheadJittingStartTemplate(null);\n                templates[3] = OverheadJittingStopTemplate(null);\n                templates[4] = WorkloadJittingStartTemplate(null);\n                templates[5] = WorkloadJittingStopTemplate(null);\n                templates[6] = WorkloadPilotStartTemplate(null);\n                templates[7] = WorkloadPilotStopTemplate(null);\n                templates[8] = OverheadWarmupStartTemplate(null);\n                templates[9] = OverheadWarmupStopTemplate(null);\n                templates[10] = OverheadActualStartTemplate(null);\n                templates[11] = OverheadActualStopTemplate(null);\n                templates[12] = WorkloadWarmupStartTemplate(null);\n                templates[13] = WorkloadWarmupStopTemplate(null);\n                templates[14] = WorkloadActualStartTemplate(null);\n                templates[15] = WorkloadActualStopTemplate(null);\n                EngineEventLogParser.templates = templates;\n            }\n\n            foreach (var template in templates)\n                if (eventsToObserve == null || eventsToObserve(template.ProviderName, template.EventName) == EventFilterResponse.AcceptEvent)\n                    callback(template);\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet.Diagnostics.Windows/Tracing/IterationEvent.cs",
    "content": "﻿using System;\nusing System.Diagnostics;\nusing System.Text;\nusing Microsoft.Diagnostics.Tracing;\n\nnamespace BenchmarkDotNet.Diagnostics.Windows.Tracing\n{\n    public sealed class IterationEvent : TraceEvent\n    {\n        public long TotalOperations => GetInt64At(0);\n\n        private event Action<IterationEvent>? target;\n\n        internal IterationEvent(Action<IterationEvent>? target, int eventId, int task, string taskName, Guid taskGuid, int opcode, string opcodeName, Guid providerGuid, string providerName)\n            : base(eventId, task, taskName, taskGuid, opcode, opcodeName, providerGuid, providerName)\n        {\n            this.target = target;\n        }\n\n        protected override Delegate? Target\n        {\n            get => target;\n            set => target = (Action<IterationEvent>?)value;\n        }\n\n        public override string[] PayloadNames => payloadNames ?? (payloadNames = [nameof(TotalOperations)]);\n\n        public override StringBuilder ToXml(StringBuilder sb)\n        {\n            Prefix(sb);\n            XmlAttrib(sb, nameof(TotalOperations), TotalOperations);\n            sb.Append(\"/>\");\n\n            return sb;\n        }\n\n        public override object? PayloadValue(int index) => index == 0 ? TotalOperations : null;\n\n        protected override void Dispatch() => target?.Invoke(this);\n\n        protected override void Validate() => Debug.Assert(!(Version == 0 && GetInt64At(0) == 0));\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet.Diagnostics.Windows/Tracing/NativeMemoryLogParser.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Diagnostics.CodeAnalysis;\nusing System.Linq;\nusing BenchmarkDotNet.Diagnosers;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Running;\nusing Microsoft.Diagnostics.Tracing.Etlx;\nusing Microsoft.Diagnostics.Tracing.Parsers.Kernel;\nusing Microsoft.Diagnostics.Tracing.Stacks;\nusing Perfolizer.Metrology;\nusing Address = System.UInt64;\n\nnamespace BenchmarkDotNet.Diagnostics.Windows.Tracing\n{\n    [SuppressMessage(\"StyleCop.CSharp.ReadabilityRules\", \"SA1121:UseBuiltInTypeAlias\")]\n    public class NativeMemoryLogParser\n    {\n        private static readonly string LogSeparator = new string('-', 20);\n\n        private readonly string etlFilePath;\n\n        private readonly BenchmarkCase benchmarkCase;\n\n        private readonly ILogger logger;\n\n        private readonly string moduleName;\n\n        private readonly string[] functionNames;\n\n        public NativeMemoryLogParser(string etlFilePath, BenchmarkCase benchmarkCase, ILogger logger,\n            string programName)\n        {\n            this.etlFilePath = etlFilePath;\n            this.benchmarkCase = benchmarkCase;\n            this.logger = logger;\n\n            moduleName = programName.ToLowerInvariant();\n            functionNames =\n            [\n                nameof(EngineParameters.WorkloadActionUnroll),\n                nameof(EngineParameters.WorkloadActionNoUnroll)\n            ];\n        }\n\n        public IEnumerable<Metric> Parse()\n        {\n            var etlxFilePath = TraceLog.CreateFromEventTraceLogFile(etlFilePath);\n\n            try\n            {\n                using (var traceLog = new TraceLog(etlxFilePath))\n                {\n                    return Parse(traceLog);\n                }\n            }\n            finally\n            {\n                etlxFilePath.DeleteFileIfExists();\n            }\n        }\n\n        //Code is inspired by https://github.com/Microsoft/perfview/blob/master/src/PerfView/PerfViewData.cs#L5719-L5944\n        private IEnumerable<Metric> Parse(TraceLog traceLog)\n        {\n            var stackSource = new MutableTraceEventStackSource(traceLog);\n            var eventSource = traceLog.Events.GetSource();\n\n            var bdnEventsParser = new EngineEventLogParser(eventSource);\n\n            var start = false;\n            var isFirstActualStartEnd = false;\n\n            long totalOperation = 0;\n            long countOfAllocatedObject = 0;\n\n            bdnEventsParser.WorkloadActualStart += data =>\n            {\n                if (!isFirstActualStartEnd)\n                {\n                    start = true;\n                }\n\n                totalOperation = data.TotalOperations;\n            };\n            bdnEventsParser.WorkloadActualStop += data =>\n            {\n                start = false;\n                isFirstActualStartEnd = true;\n            };\n\n            var heapParser = new HeapTraceProviderTraceEventParser(eventSource);\n            // We index by heap address and then within the heap we remember the allocation stack\n            var heaps = new Dictionary<Address, Dictionary<Address, long>>();\n            Dictionary<Address, long>? lastHeapAllocs = null;\n\n            Address lastHeapHandle = 0;\n\n            long nativeLeakSize = 0;\n            long totalAllocation = 0;\n\n            heapParser.HeapTraceAlloc += delegate (HeapAllocTraceData data)\n            {\n                if (!start)\n                {\n                    return;\n                }\n\n                var call = data.CallStackIndex();\n                var frameIndex = stackSource.GetCallStack(call, data);\n\n                if (!IsCallStackIn(frameIndex))\n                {\n                    return;\n                }\n\n                var allocs = lastHeapAllocs!;\n                if (data.HeapHandle != lastHeapHandle)\n                {\n                    allocs = CreateHeapCache(data.HeapHandle, heaps, ref lastHeapAllocs, ref lastHeapHandle);\n                }\n\n                allocs[data.AllocAddress] = data.AllocSize;\n\n                checked\n                {\n                    countOfAllocatedObject++;\n                    nativeLeakSize += data.AllocSize;\n                    totalAllocation += data.AllocSize;\n                }\n\n                bool IsCallStackIn(StackSourceCallStackIndex index)\n                {\n                    while (index != StackSourceCallStackIndex.Invalid)\n                    {\n                        var frame = stackSource.GetFrameIndex(index);\n                        var name = stackSource.GetFrameName(frame, false);\n\n                        if (name.StartsWith(moduleName, StringComparison.Ordinal) &&\n                            functionNames.Any(functionName => name.IndexOf(functionName, StringComparison.Ordinal) > 0))\n                        {\n                            return true;\n                        }\n\n                        index = stackSource.GetCallerIndex(index);\n                    }\n\n                    return false;\n                }\n            };\n\n            heapParser.HeapTraceFree += delegate (HeapFreeTraceData data)\n            {\n                if (!start)\n                {\n                    return;\n                }\n\n                var allocs = lastHeapAllocs!;\n                if (data.HeapHandle != lastHeapHandle)\n                {\n                    allocs = CreateHeapCache(data.HeapHandle, heaps, ref lastHeapAllocs, ref lastHeapHandle);\n                }\n\n                if (allocs.TryGetValue(data.FreeAddress, out long alloc))\n                {\n                    nativeLeakSize -= alloc;\n\n                    allocs.Remove(data.FreeAddress);\n                }\n            };\n\n            heapParser.HeapTraceReAlloc += delegate (HeapReallocTraceData data)\n            {\n                if (!start)\n                {\n                    return;\n                }\n                // Reallocs that actually move stuff will cause a Alloc and delete event\n                // so there is nothing to do for those events. But when the address is\n                // the same we need to resize.\n                if (data.OldAllocAddress != data.NewAllocAddress)\n                {\n                    return;\n                }\n\n                var allocs = lastHeapAllocs!;\n                if (data.HeapHandle != lastHeapHandle)\n                {\n                    allocs = CreateHeapCache(data.HeapHandle, heaps, ref lastHeapAllocs, ref lastHeapHandle);\n                }\n\n                if (allocs.TryGetValue(data.OldAllocAddress, out long alloc))\n                {\n                    // Free\n                    nativeLeakSize -= alloc;\n\n                    allocs.Remove(data.OldAllocAddress);\n\n                    // Alloc\n                    allocs[data.NewAllocAddress] = data.NewAllocSize;\n\n                    checked\n                    {\n                        nativeLeakSize += data.NewAllocSize;\n                    }\n                }\n            };\n\n            heapParser.HeapTraceDestroy += delegate (HeapTraceData data)\n            {\n                if (!start)\n                {\n                    return;\n                }\n\n                // Heap is dying, kill all objects in it.\n                var allocs = lastHeapAllocs!;\n                if (data.HeapHandle != lastHeapHandle)\n                {\n                    allocs = CreateHeapCache(data.HeapHandle, heaps, ref lastHeapAllocs, ref lastHeapHandle);\n                }\n\n                foreach (var alloc in allocs.Values)\n                {\n                    nativeLeakSize -= alloc;\n                }\n            };\n\n            eventSource.Process();\n\n            logger.WriteLine();\n            logger.WriteLineHeader(LogSeparator);\n            logger.WriteLineInfo($\"{benchmarkCase.DisplayInfo}\");\n            logger.WriteLineHeader(LogSeparator);\n\n            if (totalOperation == 0)\n            {\n                logger.WriteLine($\"Something went wrong. The trace file {etlFilePath} does not contain BenchmarkDotNet engine events.\");\n                return [];\n            }\n\n            var memoryAllocatedPerOperation = totalAllocation / totalOperation;\n            var memoryLeakPerOperation = nativeLeakSize / totalOperation;\n\n            logger.WriteLine(\n                $\"Native memory allocated per single operation: \" +\n                $\"{PerfolizerMeasurementFormatter.Instance.Format(\n                    SizeValue.FromBytes(memoryAllocatedPerOperation).ToMeasurement(SizeUnit.B),\n                    formatProvider: benchmarkCase.Config.CultureInfo)}\");\n            logger.WriteLine($\"Count of allocated object: {countOfAllocatedObject / totalOperation}\");\n\n            if (nativeLeakSize != 0)\n            {\n                logger.WriteLine(\n                    $\"Native memory leak per single operation: \" +\n                    $\"{PerfolizerMeasurementFormatter.Instance.Format(\n                        SizeValue.FromBytes(memoryLeakPerOperation).ToMeasurement(SizeUnit.B),\n                        formatProvider: benchmarkCase.Config.CultureInfo)}\");\n            }\n\n            var heapInfoList = heaps.Select(h => new { Address = h.Key, h.Value.Count, types = h.Value.Values });\n            foreach (var item in heapInfoList.Where(p => p.Count > 0))\n            {\n                logger.WriteLine($\"Count of not deallocated object: {item.Count / totalOperation}\");\n            }\n\n            return\n            [\n                new Metric(AllocatedNativeMemoryDescriptor.Instance, memoryAllocatedPerOperation),\n                new Metric(NativeMemoryLeakDescriptor.Instance, memoryLeakPerOperation)\n            ];\n        }\n\n        private static Dictionary<Address, long> CreateHeapCache(\n            Address heapHandle,\n            Dictionary<Address, Dictionary<Address, long>> heaps,\n            ref Dictionary<Address, long>? lastHeapAllocs,\n            ref Address lastHeapHandle)\n        {\n            Dictionary<Address, long> ret;\n\n            if (!heaps.TryGetValue(heapHandle, out ret))\n            {\n                ret = [];\n                heaps.Add(heapHandle, ret);\n            }\n\n            lastHeapHandle = heapHandle;\n            lastHeapAllocs = ret;\n            return ret;\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet.Diagnostics.Windows/Tracing/TraceLogParser.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing BenchmarkDotNet.Diagnosers;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Reports;\nusing Microsoft.Diagnostics.Tracing.Etlx;\nusing Microsoft.Diagnostics.Tracing.Parsers;\nusing Microsoft.Diagnostics.Tracing.Parsers.Kernel;\n\nnamespace BenchmarkDotNet.Diagnostics.Windows.Tracing\n{\n    public class TraceLogParser\n    {\n        private readonly Dictionary<int, ProcessMetrics> processIdToData = [];\n        private readonly Dictionary<int, int> profileSourceIdToInterval = [];\n\n        public static IEnumerable<Metric> Parse(string etlFilePath, PreciseMachineCounter[] counters)\n        {\n            var etlxFilePath = TraceLog.CreateFromEventTraceLogFile(etlFilePath);\n\n            try\n            {\n                using (var traceLog = new TraceLog(etlxFilePath))\n                {\n                    var traceLogEventSource = traceLog.Events.GetSource();\n\n                    return new TraceLogParser().Parse(traceLogEventSource, counters);\n                }\n            }\n            finally\n            {\n                etlxFilePath.DeleteFileIfExists();\n            }\n        }\n\n        private IEnumerable<Metric> Parse(TraceLogEventSource traceLogEventSource, PreciseMachineCounter[] counters)\n        {\n            var bdnEventsParser = new EngineEventLogParser(traceLogEventSource);\n            var kernelEventsParser = new KernelTraceEventParser(traceLogEventSource);\n\n            bdnEventsParser.OverheadActualStart += OnOverheadActualStart;\n            bdnEventsParser.OverheadActualStop += OnOverheadActualStop;\n\n            bdnEventsParser.WorkloadActualStart += OnWorkloadActualStart;\n            bdnEventsParser.WorkloadActualStop += OnWorkloadActualStop;\n\n            kernelEventsParser.PerfInfoCollectionStart += OnPmcIntervalChange;\n            kernelEventsParser.PerfInfoPMCSample += OnPmcEvent;\n\n            traceLogEventSource.Process();\n\n            var benchmarkedProcessData = processIdToData.Values.Single(x => x.HasBenchmarkEvents);\n\n            return benchmarkedProcessData.CalculateMetrics(profileSourceIdToInterval, counters);\n        }\n\n        private void OnOverheadActualStart(IterationEvent obj) => HandleIterationEvent(obj.ProcessID, obj.TimeStampRelativeMSec, IterationMode.Overhead, obj.TotalOperations);\n\n        private void OnOverheadActualStop(IterationEvent obj) => HandleIterationEvent(obj.ProcessID, obj.TimeStampRelativeMSec, IterationMode.Overhead, obj.TotalOperations);\n\n        private void OnWorkloadActualStart(IterationEvent obj) => HandleIterationEvent(obj.ProcessID, obj.TimeStampRelativeMSec, IterationMode.Workload, obj.TotalOperations);\n\n        private void OnWorkloadActualStop(IterationEvent obj) => HandleIterationEvent(obj.ProcessID, obj.TimeStampRelativeMSec, IterationMode.Workload, obj.TotalOperations);\n\n        private void HandleIterationEvent(int processId, double timeStampRelative, IterationMode iterationMode, long totalOperations)\n        {\n            // if given process emits Benchmarking events it's the process that we care about\n            if (!processIdToData.ContainsKey(processId))\n                processIdToData.Add(processId, new ProcessMetrics());\n\n            processIdToData[processId].HandleIterationEvent(timeStampRelative, iterationMode, totalOperations);\n        }\n\n        private void OnPmcIntervalChange(SampledProfileIntervalTraceData data)\n        {\n            if (profileSourceIdToInterval.TryGetValue(data.SampleSource, out int storedInterval) && storedInterval != data.NewInterval)\n                throw new NotSupportedException(\"Sampling interval change is not supported!\");\n\n            profileSourceIdToInterval[data.SampleSource] = data.NewInterval;\n        }\n\n        private void OnPmcEvent(PMCCounterProfTraceData data)\n        {\n            // if given process did not emit Benchmarking events before, we don't care about it\n            if (!processIdToData.ContainsKey(data.ProcessID))\n                return;\n\n            processIdToData[data.ProcessID].HandleNewSample(data.TimeStampRelativeMSec, data.InstructionPointer, data.ProfileSource);\n        }\n    }\n\n    public class ProcessMetrics\n    {\n        private readonly List<double> overheadTimestamps = new List<double>(20);\n        private readonly List<double> workloadTimestamps = new List<double>(20);\n        private long? totalOperationsPerIteration;\n\n        private readonly List<(double timeStamp, ulong instructionPointer, int profileSource)> samples = [];\n\n        public bool HasBenchmarkEvents => overheadTimestamps.Any() || workloadTimestamps.Any();\n\n        public void HandleIterationEvent(double timeStamp, IterationMode iterationMode, long totalOperations)\n        {\n            if (iterationMode == IterationMode.Overhead)\n            {\n                overheadTimestamps.Add(timeStamp);\n            }\n            else if (iterationMode == IterationMode.Workload)\n            {\n                if (!totalOperationsPerIteration.HasValue)\n                    totalOperationsPerIteration = totalOperations;\n                else if (totalOperationsPerIteration.Value != totalOperations)\n                    throw new InvalidOperationException($\"TotalOperations count can't change during the benchmark run! Invalid trace!\");\n\n                workloadTimestamps.Add(timeStamp);\n            }\n        }\n\n        public void HandleNewSample(double timeStamp, ulong instructionPointer, int profileSourceId)\n            => samples.Add((timeStamp, instructionPointer, profileSourceId));\n\n        public IEnumerable<Metric> CalculateMetrics(Dictionary<int, int> profileSourceIdToInterval, PreciseMachineCounter[] counters)\n        {\n            if (overheadTimestamps.Count % 2 != 0)\n                throw new InvalidOperationException(\"One overhead iteration stop event is missing, unable to calculate stats\");\n            if (workloadTimestamps.Count % 2 != 0)\n                throw new InvalidOperationException(\"One workload iteration stop event is missing, unable to calculate stats\");\n            if (!totalOperationsPerIteration.HasValue)\n                throw new InvalidOperationException(\"TotalOperations is missing, unable to calculate stats\");\n\n            var overheadIterations = CreateIterationData(overheadTimestamps);\n            var workloadIterations = CreateIterationData(workloadTimestamps);\n\n            SumCountersPerIterations(profileSourceIdToInterval, workloadIterations, overheadIterations, counters);\n\n            var workloadTotalPerCounter = Sum(workloadIterations);\n            var overheadTotalPerCounter = Sum(overheadIterations);\n\n            return workloadTotalPerCounter.Select(perCounter =>\n            {\n                var pmc = counters.Single(counter => counter.ProfileSourceId == perCounter.Key);\n\n                overheadTotalPerCounter.TryGetValue(perCounter.Key, out var overhead);\n\n                // result = (avg(workload) - avg(overhead))/op\n                double result = perCounter.Value / (double)workloadIterations.Length;\n\n                if (overheadIterations.Length > 0) // we skip the overhead phase for long-running benchmarks\n                {\n                    result -= (overhead / (double)overheadIterations.Length);\n                }\n\n                result /= totalOperationsPerIteration.Value;\n\n                return new Metric(new PmcMetricDescriptor(pmc), result);\n            });\n        }\n\n        private IterationData[] CreateIterationData(List<double> startStopTimeStamps)\n        {\n            // collection contains mixed .Start and .Stop intervals, if we sort it we know that n is Start and n + 1 is Stop\n            startStopTimeStamps.Sort();\n\n            var iterations = new IterationData[startStopTimeStamps.Count / 2];\n            for (int i = 0; i < iterations.Length; i++)\n            {\n                iterations[i] = new IterationData(startStopTimeStamps[i * 2], startStopTimeStamps[(i * 2) + 1]);\n            }\n\n            return iterations;\n        }\n\n        private void SumCountersPerIterations(Dictionary<int, int> profileSourceIdToInterval, IterationData[] workloadIterations, IterationData[] overheadIterations,\n            PreciseMachineCounter[] counters)\n        {\n            var profileSourceIdToCounter = counters.ToDictionary(counter => counter.ProfileSourceId);\n\n            foreach (var sample in samples)\n            {\n                var interval = profileSourceIdToInterval[sample.profileSource];\n\n                foreach (var workloadIteration in workloadIterations)\n                    if (workloadIteration.TryHandle(sample.timeStamp, sample.profileSource, interval))\n                    {\n                        profileSourceIdToCounter[sample.profileSource].OnSample(sample.instructionPointer);\n\n                        goto next;\n                    }\n\n                foreach (var overheadIteration in overheadIterations)\n                    if (overheadIteration.TryHandle(sample.timeStamp, sample.profileSource, interval))\n                        goto next;\n\n                next:\n                    continue;\n            }\n        }\n\n        private static Dictionary<int, ulong> Sum(IterationData[] iterations)\n        {\n            var totalPerCounter = new Dictionary<int, ulong>();\n\n            foreach (var iteration in iterations)\n            {\n                foreach (var idToCount in iteration.ProfileSourceIdToCount)\n                {\n                    checked\n                    {\n                        totalPerCounter.TryGetValue(idToCount.Key, out ulong existing);\n                        totalPerCounter[idToCount.Key] = existing + idToCount.Value;\n                    }\n                }\n            }\n\n            return totalPerCounter;\n        }\n    }\n\n    public class IterationData\n    {\n        public Dictionary<int, ulong> ProfileSourceIdToCount { get; }\n        private double StartTimestamp { get; }\n        private double StopTimestamp { get; }\n\n        public IterationData(double startTimestamp, double stopTimestamp)\n        {\n            StartTimestamp = startTimestamp;\n            StopTimestamp = stopTimestamp;\n            ProfileSourceIdToCount = [];\n        }\n\n        public bool TryHandle(double timeStamp, int profileSource, int interval)\n        {\n            if (!(StartTimestamp <= timeStamp && timeStamp <= StopTimestamp))\n                return false;\n\n            checked\n            {\n                ProfileSourceIdToCount.TryGetValue(profileSource, out ulong existing);\n                ProfileSourceIdToCount[profileSource] = existing + (ulong)interval;\n            }\n\n            return true;\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet.Diagnostics.dotMemory/BenchmarkDotNet.Diagnostics.dotMemory.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n    <Import Project=\"..\\..\\build\\common.props\" />\n    <PropertyGroup>\n        <TargetFrameworks>net8.0;net6.0;net462;netcoreapp3.1</TargetFrameworks>\n        <NoWarn>$(NoWarn);1591</NoWarn>\n        <AssemblyTitle>BenchmarkDotNet.Diagnostics.dotMemory</AssemblyTitle>\n        <AssemblyName>BenchmarkDotNet.Diagnostics.dotMemory</AssemblyName>\n        <PackageId>BenchmarkDotNet.Diagnostics.dotMemory</PackageId>\n    </PropertyGroup>\n\n    <ItemGroup>\n        <ProjectReference Include=\"..\\BenchmarkDotNet\\BenchmarkDotNet.csproj\" />\n    </ItemGroup>\n    \n    <ItemGroup>\n        <PackageReference Include=\"JetBrains.Profiler.SelfApi\" Version=\"2.5.16\" />\n    </ItemGroup>\n\n    <Import Project=\"..\\..\\build\\common.targets\" />\n</Project>\n"
  },
  {
    "path": "src/BenchmarkDotNet.Diagnostics.dotMemory/DotMemoryDiagnoser.cs",
    "content": "using System;\nusing System.Reflection;\nusing BenchmarkDotNet.Detectors;\nusing BenchmarkDotNet.Diagnosers;\nusing BenchmarkDotNet.Helpers;\nusing BenchmarkDotNet.Jobs;\nusing JetBrains.Profiler.SelfApi;\n\nnamespace BenchmarkDotNet.Diagnostics.dotMemory;\n\npublic class DotMemoryDiagnoser(Uri? nugetUrl = null, string? downloadTo = null) : SnapshotProfilerBase\n{\n    public override string ShortName => \"dotMemory\";\n\n    protected override void InitTool(Progress progress)\n    {\n        DotMemory.InitAsync(progress, nugetUrl, NuGetApi.V3, downloadTo).GetAwaiter().GetResult();\n    }\n\n    protected override void AttachToCurrentProcess(string snapshotFile)\n    {\n        DotMemory.Attach(new DotMemory.Config().SaveToFile(snapshotFile));\n    }\n\n    protected override void AttachToProcessByPid(int pid, string snapshotFile)\n    {\n        var config = new DotMemory.Config()\n            .UseCustomResponseTimeout(milliseconds:60 * 1000)\n            .ProfileExternalProcess(pid)\n            .SaveToFile(snapshotFile);\n        DotMemory.Attach(config);\n    }\n\n    protected override void TakeSnapshot()\n    {\n        DotMemory.GetSnapshot();\n    }\n\n    protected override void Detach()\n    {\n        DotMemory.Detach();\n    }\n\n    protected override string CreateSnapshotFilePath(DiagnoserActionParameters parameters)\n    {\n        return ArtifactFileNameHelper.GetFilePath(parameters, \"snapshots\", DateTime.Now, \"dmw\", \".0000\".Length);\n    }\n\n    protected override string GetRunnerPath()\n    {\n        var consoleRunnerPackageField = typeof(DotMemory).GetField(\"ConsoleRunnerPackage\", BindingFlags.NonPublic | BindingFlags.Static);\n        if (consoleRunnerPackageField == null)\n            throw new InvalidOperationException(\"Field 'ConsoleRunnerPackage' not found.\");\n\n        object? consoleRunnerPackage = consoleRunnerPackageField.GetValue(null);\n        if (consoleRunnerPackage == null)\n            throw new InvalidOperationException(\"Unable to get value of 'ConsoleRunnerPackage'.\");\n\n        var consoleRunnerPackageType = consoleRunnerPackage.GetType();\n        var getRunnerPathMethod = consoleRunnerPackageType.GetMethod(\"GetRunnerPath\");\n        if (getRunnerPathMethod == null)\n            throw new InvalidOperationException(\"Method 'GetRunnerPath' not found.\");\n\n        string? runnerPath = getRunnerPathMethod.Invoke(consoleRunnerPackage, null) as string;\n        if (runnerPath == null)\n            throw new InvalidOperationException(\"Unable to invoke 'GetRunnerPath'.\");\n\n        return runnerPath;\n    }\n\n    internal override bool IsSupported(RuntimeMoniker runtimeMoniker)\n    {\n        switch (runtimeMoniker)\n        {\n            case RuntimeMoniker.HostProcess:\n            case RuntimeMoniker.Net461:\n            case RuntimeMoniker.Net462:\n            case RuntimeMoniker.Net47:\n            case RuntimeMoniker.Net471:\n            case RuntimeMoniker.Net472:\n            case RuntimeMoniker.Net48:\n            case RuntimeMoniker.Net481:\n            case RuntimeMoniker.Net50:\n            case RuntimeMoniker.Net60:\n            case RuntimeMoniker.Net70:\n            case RuntimeMoniker.Net80:\n            case RuntimeMoniker.Net90:\n            case RuntimeMoniker.Net10_0:\n            case RuntimeMoniker.Net11_0:\n            case RuntimeMoniker.R2R80:\n            case RuntimeMoniker.R2R90:\n            case RuntimeMoniker.R2R10_0:\n            case RuntimeMoniker.R2R11_0:\n                return true;\n            case RuntimeMoniker.NotRecognized:\n            case RuntimeMoniker.Mono:\n            case RuntimeMoniker.NativeAot60:\n            case RuntimeMoniker.NativeAot70:\n            case RuntimeMoniker.NativeAot80:\n            case RuntimeMoniker.NativeAot90:\n            case RuntimeMoniker.NativeAot10_0:\n            case RuntimeMoniker.NativeAot11_0:\n            case RuntimeMoniker.WasmNet80:\n            case RuntimeMoniker.WasmNet90:\n            case RuntimeMoniker.WasmNet10_0:\n            case RuntimeMoniker.WasmNet11_0:\n            case RuntimeMoniker.MonoAOTLLVM:\n            case RuntimeMoniker.MonoAOTLLVMNet60:\n            case RuntimeMoniker.MonoAOTLLVMNet70:\n            case RuntimeMoniker.MonoAOTLLVMNet80:\n            case RuntimeMoniker.MonoAOTLLVMNet90:\n            case RuntimeMoniker.MonoAOTLLVMNet10_0:\n            case RuntimeMoniker.MonoAOTLLVMNet11_0:\n            case RuntimeMoniker.Mono60:\n            case RuntimeMoniker.Mono70:\n            case RuntimeMoniker.Mono80:\n                return false;\n            case RuntimeMoniker.NetCoreApp20:\n            case RuntimeMoniker.NetCoreApp21:\n            case RuntimeMoniker.NetCoreApp22:\n                return OsDetector.IsWindows();\n            case RuntimeMoniker.NetCoreApp30:\n            case RuntimeMoniker.NetCoreApp31:\n                return OsDetector.IsWindows() || OsDetector.IsLinux();\n            default:\n                throw new ArgumentOutOfRangeException(nameof(runtimeMoniker), runtimeMoniker, $\"Runtime moniker {runtimeMoniker} is not supported\");\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet.Diagnostics.dotMemory/DotMemoryDiagnoserAttribute.cs",
    "content": "using System;\nusing BenchmarkDotNet.Configs;\n\nnamespace BenchmarkDotNet.Diagnostics.dotMemory;\n\n[AttributeUsage(AttributeTargets.Class)]\npublic class DotMemoryDiagnoserAttribute : Attribute, IConfigSource\n{\n    public IConfig Config { get; }\n\n    public DotMemoryDiagnoserAttribute()\n    {\n        var diagnoser = new DotMemoryDiagnoser();\n        Config = ManualConfig.CreateEmpty().AddDiagnoser(diagnoser);\n    }\n\n    public DotMemoryDiagnoserAttribute(Uri? nugetUrl, string? downloadTo = null)\n    {\n        var diagnoser = new DotMemoryDiagnoser(nugetUrl, downloadTo);\n        Config = ManualConfig.CreateEmpty().AddDiagnoser(diagnoser);\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet.Diagnostics.dotMemory/Properties/AssemblyInfo.cs",
    "content": "﻿using System;\nusing System.Runtime.CompilerServices;\nusing BenchmarkDotNet.Properties;\n\n[assembly: CLSCompliant(true)]\n\n[assembly: InternalsVisibleTo(\"BenchmarkDotNet.Tests,PublicKey=\" + BenchmarkDotNetInfo.PublicKey)]\n"
  },
  {
    "path": "src/BenchmarkDotNet.Diagnostics.dotTrace/BenchmarkDotNet.Diagnostics.dotTrace.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n    <Import Project=\"..\\..\\build\\common.props\" />\n    <PropertyGroup>\n        <TargetFrameworks>net8.0;net6.0;net462;netcoreapp3.1</TargetFrameworks>\n        <NoWarn>$(NoWarn);1591</NoWarn>\n        <AssemblyTitle>BenchmarkDotNet.Diagnostics.dotTrace</AssemblyTitle>\n        <AssemblyName>BenchmarkDotNet.Diagnostics.dotTrace</AssemblyName>\n        <PackageId>BenchmarkDotNet.Diagnostics.dotTrace</PackageId>\n    </PropertyGroup>\n\n    <ItemGroup>\n        <ProjectReference Include=\"..\\BenchmarkDotNet\\BenchmarkDotNet.csproj\" />\n    </ItemGroup>\n    \n    <ItemGroup>\n        <PackageReference Include=\"JetBrains.Profiler.SelfApi\" Version=\"2.5.16\" />\n    </ItemGroup>\n\n    <Import Project=\"..\\..\\build\\common.targets\" />\n</Project>\n"
  },
  {
    "path": "src/BenchmarkDotNet.Diagnostics.dotTrace/DotTraceDiagnoser.cs",
    "content": "using System;\nusing System.Reflection;\nusing BenchmarkDotNet.Detectors;\nusing BenchmarkDotNet.Diagnosers;\nusing BenchmarkDotNet.Helpers;\nusing BenchmarkDotNet.Jobs;\nusing JetBrains.Profiler.SelfApi;\n\nnamespace BenchmarkDotNet.Diagnostics.dotTrace;\n\npublic class DotTraceDiagnoser(Uri? nugetUrl = null, string? downloadTo = null) : SnapshotProfilerBase\n{\n    public override string ShortName => \"dotTrace\";\n\n    protected override void InitTool(Progress progress)\n    {\n        DotTrace.InitAsync(progress, nugetUrl, NuGetApi.V3, downloadTo).GetAwaiter().GetResult();\n    }\n\n    protected override void AttachToCurrentProcess(string snapshotFile)\n    {\n        DotTrace.Attach(new DotTrace.Config().SaveToFile(snapshotFile));\n        DotTrace.StartCollectingData();\n    }\n\n    protected override void AttachToProcessByPid(int pid, string snapshotFile)\n    {\n        var config = new DotTrace.Config()\n            .UseCustomResponseTimeout(milliseconds: 60 * 1000)\n            .ProfileExternalProcess(pid)\n            .SaveToFile(snapshotFile);\n        DotTrace.Attach(config);\n        DotTrace.StartCollectingData();\n    }\n\n    protected override void TakeSnapshot()\n    {\n        DotTrace.StopCollectingData();\n        DotTrace.SaveData();\n    }\n\n    protected override void Detach()\n    {\n        DotTrace.Detach();\n    }\n\n    protected override string CreateSnapshotFilePath(DiagnoserActionParameters parameters)\n    {\n        return ArtifactFileNameHelper.GetFilePath(parameters, \"snapshots\", DateTime.Now, \"dtp\", \".0000\".Length);\n    }\n\n    protected override string GetRunnerPath()\n    {\n        var consoleRunnerPackageField = typeof(DotTrace).GetField(\"ConsoleRunnerPackage\", BindingFlags.NonPublic | BindingFlags.Static);\n        if (consoleRunnerPackageField == null)\n            throw new InvalidOperationException(\"Field 'ConsoleRunnerPackage' not found.\");\n\n        object? consoleRunnerPackage = consoleRunnerPackageField.GetValue(null);\n        if (consoleRunnerPackage == null)\n            throw new InvalidOperationException(\"Unable to get value of 'ConsoleRunnerPackage'.\");\n\n        var consoleRunnerPackageType = consoleRunnerPackage.GetType();\n        var getRunnerPathMethod = consoleRunnerPackageType.GetMethod(\"GetRunnerPath\");\n        if (getRunnerPathMethod == null)\n            throw new InvalidOperationException(\"Method 'GetRunnerPath' not found.\");\n\n        string? runnerPath = getRunnerPathMethod.Invoke(consoleRunnerPackage, null) as string;\n        if (runnerPath == null)\n            throw new InvalidOperationException(\"Unable to invoke 'GetRunnerPath'.\");\n\n        return runnerPath;\n    }\n\n    internal override bool IsSupported(RuntimeMoniker runtimeMoniker)\n    {\n        switch (runtimeMoniker)\n        {\n            case RuntimeMoniker.HostProcess:\n            case RuntimeMoniker.Net461:\n            case RuntimeMoniker.Net462:\n            case RuntimeMoniker.Net47:\n            case RuntimeMoniker.Net471:\n            case RuntimeMoniker.Net472:\n            case RuntimeMoniker.Net48:\n            case RuntimeMoniker.Net481:\n            case RuntimeMoniker.Net50:\n            case RuntimeMoniker.Net60:\n            case RuntimeMoniker.Net70:\n            case RuntimeMoniker.Net80:\n            case RuntimeMoniker.Net90:\n            case RuntimeMoniker.Net10_0:\n            case RuntimeMoniker.Net11_0:\n            case RuntimeMoniker.R2R80:\n            case RuntimeMoniker.R2R90:\n            case RuntimeMoniker.R2R10_0:\n            case RuntimeMoniker.R2R11_0:\n                return true;\n            case RuntimeMoniker.NotRecognized:\n            case RuntimeMoniker.Mono:\n            case RuntimeMoniker.NativeAot60:\n            case RuntimeMoniker.NativeAot70:\n            case RuntimeMoniker.NativeAot80:\n            case RuntimeMoniker.NativeAot90:\n            case RuntimeMoniker.NativeAot10_0:\n            case RuntimeMoniker.NativeAot11_0:\n            case RuntimeMoniker.WasmNet80:\n            case RuntimeMoniker.WasmNet90:\n            case RuntimeMoniker.WasmNet10_0:\n            case RuntimeMoniker.WasmNet11_0:\n            case RuntimeMoniker.MonoAOTLLVM:\n            case RuntimeMoniker.MonoAOTLLVMNet60:\n            case RuntimeMoniker.MonoAOTLLVMNet70:\n            case RuntimeMoniker.MonoAOTLLVMNet80:\n            case RuntimeMoniker.MonoAOTLLVMNet90:\n            case RuntimeMoniker.MonoAOTLLVMNet10_0:\n            case RuntimeMoniker.MonoAOTLLVMNet11_0:\n            case RuntimeMoniker.Mono60:\n            case RuntimeMoniker.Mono70:\n            case RuntimeMoniker.Mono80:\n                return false;\n            case RuntimeMoniker.NetCoreApp20:\n            case RuntimeMoniker.NetCoreApp21:\n            case RuntimeMoniker.NetCoreApp22:\n                return OsDetector.IsWindows();\n            case RuntimeMoniker.NetCoreApp30:\n            case RuntimeMoniker.NetCoreApp31:\n                return OsDetector.IsWindows() || OsDetector.IsLinux();\n            default:\n                throw new ArgumentOutOfRangeException(nameof(runtimeMoniker), runtimeMoniker, $\"Runtime moniker {runtimeMoniker} is not supported\");\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet.Diagnostics.dotTrace/DotTraceDiagnoserAttribute.cs",
    "content": "using System;\nusing BenchmarkDotNet.Configs;\n\nnamespace BenchmarkDotNet.Diagnostics.dotTrace;\n\n[AttributeUsage(AttributeTargets.Class)]\npublic class DotTraceDiagnoserAttribute : Attribute, IConfigSource\n{\n    public IConfig Config { get; }\n\n    public DotTraceDiagnoserAttribute()\n    {\n        var diagnoser = new DotTraceDiagnoser();\n        Config = ManualConfig.CreateEmpty().AddDiagnoser(diagnoser);\n    }\n\n    public DotTraceDiagnoserAttribute(Uri? nugetUrl, string? downloadTo = null)\n    {\n        var diagnoser = new DotTraceDiagnoser(nugetUrl, downloadTo);\n        Config = ManualConfig.CreateEmpty().AddDiagnoser(diagnoser);\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet.Diagnostics.dotTrace/Properties/AssemblyInfo.cs",
    "content": "﻿using System;\nusing System.Runtime.CompilerServices;\nusing BenchmarkDotNet.Properties;\n\n[assembly: CLSCompliant(true)]\n\n[assembly: InternalsVisibleTo(\"BenchmarkDotNet.Tests,PublicKey=\" + BenchmarkDotNetInfo.PublicKey)]\n"
  },
  {
    "path": "src/BenchmarkDotNet.Disassembler/BenchmarkDotNet.Disassembler.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\n  <Import Project=\"..\\..\\build\\common.props\" />\n  <PropertyGroup>\n    <TargetFrameworks>net462;net8.0</TargetFrameworks>\n    <OutputType>Exe</OutputType>\n    <AssemblyTitle>BenchmarkDotNet.Disassembler</AssemblyTitle>\n    <AssemblyName>BenchmarkDotNet.Disassembler</AssemblyName>\n    <PlatformTarget>x64</PlatformTarget>\n    <!-- This project is only used for debugging the disassembler, it's not included in any BenchmarkDotNet packages. -->\n    <IsPackable>false</IsPackable>\n  </PropertyGroup>\n  <PropertyGroup>\n    <RootNamespace>BenchmarkDotNet.Disassembler</RootNamespace>\n  </PropertyGroup>\n  <ItemGroup>\n    <ProjectReference Include=\"..\\BenchmarkDotNet\\BenchmarkDotNet.csproj\" />\n  </ItemGroup>\n  <Import Project=\"..\\..\\build\\common.targets\" />\n</Project>\n"
  },
  {
    "path": "src/BenchmarkDotNet.Disassembler/Program.cs",
    "content": "﻿using BenchmarkDotNet.Diagnosers;\nusing System;\nusing System.Diagnostics;\nusing System.IO;\nusing System.Xml;\nusing System.Xml.Serialization;\n\nnamespace BenchmarkDotNet.Disassemblers\n{\n    internal static class Program\n    {\n        // the goals of the existence of this process:\n        // 1. attach to benchmarked process\n        // 2. disassemble the code\n        // 3. save it to xml file\n        // 4. detach & shut down\n        public static void Main(string[] args)\n        {\n            var options = ClrMdArgs.FromArgs(args);\n\n            if (Process.GetProcessById(options.ProcessId).HasExited) // possible when benchmark has already finished\n                throw new Exception($\"The process {options.ProcessId} has already exited\"); // if we don't throw here the Clrmd will fail with some mysterious HRESULT: 0xd000010a ;)\n\n            try\n            {\n                var methodsToExport = DisassemblyDiagnoser.GetClrMdDisassembler().AttachAndDisassemble(options);\n\n                SaveToFile(methodsToExport, options.ResultsPath);\n            }\n            catch (OutOfMemoryException) // thrown by clrmd when pdb is missing or in invalid format\n            {\n                Console.WriteLine(\"\\\\ ---------------------------\");\n                Console.WriteLine(\"Failed to read source code location!\");\n                Console.WriteLine(\"Please make sure that the project, which defines benchmarks contains following settings:\");\n                Console.WriteLine(\"\\t <DebugType>pdbonly</DebugType>\");\n                Console.WriteLine(\"\\t <DebugSymbols>true</DebugSymbols>\");\n                Console.WriteLine(\"\\\\ ---------------------------\");\n            }\n            catch (Exception ex)\n            {\n                Console.WriteLine(\"Failed to disassemble with following exception:\");\n                Console.WriteLine(ex.Message);\n                Console.WriteLine(ex.StackTrace);\n            }\n        }\n\n        private static void SaveToFile(DisassemblyResult disassemblyResult, string filePath)\n        {\n            using (var stream = new FileStream(filePath, FileMode.Append, FileAccess.Write))\n            using (var writer = XmlWriter.Create(stream))\n            {\n                var serializer = new XmlSerializer(typeof(DisassemblyResult));\n\n                serializer.Serialize(writer, disassemblyResult);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet.Exporters.Plotting/BenchmarkDotNet.Exporters.Plotting.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\n  <Import Project=\"..\\..\\build\\common.props\" />\n  <PropertyGroup>\n    <AssemblyTitle>BenchmarkDotNet plotting export support.</AssemblyTitle>\n    <TargetFrameworks>netstandard2.0</TargetFrameworks>\n    <AssemblyName>BenchmarkDotNet.Exporters.Plotting</AssemblyName>\n    <PackageId>BenchmarkDotNet.Exporters.Plotting</PackageId>\n    <RootNamespace>BenchmarkDotNet.Exporters.Plotting</RootNamespace>\n    <!-- needed for docfx xref resolver -->\n    <ProduceReferenceAssembly>True</ProduceReferenceAssembly>\n  </PropertyGroup>\n  <ItemGroup>\n    <ProjectReference Include=\"..\\BenchmarkDotNet\\BenchmarkDotNet.csproj\" />\n  </ItemGroup>\n  <ItemGroup>\n    <PackageReference Include=\"ScottPlot\" Version=\"5.0.55\" />\n  </ItemGroup>\n  <Import Project=\"..\\..\\build\\common.targets\" />\n</Project>\n"
  },
  {
    "path": "src/BenchmarkDotNet.Exporters.Plotting/ScottPlotExporter.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Properties;\nusing BenchmarkDotNet.Reports;\nusing ScottPlot;\nusing ScottPlot.Plottables;\n\nnamespace BenchmarkDotNet.Exporters.Plotting\n{\n    /// <summary>\n    /// Provides plot exports as .png files.\n    /// </summary>\n    public class ScottPlotExporter : IExporter\n    {\n        /// <summary>\n        /// Default instance of the exporter with default configuration.\n        /// </summary>\n        public static readonly IExporter Default = new ScottPlotExporter();\n\n        /// <summary>\n        /// Gets the name of the Exporter type.\n        /// </summary>\n        public string Name => nameof(ScottPlotExporter);\n\n        /// <summary>\n        /// Initializes a new instance of ScottPlotExporter.\n        /// </summary>\n        /// <param name=\"width\">The width of all plots in pixels (optional). Defaults to 1920.</param>\n        /// <param name=\"height\">The height of all plots in pixels (optional). Defaults to 1080.</param>\n        public ScottPlotExporter(int width = 1920, int height = 1080)\n        {\n            this.Width = width;\n            this.Height = height;\n            this.IncludeBarPlot = true;\n            this.IncludeBoxPlot = true;\n            this.RotateLabels = true;\n        }\n\n        /// <summary>\n        /// Gets or sets the width of all plots in pixels.\n        /// </summary>\n        public int Width { get; set; }\n\n        /// <summary>\n        /// Gets or sets the height of all plots in pixels.\n        /// </summary>\n        public int Height { get; set; }\n\n        /// <summary>\n        /// Gets or sets the common font size for ticks, labels etc. (defaults to 14).\n        /// </summary>\n        public int FontSize { get; set; } = 14;\n\n        /// <summary>\n        /// Gets or sets the font size for the chart title. (defaults to 28).\n        /// </summary>\n        public int TitleFontSize { get; set; } = 28;\n\n        /// <summary>\n        /// Gets or sets a value indicating whether labels for Plot X-axis should be rotated.\n        /// This allows for longer labels at the expense of chart height.\n        /// </summary>\n        public bool RotateLabels { get; set; }\n\n        /// <summary>\n        /// Gets or sets a value indicating whether a bar plot for time-per-op\n        /// measurement values should be exported.\n        /// </summary>\n        public bool IncludeBarPlot { get; set; }\n\n        /// <summary>\n        /// Gets or sets a value indicating whether a box plot or whisker plot for time-per-op\n        /// measurement values should be exported.\n        /// </summary>\n        public bool IncludeBoxPlot { get; set; }\n\n        /// <summary>\n        /// Not supported.\n        /// </summary>\n        /// <param name=\"summary\">This parameter is not used.</param>\n        /// <param name=\"logger\">This parameter is not used.</param>\n        /// <exception cref=\"NotSupportedException\"></exception>\n        public void ExportToLog(Summary summary, ILogger logger)\n        {\n            throw new NotSupportedException();\n        }\n\n        /// <summary>\n        /// Exports plots to .png file.\n        /// </summary>\n        /// <param name=\"summary\">The summary to be exported.</param>\n        /// <param name=\"consoleLogger\">Logger to output to.</param>\n        /// <returns>The file paths of every plot exported.</returns>\n        public IEnumerable<string> ExportToFiles(Summary summary, ILogger consoleLogger)\n        {\n            var title = summary.Title;\n            var version = BenchmarkDotNetInfo.Instance.BrandTitle;\n            var annotations = GetAnnotations(version);\n\n            var (timeUnit, timeScale) = GetTimeUnit(summary.Reports\n                .SelectMany(m => m.AllMeasurements.Where(m => m.Is(IterationMode.Workload, IterationStage.Result))));\n\n            foreach (var benchmark in summary.Reports.GroupBy(r => r.BenchmarkCase.Descriptor.Type.Name))\n            {\n                var benchmarkName = benchmark.Key;\n\n                // Get the measurement nanoseconds per op, divided by time scale, grouped by target and Job [param].\n                var timeStats = from report in benchmark\n                                let jobId = report.BenchmarkCase.DisplayInfo.Replace(report.BenchmarkCase.Descriptor.DisplayInfo + \": \", string.Empty)\n                                from measurement in report.AllMeasurements\n                                where measurement.Is(IterationMode.Workload, IterationStage.Result)\n                                let measurementValue = measurement.Nanoseconds / measurement.Operations\n                                group measurementValue / timeScale by (Target: report.BenchmarkCase.Descriptor.WorkloadMethodDisplayInfo, JobId: jobId) into g\n                                select new ChartStats(g.Key.Target, g.Key.JobId, g.ToList());\n\n                if (this.IncludeBarPlot)\n                {\n                    // <BenchmarkName>-barplot.png\n                    yield return CreateBarPlot(\n                        $\"{title} - {benchmarkName}\",\n                        Path.Combine(summary.ResultsDirectoryPath, $\"{title}-{benchmarkName}-barplot.png\"),\n                        $\"Time ({timeUnit})\",\n                        \"Target\",\n                        timeStats,\n                        annotations);\n                }\n\n                if (this.IncludeBoxPlot)\n                {\n                    // <BenchmarkName>-boxplot.png\n                    yield return CreateBoxPlot(\n                        $\"{title} - {benchmarkName}\",\n                        Path.Combine(summary.ResultsDirectoryPath, $\"{title}-{benchmarkName}-boxplot.png\"),\n                        $\"Time ({timeUnit})\",\n                        \"Target\",\n                        timeStats,\n                        annotations);\n                }\n\n                /* TODO: Rest of the RPlotExporter plots.\n                <BenchmarkName>-<MethodName>-density.png\n                <BenchmarkName>-<MethodName>-facetTimeline.png\n                <BenchmarkName>-<MethodName>-facetTimelineSmooth.png\n                <BenchmarkName>-<MethodName>-<JobName>-timelineSmooth.png\n                <BenchmarkName>-<MethodName>-<JobName>-timelineSmooth.png*/\n            }\n        }\n\n        /// <summary>\n        /// Calculate Standard Deviation.\n        /// </summary>\n        /// <param name=\"values\">Values to calculate from.</param>\n        /// <returns>Standard deviation of values.</returns>\n        private static double StandardError(IReadOnlyList<double> values)\n        {\n            double average = values.Average();\n            double sumOfSquaresOfDifferences = values.Select(val => (val - average) * (val - average)).Sum();\n            double standardDeviation = Math.Sqrt(sumOfSquaresOfDifferences / values.Count);\n            return standardDeviation / Math.Sqrt(values.Count);\n        }\n\n        /// <summary>\n        /// Gets the lowest appropriate time scale across all measurements.\n        /// </summary>\n        /// <param name=\"values\">All measurements</param>\n        /// <returns>A unit and scaling factor to convert from nanoseconds.</returns>\n        private (string Unit, double ScaleFactor) GetTimeUnit(IEnumerable<Measurement> values)\n        {\n            var minValue = values.Select(m => m.Nanoseconds / m.Operations).DefaultIfEmpty(0d).Min();\n            if (minValue > 1000000000d)\n            {\n                return (\"sec\", 1000000000d);\n            }\n\n            if (minValue > 1000000d)\n            {\n                return (\"ms\", 1000000d);\n            }\n\n            if (minValue > 1000d)\n            {\n                return (\"us\", 1000d);\n            }\n\n            return (\"ns\", 1d);\n        }\n\n        private string CreateBarPlot(string title, string fileName, string yLabel, string xLabel, IEnumerable<ChartStats> data, IReadOnlyList<Annotation> annotations)\n        {\n            Plot plt = new Plot();\n            plt.Title(title, this.TitleFontSize);\n            plt.YLabel(yLabel, this.FontSize);\n            plt.XLabel(xLabel, this.FontSize);\n\n            var palette = new ScottPlot.Palettes.Category10();\n\n            var legendPalette = data.Select(d => d.JobId)\n                .Distinct()\n                .Select((jobId, index) => (jobId, index))\n                .ToDictionary(t => t.jobId, t => palette.GetColor(t.index));\n\n            plt.Legend.IsVisible = true;\n            plt.Legend.Alignment = Alignment.UpperRight;\n            plt.Legend.FontSize = this.FontSize;\n            var legend = data.Select(d => d.JobId)\n                .Distinct()\n                .Select((label, index) => new LegendItem()\n                {\n                    LabelText = label,\n                    FillColor = legendPalette[label]\n                })\n                .ToList();\n\n            plt.Legend.ManualItems.AddRange(legend);\n\n            var jobCount = plt.Legend.ManualItems.Count;\n            var ticks = data\n                .Select((d, index) => new Tick(index, d.Target))\n                .ToArray();\n\n            plt.Axes.Left.TickLabelStyle.FontSize = this.FontSize;\n            plt.Axes.Bottom.TickGenerator = new ScottPlot.TickGenerators.NumericManual(ticks);\n            plt.Axes.Bottom.MajorTickStyle.Length = 0;\n            plt.Axes.Bottom.TickLabelStyle.FontSize = this.FontSize;\n\n            if (this.RotateLabels)\n            {\n                plt.Axes.Bottom.TickLabelStyle.Rotation = 45;\n                plt.Axes.Bottom.TickLabelStyle.Alignment = Alignment.MiddleLeft;\n\n                // determine the width of the largest tick label\n                float largestLabelWidth = 0;\n                foreach (Tick tick in ticks)\n                {\n                    PixelSize size = plt.Axes.Bottom.TickLabelStyle.Measure(tick.Label).Size;\n                    largestLabelWidth = Math.Max(largestLabelWidth, size.Width);\n                }\n\n                // ensure axis panels do not get smaller than the largest label\n                plt.Axes.Bottom.MinimumSize = largestLabelWidth * 2;\n                plt.Axes.Right.MinimumSize = largestLabelWidth;\n            }\n\n            var bars = data\n                .Select((d, index) => new Bar()\n                {\n                    Position = ticks[index].Position,\n                    Value = d.Mean,\n                    Error = d.StdError,\n                    FillColor = legendPalette[d.JobId]\n                });\n            plt.Add.Bars(bars.ToList());\n\n            // Tell the plot to autoscale with no padding beneath the bars\n            plt.Axes.Margins(bottom: 0, right: .2);\n\n            plt.PlottableList.AddRange(annotations);\n\n            plt.SavePng(fileName, this.Width, this.Height);\n            return Path.GetFullPath(fileName);\n        }\n\n        private string CreateBoxPlot(string title, string fileName, string yLabel, string xLabel, IEnumerable<ChartStats> data, IReadOnlyList<Annotation> annotations)\n        {\n            Plot plt = new Plot();\n            plt.Title(title, this.TitleFontSize);\n            plt.YLabel(yLabel, this.FontSize);\n            plt.XLabel(xLabel, this.FontSize);\n\n            var palette = new ScottPlot.Palettes.Category10();\n\n            var legendPalette = data.Select(d => d.JobId)\n                .Distinct()\n                .Select((jobId, index) => (jobId, index))\n                .ToDictionary(t => t.jobId, t => palette.GetColor(t.index));\n\n            plt.Legend.IsVisible = true;\n            plt.Legend.Alignment = Alignment.UpperRight;\n            plt.Legend.FontSize = this.FontSize;\n            var legend = data.Select(d => d.JobId)\n                .Distinct()\n                .Select((label, index) => new LegendItem()\n                {\n                    LabelText = label,\n                    FillColor = legendPalette[label]\n                })\n                .ToList();\n\n            plt.Legend.ManualItems.AddRange(legend);\n\n            var jobCount = plt.Legend.ManualItems.Count;\n            var ticks = data\n                .Select((d, index) => new Tick(index, d.Target))\n                .ToArray();\n\n            plt.Axes.Left.TickLabelStyle.FontSize = this.FontSize;\n            plt.Axes.Bottom.TickGenerator = new ScottPlot.TickGenerators.NumericManual(ticks);\n            plt.Axes.Bottom.MajorTickStyle.Length = 0;\n            plt.Axes.Bottom.TickLabelStyle.FontSize = this.FontSize;\n\n            if (this.RotateLabels)\n            {\n                plt.Axes.Bottom.TickLabelStyle.Rotation = 45;\n                plt.Axes.Bottom.TickLabelStyle.Alignment = Alignment.MiddleLeft;\n\n                // determine the width of the largest tick label\n                float largestLabelWidth = 0;\n                foreach (Tick tick in ticks)\n                {\n                    PixelSize size = plt.Axes.Bottom.TickLabelStyle.Measure(tick.Label).Size;\n                    largestLabelWidth = Math.Max(largestLabelWidth, size.Width);\n                }\n\n                // ensure axis panels do not get smaller than the largest label\n                plt.Axes.Bottom.MinimumSize = largestLabelWidth * 2;\n                plt.Axes.Right.MinimumSize = largestLabelWidth;\n            }\n\n            int globalIndex = 0;\n            foreach (var (targetGroup, targetGroupIndex) in data.GroupBy(s => s.Target).Select((targetGroup, index) => (targetGroup, index)))\n            {\n                var boxes = targetGroup.Select(job => (job.JobId, Stats: job.CalculateBoxPlotStatistics())).Select((j, jobIndex) => new Box()\n                    {\n                        Position = ticks[globalIndex++].Position,\n                        FillStyle = new FillStyle() { Color = legendPalette[j.JobId] },\n                        LineStyle = new LineStyle() { Color = Colors.Black },\n                        BoxMin = j.Stats.Q1,\n                        BoxMax = j.Stats.Q3,\n                        WhiskerMin = j.Stats.Min,\n                        WhiskerMax = j.Stats.Max,\n                        BoxMiddle = j.Stats.Median\n                    })\n                    .ToList();\n                plt.Add.Boxes(boxes);\n            }\n\n            // Tell the plot to autoscale with a small padding below the boxes.\n            plt.Axes.Margins(bottom: 0.05, right: .2);\n\n            plt.PlottableList.AddRange(annotations);\n\n            plt.SavePng(fileName, this.Width, this.Height);\n            return Path.GetFullPath(fileName);\n        }\n\n        /// <summary>\n        /// Provides a list of annotations to put over the data area.\n        /// </summary>\n        /// <param name=\"version\">The version to be displayed.</param>\n        /// <returns>A list of annotations for every plot.</returns>\n        private IReadOnlyList<Annotation> GetAnnotations(string version)\n        {\n            var versionAnnotation = new Annotation()\n            {\n                LabelStyle =\n                {\n                    Text = version,\n                    FontSize = 14,\n                    ForeColor = new Color(0, 0, 0, 100)\n                },\n                OffsetY = 10,\n                OffsetX = 20,\n                Alignment = Alignment.LowerRight\n            };\n\n\n            return [versionAnnotation];\n        }\n\n        private class ChartStats\n        {\n            public ChartStats(string Target, string JobId, IReadOnlyList<double> Values)\n            {\n                this.Target = Target;\n                this.JobId = JobId;\n                this.Values = Values;\n            }\n\n            public string Target { get; }\n\n            public string JobId { get; }\n\n            public IReadOnlyList<double> Values { get; }\n\n            public double Min => this.Values.DefaultIfEmpty(0d).Min();\n\n            public double Max => this.Values.DefaultIfEmpty(0d).Max();\n\n            public double Mean => this.Values.DefaultIfEmpty(0d).Average();\n\n            public double StdError => StandardError(this.Values);\n\n\n            private static (int MidPoint, double Median) CalculateMedian(ReadOnlySpan<double> values)\n            {\n                int n = values.Length;\n                var midPoint = n / 2;\n\n                // Check if count is even, if so use average of the two middle values,\n                // otherwise take the middle value.\n                var median = n % 2 == 0 ? (values[midPoint - 1] + values[midPoint]) / 2d : values[midPoint];\n                return (midPoint, median);\n            }\n\n            /// <summary>\n            /// Calculate the mid points.\n            /// </summary>\n            /// <returns></returns>\n            public (double Min, double Q1, double Median, double Q3, double Max, double[] Outliers) CalculateBoxPlotStatistics()\n            {\n                var values = this.Values.ToArray();\n                Array.Sort(values);\n                var s = values.AsSpan();\n                var (midPoint, median) = CalculateMedian(s);\n\n                var (q1Index, q1) = midPoint > 0 ? CalculateMedian(s.Slice(0, midPoint)) : (midPoint, median);\n                var (q3Index, q3) = midPoint + 1 < s.Length ? CalculateMedian(s.Slice(midPoint + 1)) : (midPoint, median);\n                var iqr = q3 - q1;\n                var lowerFence = q1 - 1.5d * iqr;\n                var upperFence = q3 + 1.5d * iqr;\n                var outliers = values.Where(v => v < lowerFence || v > upperFence).ToArray();\n                var nonOutliers = values.Where(v => v >= lowerFence && v <= upperFence).ToArray();\n                return (\n                    nonOutliers.FirstOrDefault(),\n                    q1,\n                    median,\n                    q3,\n                    nonOutliers.LastOrDefault(),\n                    outliers\n                );\n            }\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet.TestAdapter/BenchmarkCaseExtensions.cs",
    "content": "﻿using BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Characteristics;\nusing BenchmarkDotNet.Exporters;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Running;\nusing Microsoft.TestPlatform.AdapterUtilities;\nusing Microsoft.VisualStudio.TestPlatform.ObjectModel;\nusing System;\n\nnamespace BenchmarkDotNet.TestAdapter\n{\n    /// <summary>\n    /// A set of extensions for BenchmarkCase to support converting to VSTest TestCase objects.\n    /// </summary>\n    internal static class BenchmarkCaseExtensions\n    {\n        /// <summary>\n        /// Converts a BDN BenchmarkCase to a VSTest TestCase.\n        /// </summary>\n        /// <param name=\"benchmarkCase\">The BenchmarkCase to convert.</param>\n        /// <param name=\"assemblyPath\">The dll or exe of the benchmark project.</param>\n        /// <param name=\"includeJobInName\">Whether or not the display name should include the job name.</param>\n        /// <returns>The VSTest TestCase.</returns>\n        internal static TestCase ToVsTestCase(this BenchmarkCase benchmarkCase, string assemblyPath, bool includeJobInName = false)\n        {\n            var benchmarkMethod = benchmarkCase.Descriptor.WorkloadMethod;\n            var fullClassName = benchmarkCase.Descriptor.Type.GetCorrectCSharpTypeName(prefixWithGlobal:false);\n            var parametrizedMethodName = FullNameProvider.GetMethodName(benchmarkCase);\n\n            var displayJobInfo = benchmarkCase.GetUnrandomizedJobDisplayInfo();\n            var displayMethodName = parametrizedMethodName + (includeJobInName ? $\" [{displayJobInfo}]\" : \"\");\n            var displayName = $\"{fullClassName}.{displayMethodName}\";\n\n            // We use displayName as FQN to workaround the Rider/R# problem with FQNs processing\n            // See: https://github.com/dotnet/BenchmarkDotNet/issues/2494\n            var fullyQualifiedName = displayName;\n\n            // Use benchmark method FQN on Visual Studio environment to avoid TestExplorer hierarchy split\n            // when job display name contains '.' which is interpreted as a namespace separator by VS.\n            // See: https://github.com/dotnet/BenchmarkDotNet/issues/2793\n            if (Environment.GetEnvironmentVariable(\"VSAPPIDNAME\") != null)\n            {\n                var benchmarkMethodName = benchmarkMethod.Name;\n                fullyQualifiedName = $\"{fullClassName}.{benchmarkMethodName}\";\n            }\n\n            var vsTestCase = new TestCase(fullyQualifiedName, VsTestAdapter.ExecutorUri, assemblyPath)\n            {\n                DisplayName = displayName,\n                Id = GetTestCaseId(benchmarkCase)\n            };\n\n            var benchmarkAttribute = benchmarkMethod.ResolveAttribute<BenchmarkAttribute>();\n            if (benchmarkAttribute != null)\n            {\n                vsTestCase.CodeFilePath = benchmarkAttribute.SourceCodeFile;\n                vsTestCase.LineNumber = benchmarkAttribute.SourceCodeLineNumber;\n            }\n\n            var categories = DefaultCategoryDiscoverer.Instance.GetCategories(benchmarkMethod);\n            foreach (var category in categories)\n                vsTestCase.Traits.Add(\"Category\", category);\n\n            vsTestCase.Traits.Add(\"\", \"BenchmarkDotNet\");\n\n            return vsTestCase;\n        }\n\n        /// <summary>\n        /// If an ID is not provided, a random string is used for the ID. This method will identify if randomness was\n        /// used for the ID and return the Job's DisplayInfo with that randomness removed so that the same benchmark\n        /// can be referenced across multiple processes.\n        /// </summary>\n        /// <param name=\"benchmarkCase\">The benchmark case.</param>\n        /// <returns>The benchmark case' job's DisplayInfo without randomness.</returns>\n        internal static string GetUnrandomizedJobDisplayInfo(this BenchmarkCase benchmarkCase)\n        {\n            var jobDisplayInfo = benchmarkCase.Job.DisplayInfo;\n            if (!benchmarkCase.Job.HasValue(CharacteristicObject.IdCharacteristic) &&\n                benchmarkCase.Job.ResolvedId.StartsWith(\"Job-\", StringComparison.OrdinalIgnoreCase))\n            {\n                // Replace Job-ABCDEF with Job\n                jobDisplayInfo = \"Job\" + jobDisplayInfo.Substring(benchmarkCase.Job.ResolvedId.Length);\n            }\n\n            return jobDisplayInfo;\n        }\n\n        /// <summary>\n        /// Gets an ID for a given BenchmarkCase that is uniquely identifiable from discovery to execution phase.\n        /// </summary>\n        /// <param name=\"benchmarkCase\">The benchmark case.</param>\n        /// <returns>The test case ID.</returns>\n        internal static Guid GetTestCaseId(this BenchmarkCase benchmarkCase)\n        {\n            var testIdProvider = new TestIdProvider();\n            testIdProvider.AppendString(VsTestAdapter.ExecutorUriString);\n            testIdProvider.AppendString(benchmarkCase.Descriptor.Type.Namespace ?? string.Empty);\n            testIdProvider.AppendString(benchmarkCase.Descriptor.DisplayInfo);\n            testIdProvider.AppendString(benchmarkCase.GetUnrandomizedJobDisplayInfo());\n            testIdProvider.AppendString(benchmarkCase.Parameters.DisplayInfo);\n            return testIdProvider.GetId();\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet.TestAdapter/BenchmarkDotNet.TestAdapter.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\n  <Import Project=\"..\\..\\build\\common.props\" />\n  <PropertyGroup>\n    <TargetFrameworks>netstandard2.0;net462</TargetFrameworks>\n    <AssemblyTitle>BenchmarkDotNet.TestAdapter</AssemblyTitle>\n    <AssemblyName>BenchmarkDotNet.TestAdapter</AssemblyName>\n    <PackageId>BenchmarkDotNet.TestAdapter</PackageId>\n    <ProduceReferenceAssembly>True</ProduceReferenceAssembly>\n  </PropertyGroup>\n\n  <!-- Use minimum supported LTSC version of Visual Studio 2022 -->\n  <!-- https://learn.microsoft.com/en-us/lifecycle/products/visual-studio-2022 -->\n  <ItemGroup>\n    <PackageReference Include=\"Microsoft.TestPlatform.AdapterUtilities\" Version=\"17.8.0\" />\n    <PackageReference Include=\"Microsoft.TestPlatform.ObjectModel\" Version=\"17.8.0\" />\n    <PackageReference Include=\"Microsoft.TestPlatform.TranslationLayer\" Version=\"17.8.0\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <ProjectReference Include=\"..\\BenchmarkDotNet\\BenchmarkDotNet.csproj\" />\n  </ItemGroup>\n\n  <!-- Include files in nuget package for generating entry point -->\n  <ItemGroup>\n    <Compile Remove=\"entrypoints\\EntryPoint.*\" />\n    <None Include=\"entrypoints\\EntryPoint.*\" Pack=\"true\" PackagePath=\"entrypoints\\\" />\n    <None Include=\"build\\BenchmarkDotNet.TestAdapter.props\" Pack=\"true\" PackagePath=\"build\\\" />\n  </ItemGroup>\n  <Import Project=\"..\\..\\build\\common.targets\" />\n</Project>\n"
  },
  {
    "path": "src/BenchmarkDotNet.TestAdapter/BenchmarkEnumerator.cs",
    "content": "﻿using BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Helpers;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Toolchains;\nusing System;\nusing System.IO;\nusing System.Linq;\nusing System.Reflection;\n\nnamespace BenchmarkDotNet.TestAdapter\n{\n    /// <summary>\n    /// A class used for enumerating all the benchmarks in an assembly.\n    /// </summary>\n    internal static class BenchmarkEnumerator\n    {\n        /// <summary>\n        /// Returns all the BenchmarkRunInfo objects from a given assembly.\n        /// </summary>\n        /// <param name=\"assemblyPath\">The dll or exe of the benchmark project.</param>\n        /// <returns>The benchmarks inside the assembly.</returns>\n        public static BenchmarkRunInfo[] GetBenchmarksFromAssemblyPath(string assemblyPath)\n        {\n#if NET462\n            // Temporary workaround for BenchmarkDotNet assembly loading issue that occurred under the following conditions:\n            //   1. Run BenchmarkDotNet.Samples project with following command.\n            //     > dotnet test -c Release --list-tests --framework net462 -tl:off\n            //   2. When using `BenchmarkDotNet.TestAdapter` package and targeting .NET Framework.\n            AppDomain.CurrentDomain.AssemblyResolve += (sender, eventArgs) =>\n            {\n                if (eventArgs.Name.StartsWith(\"BenchmarkDotNet, Version=\"))\n                {\n                    var baseDir = Path.GetDirectoryName(assemblyPath);\n                    var path = Path.Combine(baseDir, \"BenchmarkDotNet.dll\");\n                    if (File.Exists(path))\n                    {\n                        return Assembly.LoadFrom(path);\n                    }\n                }\n\n                if (eventArgs.Name.StartsWith(\"System.Collections.Immutable, Version=\"))\n                {\n                    var baseDir = Path.GetDirectoryName(assemblyPath);\n                    var path = Path.Combine(baseDir, \"System.Collections.Immutable.dll\");\n                    if (File.Exists(path))\n                    {\n                        return Assembly.LoadFrom(path);\n                    }\n                }\n\n                if (eventArgs.Name.StartsWith(\"System.Memory, Version=\"))\n                {\n                    var baseDir = Path.GetDirectoryName(assemblyPath);\n                    var path = Path.Combine(baseDir, \"System.Memory.dll\");\n                    if (File.Exists(path))\n                    {\n                        return Assembly.LoadFrom(path);\n                    }\n                }\n\n                // Fallback to default assembly resolver\n                return null;\n            };\n#endif\n\n            var assembly = Assembly.LoadFrom(assemblyPath);\n\n            var isDebugAssembly = assembly.IsJitOptimizationDisabled() ?? false;\n\n            return GenericBenchmarksBuilder.GetRunnableBenchmarks(assembly.GetRunnableBenchmarks())\n                .Select(type =>\n                {\n                    var benchmarkRunInfo = BenchmarkConverter.TypeToBenchmarks(type);\n                    if (isDebugAssembly)\n                    {\n                        // If the assembly is a debug assembly, then only display them if they will run in-process\n                        // This will allow people to debug their benchmarks using VSTest if they wish.\n                        benchmarkRunInfo = new BenchmarkRunInfo(\n                            benchmarkRunInfo.BenchmarksCases.Where(c => c.GetToolchain().IsInProcess).ToArray(),\n                            benchmarkRunInfo.Type,\n                            benchmarkRunInfo.Config,\n                            benchmarkRunInfo.CompositeInProcessDiagnoser);\n                    }\n\n                    return benchmarkRunInfo;\n                })\n                .Where(runInfo => runInfo.BenchmarksCases.Length > 0)\n                .ToArray();\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet.TestAdapter/BenchmarkExecutor.cs",
    "content": "﻿using BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.TestAdapter.Remoting;\nusing Microsoft.VisualStudio.TestPlatform.ObjectModel;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading;\n\nnamespace BenchmarkDotNet.TestAdapter\n{\n    /// <summary>\n    /// A class used for executing benchmarks\n    /// </summary>\n    internal class BenchmarkExecutor\n    {\n        private readonly CancellationTokenSource cts = new();\n\n        /// <summary>\n        /// Runs all the benchmarks in the given assembly, updating the TestExecutionRecorder as they get run.\n        /// </summary>\n        /// <param name=\"assemblyPath\">The dll or exe of the benchmark project.</param>\n        /// <param name=\"recorder\">The interface used to record the current test execution progress.</param>\n        /// <param name=\"benchmarkIds\">\n        /// An optional list of benchmark IDs specifying which benchmarks to run.\n        /// These IDs are the same as the ones generated for the VSTest TestCase.\n        /// </param>\n        public void RunBenchmarks(string assemblyPath, TestExecutionRecorderWrapper recorder, HashSet<Guid>? benchmarkIds = null)\n        {\n            var benchmarks = BenchmarkEnumerator.GetBenchmarksFromAssemblyPath(assemblyPath);\n            var testCases = new List<TestCase>();\n\n            var filteredBenchmarks = new List<BenchmarkRunInfo>();\n            foreach (var benchmark in benchmarks)\n            {\n                var needsJobInfo = benchmark.BenchmarksCases.Select(c => c.Job.DisplayInfo).Distinct().Count() > 1;\n                var filteredCases = new List<BenchmarkCase>();\n                foreach (var benchmarkCase in benchmark.BenchmarksCases)\n                {\n                    var testId = benchmarkCase.GetTestCaseId();\n                    if (benchmarkIds == null || benchmarkIds.Contains(testId))\n                    {\n                        filteredCases.Add(benchmarkCase);\n                        testCases.Add(benchmarkCase.ToVsTestCase(assemblyPath, needsJobInfo));\n                    }\n                }\n\n                if (filteredCases.Count > 0)\n                {\n                    filteredBenchmarks.Add(new BenchmarkRunInfo(filteredCases.ToArray(), benchmark.Type, benchmark.Config, benchmark.CompositeInProcessDiagnoser));\n                }\n            }\n\n            benchmarks = filteredBenchmarks.ToArray();\n\n            if (benchmarks.Length == 0)\n                return;\n\n            // Create an event processor which will subscribe to events and push them to VSTest\n            var eventProcessor = new VsTestEventProcessor(testCases, recorder, cts.Token);\n\n            // Create a logger which will forward all log messages in BDN to the VSTest logger.\n            var logger = new VsTestLogger(recorder.GetLogger());\n\n            // Modify all the benchmarks so that the event process and logger is added.\n            benchmarks = benchmarks\n                .Select(b => new BenchmarkRunInfo(\n                    b.BenchmarksCases,\n                    b.Type,\n                    b.Config.AddEventProcessor(eventProcessor)\n                            .AddLogger(logger)\n                            .RemoveLoggersOfType<ConsoleLogger>() // Console logs are also outputted by VSTestLogger.\n                            .CreateImmutableConfig(),\n                    b.CompositeInProcessDiagnoser))\n                .ToArray();\n\n            // Run all the benchmarks, and ensure that any tests that don't have a result yet are sent.\n            BenchmarkRunner.Run(benchmarks);\n            eventProcessor.SendUnsentTestResults();\n        }\n\n        /// <summary>\n        /// Stop the benchmarks when next able.\n        /// </summary>\n        public void Cancel()\n        {\n            cts.Cancel();\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet.TestAdapter/Remoting/BenchmarkEnumeratorWrapper.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\n\nnamespace BenchmarkDotNet.TestAdapter.Remoting\n{\n    /// <summary>\n    /// A wrapper around the BenchmarkEnumerator for passing data across AppDomain boundaries.\n    /// </summary>\n    internal class BenchmarkEnumeratorWrapper : MarshalByRefObject\n    {\n        /// <summary>\n        /// Gets a list of VSTest TestCases from the given assembly.\n        /// Each test case is serialized into a string so that it can be used across AppDomain boundaries.\n        /// </summary>\n        /// <param name=\"assemblyPath\">The dll or exe of the benchmark project.</param>\n        /// <returns>The serialized test cases.</returns>\n        public List<string> GetTestCasesFromAssemblyPathSerialized(string assemblyPath)\n        {\n            var serializedTestCases = new List<string>();\n            foreach (var runInfo in BenchmarkEnumerator.GetBenchmarksFromAssemblyPath(assemblyPath))\n            {\n                // If all the benchmarks have the same job, then no need to include job info.\n                var needsJobInfo = runInfo.BenchmarksCases.Select(c => c.Job.DisplayInfo).Distinct().Count() > 1;\n                foreach (var benchmarkCase in runInfo.BenchmarksCases)\n                {\n                    var testCase = benchmarkCase.ToVsTestCase(assemblyPath, needsJobInfo);\n                    serializedTestCases.Add(SerializationHelpers.Serialize(testCase));\n                }\n            }\n\n            return serializedTestCases;\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet.TestAdapter/Remoting/BenchmarkExecutorWrapper.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\n\nnamespace BenchmarkDotNet.TestAdapter.Remoting\n{\n    /// <summary>\n    /// A wrapper around the BenchmarkExecutor that works across AppDomain boundaries.\n    /// </summary>\n    internal class BenchmarkExecutorWrapper : MarshalByRefObject\n    {\n        private readonly BenchmarkExecutor benchmarkExecutor = new();\n\n        public void RunBenchmarks(string assemblyPath, TestExecutionRecorderWrapper recorder, HashSet<Guid>? benchmarkIds = null)\n        {\n            benchmarkExecutor.RunBenchmarks(assemblyPath, recorder, benchmarkIds);\n        }\n\n        public void Cancel()\n        {\n            benchmarkExecutor.Cancel();\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet.TestAdapter/Remoting/MessageLoggerWrapper.cs",
    "content": "﻿using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging;\nusing System;\n\nnamespace BenchmarkDotNet.TestAdapter.Remoting\n{\n    /// <summary>\n    /// A wrapper around an IMessageLogger that works across AppDomain boundaries.\n    /// </summary>\n    internal class MessageLoggerWrapper : MarshalByRefObject, IMessageLogger\n    {\n        private readonly IMessageLogger logger;\n\n        public MessageLoggerWrapper(IMessageLogger logger)\n        {\n            this.logger = logger;\n        }\n\n        public void SendMessage(TestMessageLevel testMessageLevel, string message)\n        {\n            logger.SendMessage(testMessageLevel, message);\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet.TestAdapter/Remoting/SerializationHelpers.cs",
    "content": "﻿using Microsoft.VisualStudio.TestPlatform.CommunicationUtilities;\n\nnamespace BenchmarkDotNet.TestAdapter.Remoting\n{\n    /// <summary>\n    /// A set of helper methods for serializing and deserializing the VSTest TestCases and TestReports.\n    /// </summary>\n    internal static class SerializationHelpers\n    {\n        // Version number of the VSTest protocol that the adapter supports. Only needs to be updated when\n        // the VSTest protocol has a change and this test adapter wishes to take a dependency on it.\n        // A list of protocol versions and a summary of the changes that were made in them can be found here:\n        //    https://github.com/microsoft/vstest/blob/main/docs/Overview.md#protocolversion-request\n        private const int VsTestProtocolVersion = 7;\n\n        public static string Serialize<T>(T data)\n        {\n            return JsonDataSerializer.Instance.Serialize(data, version: VsTestProtocolVersion);\n        }\n\n        public static T Deserialize<T>(string data)\n        {\n            return JsonDataSerializer.Instance.Deserialize<T>(data, version: VsTestProtocolVersion)!;\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet.TestAdapter/Remoting/TestExecutionRecorderWrapper.cs",
    "content": "﻿using Microsoft.VisualStudio.TestPlatform.ObjectModel;\nusing Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter;\nusing System;\n\nnamespace BenchmarkDotNet.TestAdapter.Remoting\n{\n    /// <summary>\n    /// A wrapper around the ITestExecutionRecorder which works across AppDomain boundaries.\n    /// </summary>\n    internal class TestExecutionRecorderWrapper : MarshalByRefObject\n    {\n        private readonly ITestExecutionRecorder testExecutionRecorder;\n\n        public TestExecutionRecorderWrapper(ITestExecutionRecorder testExecutionRecorder)\n        {\n            this.testExecutionRecorder = testExecutionRecorder;\n        }\n\n        public MessageLoggerWrapper GetLogger()\n        {\n            return new MessageLoggerWrapper(testExecutionRecorder);\n        }\n\n        internal void RecordStart(string serializedTestCase)\n        {\n            testExecutionRecorder.RecordStart(SerializationHelpers.Deserialize<TestCase>(serializedTestCase));\n        }\n\n        internal void RecordEnd(string serializedTestCase, TestOutcome testOutcome)\n        {\n            testExecutionRecorder.RecordEnd(SerializationHelpers.Deserialize<TestCase>(serializedTestCase), testOutcome);\n        }\n\n        internal void RecordResult(string serializedTestResult)\n        {\n            testExecutionRecorder.RecordResult(SerializationHelpers.Deserialize<TestResult>(serializedTestResult));\n        }\n    }\n}"
  },
  {
    "path": "src/BenchmarkDotNet.TestAdapter/Utility/LoggerHelper.cs",
    "content": "﻿using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging;\nusing System.Diagnostics;\nusing System.IO;\n\nnamespace BenchmarkDotNet.TestAdapter;\n\ninternal class LoggerHelper\n{\n    public LoggerHelper(IMessageLogger logger, Stopwatch stopwatch)\n    {\n        InnerLogger = logger;\n        Stopwatch = stopwatch;\n    }\n\n    public IMessageLogger InnerLogger { get; private set; }\n\n    public Stopwatch Stopwatch { get; private set; }\n\n    public void Log(string format, params object[] args)\n    {\n        SendMessage(TestMessageLevel.Informational, null, string.Format(format, args));\n    }\n\n    public void LogWithSource(string source, string format, params object[] args)\n    {\n        SendMessage(TestMessageLevel.Informational, source, string.Format(format, args));\n    }\n\n    public void LogError(string format, params object[] args)\n    {\n        SendMessage(TestMessageLevel.Error, null, string.Format(format, args));\n    }\n\n    public void LogErrorWithSource(string source, string format, params object[] args)\n    {\n        SendMessage(TestMessageLevel.Error, source, string.Format(format, args));\n    }\n\n    public void LogWarning(string format, params object[] args)\n    {\n        SendMessage(TestMessageLevel.Warning, null, string.Format(format, args));\n    }\n\n    public void LogWarningWithSource(string source, string format, params object[] args)\n    {\n        SendMessage(TestMessageLevel.Warning, source, string.Format(format, args));\n    }\n\n    private void SendMessage(TestMessageLevel level, string? assemblyName, string message)\n    {\n        var assemblyText = assemblyName == null\n            ? \"\" :\n            $\"{Path.GetFileNameWithoutExtension(assemblyName)}: \";\n\n        InnerLogger.SendMessage(level, $\"[BenchmarkDotNet {Stopwatch.Elapsed:hh\\\\:mm\\\\:ss\\\\.ff}] {assemblyText}{message}\");\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet.TestAdapter/Utility/TestCaseFilter.cs",
    "content": "﻿using Microsoft.VisualStudio.TestPlatform.ObjectModel;\nusing Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter;\nusing System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Reflection;\nusing System.Runtime.ExceptionServices;\n\nnamespace BenchmarkDotNet.TestAdapter;\n\ninternal class TestCaseFilter\n{\n    private const string DisplayNameString = \"DisplayName\";\n    private const string FullyQualifiedNameString = \"FullyQualifiedName\";\n\n    private readonly HashSet<string> knownTraits;\n    private List<string> supportedPropertyNames;\n    private readonly ITestCaseFilterExpression? filterExpression;\n    private readonly bool successfullyGotFilter;\n    private readonly bool isDiscovery;\n\n    public TestCaseFilter(IDiscoveryContext discoveryContext, LoggerHelper logger)\n    {\n        // Traits are not known at discovery time because we load them from benchmarks\n        isDiscovery = true;\n        knownTraits = [];\n        supportedPropertyNames = GetSupportedPropertyNames();\n        successfullyGotFilter = GetTestCaseFilterExpressionFromDiscoveryContext(discoveryContext, logger, out filterExpression);\n    }\n\n    public TestCaseFilter(IRunContext runContext, LoggerHelper logger, string assemblyFileName, HashSet<string> knownTraits)\n    {\n        this.knownTraits = knownTraits;\n        supportedPropertyNames = GetSupportedPropertyNames();\n        successfullyGotFilter = GetTestCaseFilterExpression(runContext, logger, assemblyFileName, out filterExpression);\n    }\n\n    public string GetTestCaseFilterValue()\n    {\n        return successfullyGotFilter\n            ? filterExpression?.TestCaseFilterValue ?? \"\"\n            : \"\";\n    }\n\n    public bool MatchTestCase(TestCase testCase)\n    {\n        if (!successfullyGotFilter)\n        {\n            // Had an error while getting filter, match no testcase to ensure discovered test list is empty\n            return false;\n        }\n        else if (filterExpression == null)\n        {\n            // No filter specified, keep every testcase\n            return true;\n        }\n\n        return filterExpression.MatchTestCase(testCase, p => PropertyProvider(testCase, p));\n    }\n\n    public object? PropertyProvider(TestCase testCase, string name)\n    {\n        // Traits filtering\n        if (isDiscovery || knownTraits.Contains(name))\n        {\n            var result = new List<string>();\n\n            foreach (var trait in GetTraits(testCase))\n                if (string.Equals(trait.Key, name, StringComparison.OrdinalIgnoreCase))\n                    result.Add(trait.Value);\n\n            if (result.Count > 0)\n                return result.ToArray();\n        }\n\n        // Property filtering\n        switch (name.ToLowerInvariant())\n        {\n            // FullyQualifiedName\n            case \"fullyqualifiedname\":\n                return testCase.FullyQualifiedName;\n            // DisplayName\n            case \"displayname\":\n                return testCase.DisplayName;\n            default:\n                return null;\n        }\n    }\n\n    private bool GetTestCaseFilterExpression(IRunContext runContext, LoggerHelper logger, string assemblyFileName, out ITestCaseFilterExpression? filter)\n    {\n        filter = null;\n\n        try\n        {\n            filter = runContext.GetTestCaseFilter(supportedPropertyNames, null!);\n            return true;\n        }\n        catch (TestPlatformFormatException e)\n        {\n            logger.LogWarning(\"{0}: Exception filtering tests: {1}\", Path.GetFileNameWithoutExtension(assemblyFileName), e.Message);\n            return false;\n        }\n    }\n\n    private bool GetTestCaseFilterExpressionFromDiscoveryContext(IDiscoveryContext discoveryContext, LoggerHelper logger, out ITestCaseFilterExpression? filter)\n    {\n        filter = null;\n\n        if (discoveryContext is IRunContext runContext)\n        {\n            try\n            {\n                filter = runContext.GetTestCaseFilter(supportedPropertyNames, null!);\n                return true;\n            }\n            catch (TestPlatformException e)\n            {\n                logger.LogWarning(\"Exception filtering tests: {0}\", e.Message);\n                return false;\n            }\n        }\n        else\n        {\n            try\n            {\n                // GetTestCaseFilter is present on DiscoveryContext but not in IDiscoveryContext interface\n                var method = discoveryContext.GetType().GetRuntimeMethod(\"GetTestCaseFilter\", [typeof(IEnumerable<string>), typeof(Func<string, TestProperty>)]);\n                filter = (ITestCaseFilterExpression)method?.Invoke(discoveryContext, [supportedPropertyNames, null])!;\n\n                return true;\n            }\n            catch (TargetInvocationException e)\n            {\n                if (e.InnerException is TestPlatformException ex)\n                {\n                    logger.LogWarning(\"Exception filtering tests: {0}\", ex.Message);\n                    return false;\n                }\n\n                ExceptionDispatchInfo.Capture(e.InnerException ?? e).Throw();\n                return default!;// It's required to suppress error CS0161.\n            }\n        }\n    }\n\n    private List<string> GetSupportedPropertyNames()\n    {\n        // Returns the set of well-known property names usually used with the Test Plugins (Used Test Traits + DisplayName + FullyQualifiedName)\n        if (supportedPropertyNames == null)\n        {\n            supportedPropertyNames = knownTraits.ToList();\n            supportedPropertyNames.Add(DisplayNameString);\n            supportedPropertyNames.Add(FullyQualifiedNameString);\n        }\n\n        return supportedPropertyNames;\n    }\n\n    private static IEnumerable<KeyValuePair<string, string>> GetTraits(TestCase testCase)\n    {\n        var traitProperty = TestProperty.Find(\"TestObject.Traits\");\n        return traitProperty != null\n            ? testCase.GetPropertyValue(traitProperty, Array.Empty<KeyValuePair<string, string>>())\n            : [];\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet.TestAdapter/VSTestAdapter.cs",
    "content": "﻿using BenchmarkDotNet.TestAdapter.Remoting;\nusing Microsoft.VisualStudio.TestPlatform.ObjectModel;\nusing Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter;\nusing Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging;\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.IO;\nusing System.Linq;\nusing System.Reflection;\nusing System.Threading;\n\nnamespace BenchmarkDotNet.TestAdapter\n{\n    /// <summary>\n    /// Discovers and executes benchmarks using the VSTest protocol.\n    /// </summary>\n    [ExtensionUri(ExecutorUriString)]\n    [DefaultExecutorUri(ExecutorUriString)]\n    [FileExtension(\".dll\")]\n    [FileExtension(\".exe\")]\n    public class VsTestAdapter : ITestExecutor, ITestDiscoverer\n    {\n        // This URI is used to identify the adapter.\n        internal const string ExecutorUriString = \"executor://BenchmarkDotNet.TestAdapter\";\n        internal static readonly Uri ExecutorUri = new Uri(ExecutorUriString);\n\n        /// <summary>\n        /// Cancellation token used to stop any benchmarks that are currently running.\n        /// </summary>\n        private CancellationTokenSource? cts = null;\n\n        /// <summary>\n        /// Discovers the benchmarks.\n        /// </summary>\n        /// <param name=\"sources\">List of assemblies to search for benchmarks in.</param>\n        /// <param name=\"discoveryContext\">A context that the discovery is performed in.</param>\n        /// <param name=\"logger\">Logger that sends messages back to VSTest host.</param>\n        /// <param name=\"discoverySink\">Interface that provides methods for sending discovered benchmarks back to the host.</param>\n        public void DiscoverTests(\n            IEnumerable<string> sources,\n            IDiscoveryContext discoveryContext,\n            IMessageLogger logger,\n            ITestCaseDiscoverySink discoverySink)\n        {\n            var stopwatch = Stopwatch.StartNew();\n            var loggerHelper = new LoggerHelper(logger, stopwatch);\n            var testCaseFilter = new TestCaseFilter(discoveryContext, loggerHelper);\n\n            foreach (var source in sources)\n            {\n                ValidateSourceIsAssemblyOrThrow(source);\n                foreach (var testCase in GetVsTestCasesFromAssembly(source, logger))\n                {\n                    if (!testCaseFilter.MatchTestCase(testCase))\n                        continue;\n\n                    discoverySink.SendTestCase(testCase);\n                }\n            }\n        }\n\n        /// <summary>\n        /// Runs a given set of test cases that represent benchmarks.\n        /// </summary>\n        /// <param name=\"tests\">The tests to run.</param>\n        /// <param name=\"runContext\">A context that the run is performed in.</param>\n        /// <param name=\"frameworkHandle\">Interface used for communicating with the VSTest host.</param>\n        public void RunTests(IEnumerable<TestCase>? tests, IRunContext? runContext, IFrameworkHandle? frameworkHandle)\n        {\n            if (tests == null)\n                throw new ArgumentNullException(nameof(tests));\n            if (frameworkHandle == null)\n                throw new ArgumentNullException(nameof(frameworkHandle));\n\n            cts ??= new CancellationTokenSource();\n\n            var stopwatch = Stopwatch.StartNew();\n            var logger = new LoggerHelper(frameworkHandle, stopwatch);\n\n            foreach (var testsPerAssembly in tests.GroupBy(t => t.Source))\n            {\n                RunBenchmarks(testsPerAssembly.Key, frameworkHandle, testsPerAssembly);\n            }\n\n            cts = null;\n        }\n\n        /// <summary>\n        /// Runs all/filtered benchmarks in the given set of sources (assemblies).\n        /// </summary>\n        /// <param name=\"sources\">The assemblies to run.</param>\n        /// <param name=\"runContext\">A context that the run is performed in.</param>\n        /// <param name=\"frameworkHandle\">Interface used for communicating with the VSTest host.</param>\n        public void RunTests(IEnumerable<string>? sources, IRunContext? runContext, IFrameworkHandle? frameworkHandle)\n        {\n            if (sources == null)\n                throw new ArgumentNullException(nameof(sources));\n            if (frameworkHandle == null)\n                throw new ArgumentNullException(nameof(frameworkHandle));\n\n            cts ??= new CancellationTokenSource();\n\n            var stopwatch = Stopwatch.StartNew();\n            var logger = new LoggerHelper(frameworkHandle, stopwatch);\n\n            foreach (var source in sources)\n            {\n                var filter = new TestCaseFilter(runContext!, logger, source, [\"Category\"]);\n                if (filter.GetTestCaseFilterValue() != \"\")\n                {\n                    var discoveredBenchmarks = GetVsTestCasesFromAssembly(source, frameworkHandle);\n                    var filteredTestCases = discoveredBenchmarks.Where(x => filter.MatchTestCase(x))\n                                                                .ToArray();\n\n                    if (filteredTestCases.Length == 0)\n                        continue;\n\n                    // Run filtered tests.\n                    RunBenchmarks(source, frameworkHandle, filteredTestCases);\n                }\n                else\n                {\n                    // Run all benchmarks\n                    RunBenchmarks(source, frameworkHandle);\n                }\n            }\n\n\n            cts = null;\n        }\n\n        /// <summary>\n        /// Stops any currently running benchmarks.\n        /// </summary>\n        public void Cancel()\n        {\n            cts?.Cancel();\n        }\n\n        /// <summary>\n        /// Gets the VSTest test cases in the given assembly.\n        /// </summary>\n        /// <param name=\"assemblyPath\">The dll or exe of the benchmark project.</param>\n        /// <param name=\"logger\">A logger that sends logs to VSTest.</param>\n        /// <returns>The VSTest test cases inside the given assembly.</returns>\n        private static List<TestCase> GetVsTestCasesFromAssembly(string assemblyPath, IMessageLogger logger)\n        {\n            try\n            {\n                // Ensure that the test enumeration is done inside the context of the source directory.\n                var enumerator = (BenchmarkEnumeratorWrapper)CreateIsolatedType(typeof(BenchmarkEnumeratorWrapper), assemblyPath);\n                var testCases = enumerator\n                    .GetTestCasesFromAssemblyPathSerialized(assemblyPath)\n                    .Select(SerializationHelpers.Deserialize<TestCase>)\n                    .ToList();\n\n                // Validate that all test ids are unique\n                var idLookup = new Dictionary<Guid, string>();\n                foreach (var testCase in testCases)\n                {\n                    if (idLookup.TryGetValue(testCase.Id, out var matchingCase))\n                        throw new Exception($\"Encountered Duplicate Test ID: '{testCase.DisplayName}' and '{matchingCase}'\");\n\n                    idLookup[testCase.Id] = testCase.DisplayName;\n                }\n\n                return testCases;\n            }\n            catch (Exception ex)\n            {\n                logger.SendMessage(TestMessageLevel.Error, $\"Failed to load benchmarks from assembly\\n{ex}\");\n                throw;\n            }\n        }\n\n        /// <summary>\n        /// Runs the benchmarks in the given source.\n        /// </summary>\n        /// <param name=\"source\">The dll or exe of the benchmark project.</param>\n        /// <param name=\"frameworkHandle\">An interface used to communicate with the VSTest host.</param>\n        /// <param name=\"testCases\">\n        /// The specific test cases to be run if specified.\n        /// If unspecified, runs all the test cases in the source.\n        /// </param>\n        private void RunBenchmarks(string source, IFrameworkHandle frameworkHandle, IEnumerable<TestCase>? testCases = null)\n        {\n            ValidateSourceIsAssemblyOrThrow(source);\n\n            // Create a HashSet of all the TestCase IDs to be run if specified.\n            var caseIds = testCases == null ? null : new HashSet<Guid>(testCases.Select(c => c.Id));\n\n            try\n            {\n                // Ensure that test execution is done inside the context of the source directory.\n                var executor = (BenchmarkExecutorWrapper)CreateIsolatedType(typeof(BenchmarkExecutorWrapper), source);\n                cts?.Token.Register(executor.Cancel);\n\n                executor.RunBenchmarks(source, new TestExecutionRecorderWrapper(frameworkHandle), caseIds);\n            }\n            catch (Exception ex)\n            {\n                frameworkHandle.SendMessage(TestMessageLevel.Error, $\"Failed to run benchmarks in assembly\\n{ex}\");\n                throw;\n            }\n        }\n\n        /// <summary>\n        /// This will create the given type in a child AppDomain when used in .NET Framework.\n        /// If not in the .NET Framework, it will use the current AppDomain.\n        /// </summary>\n        /// <param name=\"type\">The type to create.</param>\n        /// <param name=\"assemblyPath\">The dll or exe of the benchmark project.</param>\n        /// <returns>The created object.</returns>\n        private static object CreateIsolatedType(Type type, string assemblyPath)\n        {\n            // .NET Framework runs require a custom AppDomain to be set up to run the benchmarks in because otherwise,\n            // all the assemblies will be loaded from the VSTest console rather than from the directory that the BDN\n            // program under test lives in. .NET Core assembly resolution is smarter and will correctly load the right\n            // assembly versions as needed and does not require a custom AppDomain. Unfortunately, the APIs needed to\n            // create the AppDomain for .NET Framework are not part of .NET Standard, and so a multi-targeting solution\n            // such as this is required to get this to work. This same approach is also used by other .NET unit testing\n            // libraries as well, further justifying this approach to solving how to get the correct assemblies loaded.\n#if NETFRAMEWORK\n            var appBase = Path.GetDirectoryName(assemblyPath);\n            var setup = new AppDomainSetup { ApplicationBase = appBase };\n            var domainName = $\"Isolated Domain for {type.Name}\";\n            var appDomain = AppDomain.CreateDomain(domainName, null, setup);\n            return appDomain.CreateInstanceAndUnwrap(\n                type.Assembly.FullName, type.FullName, false, BindingFlags.Default, null, null, null, null);\n#else\n            return Activator.CreateInstance(type);\n#endif\n        }\n\n        private static void ValidateSourceIsAssemblyOrThrow(string source)\n        {\n            if (string.IsNullOrEmpty(source))\n                throw new ArgumentException($\"'{nameof(source)}' cannot be null or whitespace.\", nameof(source));\n\n            if (!Path.HasExtension(source))\n                throw new NotSupportedException($\"Missing extension on source '{source}', must have the extension '.dll' or '.exe'.\");\n\n            var extension = Path.GetExtension(source);\n            if (!string.Equals(extension, \".dll\", StringComparison.OrdinalIgnoreCase) && !string.Equals(extension, \".exe\", StringComparison.OrdinalIgnoreCase))\n                throw new NotSupportedException($\"Unsupported extension on source '{source}', must have the extension '.dll' or '.exe'.\");\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet.TestAdapter/VSTestEventProcessor.cs",
    "content": "﻿using BenchmarkDotNet.EventProcessors;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.TestAdapter.Remoting;\nusing BenchmarkDotNet.Toolchains.Results;\nusing BenchmarkDotNet.Validators;\nusing Microsoft.VisualStudio.TestPlatform.ObjectModel;\nusing Perfolizer.Mathematics.Histograms;\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Globalization;\nusing System.Linq;\nusing System.Text;\nusing System.Threading;\n\nnamespace BenchmarkDotNet.TestAdapter\n{\n    /// <summary>\n    /// An event processor which will pass on benchmark execution information to VSTest.\n    /// </summary>\n    internal class VsTestEventProcessor : EventProcessor\n    {\n        private readonly Dictionary<Guid, TestCase> cases;\n        private readonly TestExecutionRecorderWrapper recorder;\n        private readonly CancellationToken cancellationToken;\n        private readonly Stopwatch runTimerStopwatch = new();\n        private readonly Dictionary<Guid, TestResult> testResults = [];\n        private readonly HashSet<Guid> sentTestResults = [];\n\n        public VsTestEventProcessor(\n            List<TestCase> cases,\n            TestExecutionRecorderWrapper recorder,\n            CancellationToken cancellationToken)\n        {\n            this.cases = cases.ToDictionary(c => c.Id);\n            this.recorder = recorder;\n            this.cancellationToken = cancellationToken;\n        }\n\n        public override void OnValidationError(ValidationError validationError)\n        {\n            // If the error is not linked to a benchmark case, then set the error on all benchmarks\n            var errorCases = validationError.BenchmarkCase == null\n                ? cases.Values.ToList()\n                : [cases[validationError.BenchmarkCase.GetTestCaseId()]];\n            foreach (var testCase in errorCases)\n            {\n                var testResult = GetOrCreateTestResult(testCase);\n\n                if (validationError.IsCritical)\n                {\n                    // Fail if there is a critical validation error\n                    testResult.Outcome = TestOutcome.Failed;\n\n                    // Append validation error message to end of test case error message\n                    testResult.ErrorMessage = testResult.ErrorMessage == null\n                        ? validationError.Message\n                        : $\"{testResult.ErrorMessage}\\n{validationError.Message}\";\n\n                    // The test result is not sent yet, in case there are multiple validation errors that need to be sent.\n                }\n                else\n                {\n                    // If the validation error is not critical, append it as a message\n                    testResult.Messages.Add(new TestResultMessage(TestResultMessage.StandardOutCategory, $\"WARNING: {validationError.Message}\\n\"));\n                }\n            }\n        }\n\n        public override void OnBuildComplete(BuildPartition buildPartition, BuildResult buildResult)\n        {\n            // Only need to handle build failures\n            if (!buildResult.IsBuildSuccess)\n            {\n                foreach (var benchmarkBuildInfo in buildPartition.Benchmarks)\n                {\n                    var testCase = cases[benchmarkBuildInfo.BenchmarkCase.GetTestCaseId()];\n                    var testResult = GetOrCreateTestResult(testCase);\n\n                    if (buildResult.GenerateException != null)\n                        testResult.ErrorMessage = $\"// Generate Exception: {buildResult.GenerateException.Message}\";\n                    else if (!buildResult.IsBuildSuccess && buildResult.TryToExplainFailureReason(out string? reason))\n                        testResult.ErrorMessage = $\"// Build Error: {reason}\";\n                    else if (buildResult.ErrorMessage != null)\n                        testResult.ErrorMessage = $\"// Build Error: {buildResult.ErrorMessage}\";\n                    testResult.Outcome = TestOutcome.Failed;\n\n                    // Send the result immediately\n                    RecordStart(testCase);\n                    RecordEnd(testCase, testResult.Outcome);\n                    RecordResult(testResult);\n                    sentTestResults.Add(testCase.Id);\n                }\n            }\n        }\n\n        public override void OnStartRunBenchmark(BenchmarkCase benchmarkCase)\n        {\n            // TODO: add proper cancellation support to BDN so that we don't need to do cancellation through the event processor\n            cancellationToken.ThrowIfCancellationRequested();\n\n            var testCase = cases[benchmarkCase.GetTestCaseId()];\n            var testResult = GetOrCreateTestResult(testCase);\n            testResult.StartTime = DateTimeOffset.UtcNow;\n\n            RecordStart(testCase);\n            runTimerStopwatch.Restart();\n        }\n\n        public override void OnEndRunBenchmark(BenchmarkCase benchmarkCase, BenchmarkReport report)\n        {\n            var testCase = cases[benchmarkCase.GetTestCaseId()];\n            var testResult = GetOrCreateTestResult(testCase);\n            testResult.EndTime = DateTimeOffset.UtcNow;\n            testResult.Duration = runTimerStopwatch.Elapsed;\n            testResult.Outcome = report.Success ? TestOutcome.Passed : TestOutcome.Failed;\n\n            var resultRuns = report.GetResultRuns();\n\n            // Provide the raw result runs data.\n            testResult.SetPropertyValue(VsTestProperties.Measurement, resultRuns.Select(m => m.Nanoseconds.ToString()).ToArray());\n\n            // Add a message to the TestResult which contains the results summary.\n            testResult.Messages.Add(new TestResultMessage(TestResultMessage.StandardOutCategory, report.BenchmarkCase.DisplayInfo + \"\\n\"));\n            testResult.Messages.Add(new TestResultMessage(TestResultMessage.StandardOutCategory, $\"Runtime = {report.GetRuntimeInfo()}; GC = {report.GetGcInfo()}\\n\"));\n\n            var statistics = resultRuns.GetStatistics();\n            var cultureInfo = CultureInfo.InvariantCulture;\n            var formatter = statistics.CreateNanosecondFormatter(cultureInfo);\n\n            var builder = new StringBuilder();\n            var histogram = HistogramBuilder.Adaptive.Build(statistics.Sample.Values);\n            builder.AppendLine(\"-------------------- Histogram --------------------\");\n            builder.AppendLine(histogram.ToString(formatter));\n            builder.AppendLine(\"---------------------------------------------------\");\n\n            var statisticsOutput = statistics.ToString(cultureInfo, formatter, calcHistogram: false);\n            builder.AppendLine(statisticsOutput);\n\n            testResult.Messages.Add(new TestResultMessage(TestResultMessage.StandardOutCategory, builder.ToString()));\n\n            RecordEnd(testResult.TestCase, testResult.Outcome);\n            RecordResult(testResult);\n            sentTestResults.Add(testCase.Id);\n        }\n\n        /// <summary>\n        /// Iterate through all the benchmarks that were scheduled to run, and if they haven't been sent yet, send the result through.\n        /// </summary>\n        public void SendUnsentTestResults()\n        {\n            foreach (var testCase in cases.Values)\n            {\n                if (!sentTestResults.Contains(testCase.Id))\n                {\n                    var testResult = GetOrCreateTestResult(testCase);\n                    if (testResult.Outcome == TestOutcome.None)\n                        testResult.Outcome = TestOutcome.Skipped;\n                    RecordStart(testCase);\n                    RecordEnd(testCase, testResult.Outcome);\n                    RecordResult(testResult);\n                }\n            }\n        }\n\n        private TestResult GetOrCreateTestResult(TestCase testCase)\n        {\n            if (testResults.TryGetValue(testCase.Id, out var testResult))\n                return testResult;\n\n            var newResult = new TestResult(testCase)\n            {\n                ComputerName = Environment.MachineName,\n                DisplayName = testCase.DisplayName\n            };\n\n            testResults[testCase.Id] = newResult;\n            return newResult;\n        }\n\n        private void RecordStart(TestCase testCase)\n        {\n            recorder.RecordStart(SerializationHelpers.Serialize(testCase));\n        }\n\n        private void RecordEnd(TestCase testCase, TestOutcome testOutcome)\n        {\n            recorder.RecordEnd(SerializationHelpers.Serialize(testCase), testOutcome);\n        }\n\n        private void RecordResult(TestResult testResult)\n        {\n            recorder.RecordResult(SerializationHelpers.Serialize(testResult));\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet.TestAdapter/VSTestLogger.cs",
    "content": "﻿using BenchmarkDotNet.Loggers;\nusing Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging;\nusing System.Text;\n\nnamespace BenchmarkDotNet.TestAdapter\n{\n    /// <summary>\n    /// A class to send logs from BDN to the VSTest output log.\n    /// </summary>\n    internal sealed class VsTestLogger : ILogger\n    {\n        private readonly IMessageLogger messageLogger;\n        private readonly StringBuilder currentLine = new StringBuilder();\n        private TestMessageLevel currentLevel = TestMessageLevel.Informational;\n\n        public VsTestLogger(IMessageLogger logger)\n        {\n            messageLogger = logger;\n        }\n\n        public string Id => nameof(VsTestLogger);\n\n        public int Priority => 0;\n\n        public void Flush()\n        {\n            WriteLine();\n        }\n\n        public void Write(LogKind logKind, string text)\n        {\n            currentLine.Append(text);\n\n            // Assume that if the log kind is an error, that the whole line is treated as an error\n            // The level will be reset to Informational when WriteLine() is called.\n            currentLevel = logKind switch\n            {\n                LogKind.Error => TestMessageLevel.Error,\n                LogKind.Warning => TestMessageLevel.Warning,\n                _ => currentLevel\n            };\n        }\n\n        public void WriteLine()\n        {\n            // The VSTest logger throws an error on logging empty or whitespace strings, so skip them.\n            if (currentLine.Length == 0)\n                return;\n\n            messageLogger.SendMessage(currentLevel, currentLine.ToString());\n\n            currentLevel = TestMessageLevel.Informational;\n            currentLine.Clear();\n        }\n\n        public void WriteLine(LogKind logKind, string text)\n        {\n            Write(logKind, text);\n            WriteLine();\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet.TestAdapter/VSTestProperties.cs",
    "content": "﻿using Microsoft.VisualStudio.TestPlatform.ObjectModel;\n\nnamespace BenchmarkDotNet.TestAdapter\n{\n    /// <summary>\n    /// A class that contains all the custom properties that can be set on VSTest TestCase and TestResults.\n    /// Some of these properties are well known as they are also used by VSTest adapters for other test libraries.\n    /// </summary>\n    internal static class VsTestProperties\n    {\n        /// <summary>\n        /// A test property used for storing the test results so that they could be accessed\n        /// programmatically from a custom VSTest runner.\n        /// </summary>\n        internal static readonly TestProperty Measurement = TestProperty.Register(\n            \"BenchmarkDotNet.TestAdapter.Measurements\",\n            \"Measurements\",\n            typeof(string[]),\n            TestPropertyAttributes.Hidden,\n            typeof(TestResult));\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet.TestAdapter/build/BenchmarkDotNet.TestAdapter.props",
    "content": "﻿<Project InitialTargets=\"GenerateBDNEntryPoint\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <PropertyGroup>\n    <EntryPointSourceDirectory>$(MSBuildThisFileDirectory)..\\entrypoints\\</EntryPointSourceDirectory>\n    <!-- Disable parallel tests between TargetFrameworks, if it's not explicitly specified. -->\n    <TestTfmsInParallel Condition=\"'$(TestTfmsInParallel)' == ''\">false</TestTfmsInParallel>\n  </PropertyGroup>\n  <!-- \n    Microsoft.NET.Test.Sdk uses a property called \"GenerateProgramFile\" to determine whether it generates an entry \n    point automatically. We don't want to use the entry point that Microsoft.NET.Test.Sdk generates, so we generate \n    our own and set this property to false.\n  -->\n  <Target Name=\"GenerateBDNEntryPoint\">\n    <ItemGroup Condition=\"'$(GenerateProgramFile)' != 'false'\">\n      <Compile Include=\"$(EntryPointSourceDirectory)EntryPoint.cs\" Condition=\"'$(Language)' == 'C#'\" Visible=\"false\"/>\n      <CompileAfter Include=\"$(EntryPointSourceDirectory)EntryPoint.fs\" Condition=\"'$(Language)' == 'F#'\" Visible=\"false\"/>\n      <Compile Include=\"$(EntryPointSourceDirectory)EntryPoint.vb\" Condition=\"'$(Language)' == 'VB'\" Visible=\"false\"/>\n    </ItemGroup>\n    <PropertyGroup>\n      <!-- Disables generation of VSTest entrypoint -->\n      <GenerateProgramFile>false</GenerateProgramFile>\n    </PropertyGroup>\n  </Target>\n</Project>\n"
  },
  {
    "path": "src/BenchmarkDotNet.TestAdapter/entrypoints/EntryPoint.cs",
    "content": "﻿// <auto-generated>\n// Exclude this file from StyleCop analysis. This file isn't generated but is added to projects.\n// </auto-generated>\n\nusing BenchmarkDotNet.Running;\nusing System.Reflection;\n\npublic class __AutoGeneratedEntryPointClass\n{\n    public static void Main(string[] args) => BenchmarkSwitcher.FromAssembly(typeof(__AutoGeneratedEntryPointClass).Assembly).Run(args);\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet.TestAdapter/entrypoints/EntryPoint.fs",
    "content": "﻿// <auto-generated>\n// Exclude this file from StyleCop analysis. This file isn't generated but is added to projects.\n// </auto-generated>\n\nmodule __AutoGeneratedEntryPointClass\nopen System.Reflection;\nopen BenchmarkDotNet.Running\n\ntype internal __Marker = interface end // Used to help locale current assembly\n[<EntryPoint>]\nlet main argv =\n    BenchmarkSwitcher.FromAssembly(typeof<__Marker>.Assembly).Run(argv) |> ignore\n    0 // return an integer exit code\n"
  },
  {
    "path": "src/BenchmarkDotNet.TestAdapter/entrypoints/EntryPoint.vb",
    "content": "﻿REM <auto-generated>\nREM Exclude this file from StyleCop analysis. This file isn't generated but is added to projects.\nREM </auto-generated>\n\nImports System.Reflection\nImports BenchmarkDotNet.Running\n\nNamespace Global\n    Module __AutoGeneratedEntryPointClass\n        Sub Main(args As String())\n            Dim summary = BenchmarkSwitcher.FromAssembly(MethodBase.GetCurrentMethod().Module.Assembly).Run(args)\n        End Sub\n    End Module\nEnd Namespace"
  },
  {
    "path": "src/BenchmarkDotNet.Weaver/.gitignore",
    "content": "!packages/"
  },
  {
    "path": "src/BenchmarkDotNet.Weaver/BenchmarkDotNet.Weaver.csproj",
    "content": "﻿<!--\nIf any changes are made to this project, increment the WeaverVersionSuffix in the common.props file,\nthen run `build.cmd pack-weaver`.\n-->\n\n<Project Sdk=\"Microsoft.NET.Sdk\">\n  <Import Project=\"..\\..\\build\\common.props\" />\n  <PropertyGroup>\n    <TargetFrameworks>netstandard2.0</TargetFrameworks>\n    <VersionSuffix Condition=\"'$(IsFullPack)' != 'true'\">$(VersionSuffix)$(WeaverVersionSuffix)</VersionSuffix>\n    <OutputPath>$(MSBuildThisFileDirectory)bin\\$(Configuration)</OutputPath>\n    <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>\n    <IncludeBuildOutput>false</IncludeBuildOutput>\n    <NoWarn>$(NoWarn);NU5100;NU5127;NU5128</NoWarn>\n    <!-- AsmResolver is not signed. -->\n    <SignAssembly>false</SignAssembly>\n    <DelaySign>false</DelaySign>\n    <!-- Fix error NU5017: Cannot create a package that has no dependencies nor content. -->\n    <IsPackable Condition=\"'$(IsFullPack)' == 'true'\">false</IsPackable>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <PackageReference Include=\"AsmResolver.DotNet\" Version=\"6.0.0-rc.1\" PrivateAssets=\"all\" />\n    <PackageReference Include=\"Microsoft.Build.Framework\" Version=\"18.0.2\" PrivateAssets=\"all\" />\n    <PackageReference Include=\"Microsoft.Build.Utilities.Core\" Version=\"18.0.2\" PrivateAssets=\"all\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <!-- Include .targets file and all DLLs in the output directory in the NuGet package -->\n    <Content Include=\"$(MSBuildThisFileDirectory)buildTransitive\\**\\*.targets\" Pack=\"true\" PackagePath=\"buildTransitive\" />\n    <Content Include=\"$(OutputPath)**\\*.dll\" Pack=\"true\" PackagePath=\"tasks/$(TargetFramework)\" />\n    <None Remove=\"packages\\**\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <PackageReference Include=\"PolySharp\" Version=\"1.15.0\">\n      <PrivateAssets>all</PrivateAssets>\n      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\n    </PackageReference>\n  </ItemGroup>\n\n  <Import Project=\"..\\..\\build\\common.targets\" />\n</Project>"
  },
  {
    "path": "src/BenchmarkDotNet.Weaver/buildTransitive/netstandard2.0/BenchmarkDotNet.Weaver.targets",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <UsingTask TaskName=\"BenchmarkDotNet.Weaver.WeaveAssemblyTask\" AssemblyFile=\"$(MSBuildThisFileDirectory)..\\..\\tasks\\netstandard2.0\\BenchmarkDotNet.Weaver.dll\" />\n\n  <PropertyGroup>\n    <BenchmarkDotNetShouldWeaveAssemblies Condition=\"'$(BenchmarkDotNetShouldWeaveAssemblies)' == ''\">true</BenchmarkDotNetShouldWeaveAssemblies>\n    <BenchmarkDotNetWeaveAssembliesAfterTargets Condition=\"'$(BenchmarkDotNetWeaveAssembliesAfterTargets)' == ''\">CoreCompile</BenchmarkDotNetWeaveAssembliesAfterTargets>\n    <BenchmarkDotNetWeaveAssembliesBeforeTargets Condition=\"'$(BenchmarkDotNetWeaveAssembliesBeforeTargets)' == ''\">CopyFilesToOutputDirectory</BenchmarkDotNetWeaveAssembliesBeforeTargets>\n    <BenchmarkDotNetWeaveAssemblyPath Condition=\"'$(BenchmarkDotNetWeaveAssemblyPath)' == ''\">$(IntermediateOutputPath)$(TargetName)$(TargetExt)</BenchmarkDotNetWeaveAssemblyPath>\n    <BenchmarkDotNetWeaveAssembliesStampFile Condition=\"'$(BenchmarkDotNetWeaveAssembliesStampFile)' == ''\">$(IntermediateOutputPath)BenchmarkDotNetWeaver.stamp</BenchmarkDotNetWeaveAssembliesStampFile>\n  </PropertyGroup>\n  \n  <Target Name=\"BenchmarkDotNetWeaveAssemblies\"\n      AfterTargets=\"$(BenchmarkDotNetWeaveAssembliesAfterTargets)\"\n      BeforeTargets=\"$(BenchmarkDotNetWeaveAssembliesBeforeTargets)\"\n      Condition=\"'$(BenchmarkDotNetShouldWeaveAssemblies)' == 'true'\"\n      Inputs=\"$(BenchmarkDotNetWeaveAssemblyPath)\"\n      Outputs=\"$(BenchmarkDotNetWeaveAssembliesStampFile)\">\n\n    <WeaveAssemblyTask TargetAssembly=\"$(BenchmarkDotNetWeaveAssemblyPath)\" ReferencePaths=\"@(ReferencePath)\"/>\n\n    <!-- Create stamp file for incrementality -->\n    <Touch Files=\"$(BenchmarkDotNetWeaveAssembliesStampFile)\" AlwaysCreate=\"true\" />\n    <ItemGroup>\n      <FileWrites Include=\"$(BenchmarkDotNetWeaveAssembliesStampFile)\" />\n    </ItemGroup>\n  </Target>\n</Project>"
  },
  {
    "path": "src/BenchmarkDotNet.Weaver/src/ReferencePathAssemblyResolver.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing AsmResolver.DotNet;\n\nnamespace BenchmarkDotNet.Weaver;\n\ninternal sealed class ReferencePathAssemblyResolver : IAssemblyResolver\n{\n    private readonly Dictionary<string, string> _referenceMap;\n\n    public ReferencePathAssemblyResolver(string[] referencePaths)\n    {\n        // Build a lookup: simpleName → fullPath\n        _referenceMap = new(StringComparer.OrdinalIgnoreCase);\n        foreach (var path in referencePaths)\n        {\n            var fileName = Path.GetFileNameWithoutExtension(path);\n            if (!string.IsNullOrEmpty(fileName))\n                _referenceMap[fileName] = path;\n        }\n    }\n\n    public ResolutionStatus Resolve(AssemblyDescriptor assembly, ModuleDefinition? originModule, out AssemblyDefinition? result)\n    {\n        if (!_referenceMap.TryGetValue(assembly.Name!.Value, out var fullPath) || !File.Exists(fullPath))\n        {\n            result = null;\n            return ResolutionStatus.AssemblyNotFound;\n        }\n\n        try\n        {\n            result = AssemblyDefinition.FromFile(fullPath, createRuntimeContext: false);\n            return ResolutionStatus.Success;\n        }\n        catch (BadImageFormatException)\n        {\n            result = null;\n            return ResolutionStatus.AssemblyBadImage;\n        }\n    }\n}\n"
  },
  {
    "path": "src/BenchmarkDotNet.Weaver/src/WeaveAssemblyTask.cs",
    "content": "// *****\n// If any changes are made to this file, increment the WeaverVersionSuffix in the common.props file,\n// then run `build.cmd pack-weaver`.\n// *****\n\nusing AsmResolver.DotNet;\nusing AsmResolver.PE.DotNet.Metadata.Tables;\nusing Microsoft.Build.Framework;\nusing Microsoft.Build.Utilities;\nusing System;\nusing System.IO;\nusing System.Linq;\n\nnamespace BenchmarkDotNet.Weaver;\n\n/// <summary>\n/// The Task used by MSBuild to weave the assembly.\n/// </summary>\npublic sealed class WeaveAssemblyTask : Task\n{\n    /// <summary>\n    /// The path of the target assembly.\n    /// </summary>\n    [Required]\n    public required string TargetAssembly { get; set; }\n\n    /// <summary>\n    /// The reference paths to search for assembly resolution.\n    /// </summary>\n    [Required]\n    public required string[] ReferencePaths { get; set; }\n\n    /// <summary>\n    /// Runs the weave assembly task.\n    /// </summary>\n    /// <returns><see langword=\"true\"/> if successful; <see langword=\"false\"/> otherwise.</returns>\n    public override bool Execute()\n    {\n        if (!File.Exists(TargetAssembly))\n        {\n            Log.LogError($\"TargetAssembly does not exist: {TargetAssembly}\");\n            return false;\n        }\n\n        bool benchmarkMethodsImplAdjusted = false;\n        try\n        {\n            var module = ModuleDefinition.FromFile(TargetAssembly, createRuntimeContext: false);\n            var runtimeContext = new RuntimeContext(module.OriginalTargetRuntime, new ReferencePathAssemblyResolver(ReferencePaths));\n            runtimeContext.AddAssembly(module.Assembly!);\n\n            foreach (var type in module.GetAllTypes())\n            {\n                // We can skip non-public types as they are not valid for benchmarks.\n                if (type.IsNotPublic)\n                {\n                    continue;\n                }\n\n                foreach (var method in type.Methods)\n                {\n                    if (method.CustomAttributes.Any(a => IsBenchmarkAttribute(a, runtimeContext)))\n                    {\n                        var oldImpl = method.ImplAttributes;\n                        // Remove AggressiveInlining and add NoInlining.\n                        method.ImplAttributes = (oldImpl & ~MethodImplAttributes.AggressiveInlining) | MethodImplAttributes.NoInlining;\n                        benchmarkMethodsImplAdjusted |= (oldImpl & MethodImplAttributes.NoInlining) == 0;\n                    }\n                }\n            }\n\n            if (benchmarkMethodsImplAdjusted)\n            {\n                // Write to a memory stream before overwriting the original file in case an exception occurs during the write (like unsupported platform).\n                // https://github.com/Washi1337/AsmResolver/issues/640\n                var memoryStream = new MemoryStream();\n                try\n                {\n                    module.Write(memoryStream);\n                    using var fileStream = new FileStream(TargetAssembly, FileMode.Truncate, FileAccess.Write);\n                    memoryStream.WriteTo(fileStream);\n                }\n                catch (OutOfMemoryException)\n                {\n                    // If there is not enough memory, fallback to write to null stream then write to file.\n                    memoryStream.Dispose();\n                    memoryStream = null;\n                    GC.Collect();\n                    module.Write(Stream.Null);\n                    module.Write(TargetAssembly);\n                }\n                finally\n                {\n                    memoryStream?.Dispose();\n                }\n            }\n        }\n        catch (Exception e)\n        {\n            Log.LogWarning($\"Assembly weaving failed. Benchmark methods found requiring NoInlining: {benchmarkMethodsImplAdjusted}. Error:{Environment.NewLine}{e}\");\n        }\n        return true;\n    }\n\n    private static bool IsBenchmarkAttribute(CustomAttribute attribute, RuntimeContext runtimeContext)\n    {\n        // BenchmarkAttribute is unsealed, so we need to walk its hierarchy.\n        for (var attr = attribute.Constructor!.DeclaringType; attr != null; attr = attr.Resolve(runtimeContext).BaseType)\n        {\n            if (attr.FullName == \"BenchmarkDotNet.Attributes.BenchmarkAttribute\")\n            {\n                return true;\n            }\n        }\n        return false;\n    }\n}"
  },
  {
    "path": "templates/BenchmarkDotNet.Templates.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n  <Import Project=\"..\\build\\common.props\" />\n  <PropertyGroup>\n    <PackageType>Template</PackageType>\n    <PackageId>BenchmarkDotNet.Templates</PackageId>\n    <Title>BenchmarkDotNet project templates</Title>\n    <Description>BenchmarkDotNet Templates</Description>\n    <PackageTags>benchmark;benchmarking;performance;templates;dotnet-new</PackageTags>\n    <TargetFramework>netstandard2.0</TargetFramework>\n\n    <IncludeContentInPack>true</IncludeContentInPack>\n    <IncludeBuildOutput>false</IncludeBuildOutput>\n    <ContentTargetFolders>content</ContentTargetFolders>\n\n    <SignAssembly>false</SignAssembly>\n    <PublicSign>false</PublicSign>\n\n    <!-- this package does not have any dependencies, avoid getting a NU5128 warning -->\n    <SuppressDependenciesWhenPacking>true</SuppressDependenciesWhenPacking>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <Content Include=\"templates\\**\\*\" Exclude=\"templates\\**\\bin\\**;templates\\**\\obj\\**\" />\n    <Compile Remove=\"**\\*\" />\n    <None Remove=\"*.bat;.sh\" />\n  </ItemGroup>\n\n  <Target Name=\"Fix BenchmarkDotNetVersion\"\n          BeforeTargets=\"Build\">\n    <ReplaceFileText\n            InputFilename=\"templates/BenchmarkDotNet.BenchmarkProjectTemplate.CSharp/.template.config/template.json\"\n            OutputFilename=\"templates/BenchmarkDotNet.BenchmarkProjectTemplate.CSharp/.template.config/template.json\"\n            MatchExpression='(\"defaultValue\": )\"([\\d+\\.?]+)\"'\n            ReplacementText='${1}\"$(VersionPrefix)\"' />\n\n    <ReplaceFileText\n            InputFilename=\"templates/BenchmarkDotNet.BenchmarkProjectTemplate.FSharp/.template.config/template.json\"\n            OutputFilename=\"templates/BenchmarkDotNet.BenchmarkProjectTemplate.FSharp/.template.config/template.json\"\n            MatchExpression='(\"defaultValue\": )\"([\\d+\\.?]+)\"'\n            ReplacementText='${1}\"$(VersionPrefix)\"' />\n\n    <ReplaceFileText\n            InputFilename=\"templates/BenchmarkDotNet.BenchmarkProjectTemplate.VB/.template.config/template.json\"\n            OutputFilename=\"templates/BenchmarkDotNet.BenchmarkProjectTemplate.VB/.template.config/template.json\"\n            MatchExpression='(\"defaultValue\": )\"([\\d+\\.?]+)\"'\n            ReplacementText='${1}\"$(VersionPrefix)\"' />\n  </Target>\n  <Import Project=\"..\\build\\common.targets\" />\n</Project>"
  },
  {
    "path": "templates/install-from-source.bat",
    "content": ":: Run only from the folder where the batch file is located!\n\ndotnet build BenchmarkDotNet.Templates.csproj -c Release\ndotnet pack BenchmarkDotNet.Templates.csproj -c Release\n\n:: If we install the templates via a folder path, then it will have a different ID (ID=folder path).\n:: It will conflict with BDN templates from nuget.\n:: We need to install the templates via a FILE path in order to update the template from nuget.\n::\n:: https://stackoverflow.com/questions/47450531/batch-write-output-of-dir-to-a-variable\nfor /f \"delims=\" %%a in ('dir /s /b BenchmarkDotNet.Templates*.nupkg') do set \"nupkg_path=%%a\"\n\ndotnet new --uninstall \"BenchmarkDotNet.Templates\"\ndotnet new --install \"%nupkg_path%\""
  },
  {
    "path": "templates/install-from-source.sh",
    "content": "# Run only from the folder where the shell script is located!\n\ndotnet build BenchmarkDotNet.Templates.csproj -c Release\ndotnet pack BenchmarkDotNet.Templates.csproj -c Release\n\n#  If we install the templates via a folder path, then it will have a different ID (ID=folder path).\n#  It will conflict with BDN templates from nuget.\n#  We need to install the templates via a FILE path in order to update the template from nuget.\n\nnupkg_path=$(find . -name \"BenchmarkDotNet.Templates*.nupkg\")\n\ndotnet new uninstall \"BenchmarkDotNet.Templates\"\ndotnet new install $nupkg_path\n"
  },
  {
    "path": "templates/templates/BenchmarkDotNet.BenchmarkProjectTemplate.CSharp/.template.config/dotnetcli.host.json",
    "content": "{\n  \"$schema\": \"http://json.schemastore.org/dotnetcli.host\",\n  \"symbolInfo\": {\n    \"skipRestore\": {\n      \"longName\": \"no-restore\",\n      \"shortName\": \"\"\n    },\n    \"consoleApp\": {\n      \"longName\": \"console-app\",\n      \"shortName\": \"\"\n    }\n  }\n}"
  },
  {
    "path": "templates/templates/BenchmarkDotNet.BenchmarkProjectTemplate.CSharp/.template.config/template.json",
    "content": "{\n  \"$schema\": \"http://json.schemastore.org/template\",\n  \"identity\": \"BenchmarkDotNet.BenchmarkProjectTemplate.CSharp\",\n  \"name\": \"Benchmark Project\",\n  \"shortName\": \"benchmark\",\n  \"groupIdentity\": \"BenchmarkDotNet\",\n  \"classifications\": [\n    \"Benchmark\",\n    \"Library\"\n  ],\n  \"precedence\": \"3000\",\n  \"tags\": {\n    \"language\": \"C#\",\n    \"type\": \"project\"\n  },\n  \"description\": \"A project template for creating benchmarks.\",\n  \"author\": \".NET Foundation and contributors\",\n  \"generatorVersions\": \"[1.0.0.0-*)\",\n\n  \"sourceName\": \"_BenchmarkProjectName_\",\n  \"preferNameDirectory\": true,\n  \"defaultName\": \"BenchmarkSuite\",\n  \"symbols\": {\n    \"benchmarkName\": {\n      \"type\": \"parameter\",\n      \"datatype\": \"string\",\n      \"description\": \"The name of the benchmark class.\",\n      \"defaultValue\": \"Benchmarks\",\n      \"FileRename\": \"_BenchmarkName_\",\n      \"replaces\": \"$(BenchmarkName)\"\n    },\n    \"framework\": {\n      \"type\": \"parameter\",\n      \"description\": \"The target framework for the project.\",\n      \"datatype\": \"choice\",\n      \"choices\": [\n        {\n          \"choice\": \"net11.0\",\n          \"description\": \".NET 11\"\n        },\n        {\n          \"choice\": \"net10.0\",\n          \"description\": \".NET 10\"\n        },\n        {\n          \"choice\": \"net9.0\",\n          \"description\": \".NET 9\"\n        },\n        {\n          \"choice\": \"net8.0\",\n          \"description\": \".NET 8\"\n        },\n        {\n          \"choice\": \"net7.0\",\n          \"description\": \".NET 7\"\n        },\n        {\n          \"choice\": \"net6.0\",\n          \"description\": \".NET 6\"\n        },\n        {\n          \"choice\": \"netstandard2.1\",\n          \"description\": \".NET Standard 2.1\"\n        },\n        {\n          \"choice\": \"netstandard2.0\",\n          \"description\": \".NET Standard 2.0\"\n        },\n        {\n          \"choice\": \"net481\",\n          \"description\": \".NET Framework 4.8.1\"\n        },\n        {\n          \"choice\": \"net48\",\n          \"description\": \".NET Framework 4.8\"\n        },\n        {\n          \"choice\": \"net472\",\n          \"description\": \".NET Framework 4.7.2\"\n        },\n        {\n          \"choice\": \"net471\",\n          \"description\": \".NET Framework 4.7.1\"\n        },\n        {\n          \"choice\": \"net47\",\n          \"description\": \".NET Framework 4.7\"\n        },\n        {\n          \"choice\": \"net462\",\n          \"description\": \".NET Framework 4.6.2\"\n        }\n      ],\n      \"defaultValue\": \"\"\n    },\n    \"frameworkDefault\": {\n      \"type\": \"generated\",\n      \"generator\": \"switch\",\n      \"description\": \"generate a default framework value based on consoleApp\",\n      \"parameters\": {\n        \"evaluator\": \"C++\",\n        \"datatype\": \"string\",\n        \"cases\": [\n          {\n            \"condition\": \"(consoleApp == true)\",\n            \"value\": \"net8.0\"\n          },\n          {\n            \"condition\": \"(consoleApp == false)\",\n            \"value\": \"netstandard2.0\"\n          }\n        ]\n      }\n    },\n    \"frameworkValue\": {\n      \"type\": \"generated\",\n      \"generator\": \"coalesce\",\n      \"parameters\": {\n        \"sourceVariableName\": \"framework\",\n        \"fallbackVariableName\": \"frameworkDefault\"\n      },\n      \"replaces\": \"$(Framework)\"\n    },\n    \"config\": {\n      \"type\": \"parameter\",\n      \"datatype\": \"bool\",\n      \"description\": \"Adds a benchmark config class.\",\n      \"defaultValue\": \"false\"\n    },\n    \"skipRestore\": {\n      \"type\": \"parameter\",\n      \"datatype\": \"bool\",\n      \"description\": \"If specified, skips the automatic restore of the project on create.\",\n      \"defaultValue\": \"false\"\n    },\n    \"consoleApp\": {\n      \"type\": \"parameter\",\n      \"datatype\": \"bool\",\n      \"description\": \"If specified, the project is set up as console app.\",\n      \"defaultValue\": \"true\"\n    },\n    \"version\": {\n      \"type\": \"parameter\",\n      \"datatype\": \"string\",\n      \"description\": \"Version of BenchmarkDotNet that will be referenced.\",\n      \"defaultValue\": \"0.16.0\",\n      \"replaces\": \"$(BenchmarkDotNetVersion)\"\n    }\n  },\n  \"sources\": [\n    {\n      \"source\": \"./\",\n      \"target\": \"./\",\n      \"exclude\": [\n        \".template.config/**\"\n      ],\n      \"modifiers\": [\n        {\n          \"condition\": \"(!config)\",\n          \"exclude\": [\n            \"BenchmarkConfig.cs\"\n          ]\n        },\n        {\n          \"condition\": \"(!consoleApp)\",\n          \"exclude\": [\n            \"Program.cs\"\n          ]\n        }\n      ]\n    }\n  ],\n  \"primaryOutputs\": [\n    {\n      \"path\": \"_BenchmarkProjectName_.csproj\"\n    }\n  ],\n  \"postActions\": [\n    {\n      \"condition\": \"(!skipRestore)\",\n      \"description\": \"Restore NuGet packages required by this project.\",\n      \"manualInstructions\": [\n        {\n          \"text\": \"Run 'dotnet restore'\"\n        }\n      ],\n      \"actionId\": \"210D431B-A78B-4D2F-B762-4ED3E3EA9025\",\n      \"continueOnError\": true\n    }\n  ]\n}\n"
  },
  {
    "path": "templates/templates/BenchmarkDotNet.BenchmarkProjectTemplate.CSharp/BenchmarkConfig.cs",
    "content": "using BenchmarkDotNet.Analysers;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Columns;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Exporters;\nusing BenchmarkDotNet.Exporters.Csv;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Loggers;\n\nnamespace _BenchmarkProjectName_\n{\n    public class BenchmarkConfig : ManualConfig\n    {\n        public BenchmarkConfig()\n        {\n            // Configure your benchmarks, see for more details: https://benchmarkdotnet.org/articles/configs/configs.html.\n            //Add(Job.Dry);\n            //Add(ConsoleLogger.Default);\n            //Add(TargetMethodColumn.Method, StatisticColumn.Max);\n            //Add(RPlotExporter.Default, CsvExporter.Default);\n            //Add(EnvironmentAnalyser.Default);\n        }\n    }\n}"
  },
  {
    "path": "templates/templates/BenchmarkDotNet.BenchmarkProjectTemplate.CSharp/Program.cs",
    "content": "using BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Running;\n\nnamespace _BenchmarkProjectName_\n{\n    public class Program\n    {\n        public static void Main(string[] args)\n        {\n            var config = DefaultConfig.Instance;\n            var summary = BenchmarkRunner.Run<$(BenchmarkName)>(config, args);\n\n            // Use this to select benchmarks from the console:\n            // var summaries = BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args, config);\n        }\n    }\n}"
  },
  {
    "path": "templates/templates/BenchmarkDotNet.BenchmarkProjectTemplate.CSharp/_BenchmarkName_.cs",
    "content": "﻿using System;\nusing BenchmarkDotNet;\nusing BenchmarkDotNet.Attributes;\n\nnamespace _BenchmarkProjectName_\n{\n#if(config)\n    [Config(typeof(BenchmarkConfig))]\n#endif\n    public class $(BenchmarkName)\n    {\n        [Benchmark]\n        public void Scenario1()\n        {\n            // Implement your benchmark here\n        }\n\n        [Benchmark]\n        public void Scenario2()\n        {\n            // Implement your benchmark here\n        }\n    }\n}\n"
  },
  {
    "path": "templates/templates/BenchmarkDotNet.BenchmarkProjectTemplate.CSharp/_BenchmarkProjectName_.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n  <PropertyGroup Condition=\"'$(consoleApp)' == 'true'\">\n    <TargetFramework>$(Framework)</TargetFramework>\n    <OutputType>Exe</OutputType>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(consoleApp)' == 'false'\">\n    <TargetFramework>$(Framework)</TargetFramework>\n </PropertyGroup>\n  <PropertyGroup>\n    <PlatformTarget>AnyCPU</PlatformTarget>\n    <DebugType>pdbonly</DebugType>\n    <DebugSymbols>true</DebugSymbols>\n    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>\n    <Optimize>true</Optimize>\n    <Configuration>Release</Configuration>\n    <IsPackable>false</IsPackable>\n  </PropertyGroup>\n  <ItemGroup>\n    <PackageReference Include=\"BenchmarkDotNet\" Version=\"$(BenchmarkDotNetVersion)\" />\n    <PackageReference Include=\"BenchmarkDotNet.Diagnostics.Windows\" Version=\"$(BenchmarkDotNetVersion)\" Condition=\"'$(OS)' == 'Windows_NT'\"/>\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "templates/templates/BenchmarkDotNet.BenchmarkProjectTemplate.FSharp/.template.config/dotnetcli.host.json",
    "content": "{\n  \"$schema\": \"http://json.schemastore.org/dotnetcli.host\",\n  \"symbolInfo\": {\n    \"skipRestore\": {\n      \"longName\": \"no-restore\",\n      \"shortName\": \"\"\n    },\n    \"consoleApp\": {\n      \"longName\": \"console-app\",\n      \"shortName\": \"\"\n    }\n  }\n}"
  },
  {
    "path": "templates/templates/BenchmarkDotNet.BenchmarkProjectTemplate.FSharp/.template.config/template.json",
    "content": "{\n  \"$schema\": \"http://json.schemastore.org/template\",\n  \"identity\": \"BenchmarkDotNet.BenchmarkProjectTemplate.FSharp\",\n  \"name\": \"Benchmark Project\",\n  \"shortName\": \"benchmark\",\n  \"groupIdentity\": \"BenchmarkDotNet\",\n  \"classifications\": [\n    \"Benchmark\",\n    \"Library\"\n  ],\n  \"precedence\": \"3000\",\n  \"tags\": {\n    \"language\": \"F#\",\n    \"type\": \"project\"\n  },\n  \"description\": \"A project template for creating benchmarks.\",\n  \"author\": \".NET Foundation and contributors\",\n  \"generatorVersions\": \"[1.0.0.0-*)\",\n\n  \"sourceName\": \"_BenchmarkProjectName_\",\n  \"preferNameDirectory\": true,\n  \"defaultName\": \"BenchmarkSuite\",\n  \"symbols\": {\n    \"benchmarkName\": {\n      \"type\": \"parameter\",\n      \"datatype\": \"string\",\n      \"description\": \"The name of the benchmark class.\",\n      \"defaultValue\": \"Benchmarks\",\n      \"FileRename\": \"_BenchmarkName_\",\n      \"replaces\": \"$(BenchmarkName)\"\n    },\n    \"framework\": {\n      \"type\": \"parameter\",\n      \"description\": \"The target framework for the project.\",\n      \"datatype\": \"choice\",\n      \"choices\": [\n        {\n          \"choice\": \"net11.0\",\n          \"description\": \".NET 11\"\n        },\n        {\n          \"choice\": \"net10.0\",\n          \"description\": \".NET 10\"\n        },\n        {\n          \"choice\": \"net9.0\",\n          \"description\": \".NET 9\"\n        },\n        {\n          \"choice\": \"net8.0\",\n          \"description\": \".NET 8\"\n        },\n        {\n          \"choice\": \"net7.0\",\n          \"description\": \".NET 7\"\n        },\n        {\n          \"choice\": \"net6.0\",\n          \"description\": \".NET 6\"\n        },\n        {\n          \"choice\": \"netstandard2.1\",\n          \"description\": \".NET Standard 2.1\"\n        },\n        {\n          \"choice\": \"netstandard2.0\",\n          \"description\": \".NET Standard 2.0\"\n        },\n        {\n          \"choice\": \"net481\",\n          \"description\": \".NET Framework 4.8.1\"\n        },\n        {\n          \"choice\": \"net48\",\n          \"description\": \".NET Framework 4.8\"\n        },\n        {\n          \"choice\": \"net472\",\n          \"description\": \".NET Framework 4.7.2\"\n        },\n        {\n          \"choice\": \"net471\",\n          \"description\": \".NET Framework 4.7.1\"\n        },\n        {\n          \"choice\": \"net47\",\n          \"description\": \".NET Framework 4.7\"\n        },\n        {\n          \"choice\": \"net462\",\n          \"description\": \".NET Framework 4.6.2\"\n        }\n      ],\n      \"defaultValue\": \"\"\n    },\n    \"frameworkDefault\": {\n      \"type\": \"generated\",\n      \"generator\": \"switch\",\n      \"description\": \"generate a default framework value based on consoleApp\",\n      \"parameters\": {\n        \"evaluator\": \"C++\",\n        \"datatype\": \"string\",\n        \"cases\": [\n          {\n            \"condition\": \"(consoleApp == true)\",\n            \"value\": \"net8.0\"\n          },\n          {\n            \"condition\": \"(consoleApp == false)\",\n            \"value\": \"netstandard2.0\"\n          }\n        ]\n      }\n    },\n    \"frameworkValue\": {\n      \"type\": \"generated\",\n      \"generator\": \"coalesce\",\n      \"parameters\": {\n        \"sourceVariableName\": \"framework\",\n        \"fallbackVariableName\": \"frameworkDefault\"\n      },\n      \"replaces\": \"$(Framework)\"\n    },\n    \"config\": {\n      \"type\": \"parameter\",\n      \"datatype\": \"bool\",\n      \"description\": \"Adds a benchmark config class.\",\n      \"defaultValue\": \"false\"\n    },\n    \"skipRestore\": {\n      \"type\": \"parameter\",\n      \"datatype\": \"bool\",\n      \"description\": \"If specified, skips the automatic restore of the project on create.\",\n      \"defaultValue\": \"false\"\n    },\n    \"consoleApp\": {\n      \"type\": \"parameter\",\n      \"datatype\": \"bool\",\n      \"description\": \"If specified, the project is set up as console app.\",\n      \"defaultValue\": \"true\"\n    },\n    \"version\": {\n      \"type\": \"parameter\",\n      \"datatype\": \"string\",\n      \"description\": \"Version of BenchmarkDotNet that will be referenced.\",\n      \"defaultValue\": \"0.16.0\",\n      \"replaces\": \"$(BenchmarkDotNetVersion)\"\n    }\n  },\n  \"sources\": [\n    {\n      \"source\": \"./\",\n      \"target\": \"./\",\n      \"exclude\": [\n        \".template.config/**\"\n      ],\n      \"modifiers\": [\n        {\n          \"condition\": \"(!config)\",\n          \"exclude\": [\n            \"BenchmarkConfig.fs\"\n          ]\n        },\n        {\n          \"condition\": \"(!consoleApp)\",\n          \"exclude\": [\n            \"Program.fs\"\n          ]\n        }\n      ]\n    }\n  ],\n  \"primaryOutputs\": [\n    {\n      \"path\": \"_BenchmarkProjectName_.fsproj\"\n    }\n  ],\n  \"postActions\": [\n    {\n      \"condition\": \"(!skipRestore)\",\n      \"description\": \"Restore NuGet packages required by this project.\",\n      \"manualInstructions\": [\n        {\n          \"text\": \"Run 'dotnet restore'\"\n        }\n      ],\n      \"actionId\": \"210D431B-A78B-4D2F-B762-4ED3E3EA9025\",\n      \"continueOnError\": true\n    }\n  ]\n}\n"
  },
  {
    "path": "templates/templates/BenchmarkDotNet.BenchmarkProjectTemplate.FSharp/BenchmarkConfig.fs",
    "content": "module Configs \n\nopen BenchmarkDotNet.Configs\nopen BenchmarkDotNet.Diagnosers\nopen BenchmarkDotNet.Exporters\nopen BenchmarkDotNet.Validators\n\ntype BenchmarkConfig() as self =\n\n    // Configure your benchmarks, see for more details: https://benchmarkdotnet.org/articles/configs/configs.html.\n    inherit ManualConfig() \n    do\n        self\n            .With(MemoryDiagnoser.Default)\n            .With(MarkdownExporter.GitHub)\n            .With(ExecutionValidator.FailOnError)\n            |> ignore\n"
  },
  {
    "path": "templates/templates/BenchmarkDotNet.BenchmarkProjectTemplate.FSharp/Program.fs",
    "content": "﻿open System\nopen BenchmarkDotNet.Running\nopen _BenchmarkProjectName_\n\n[<EntryPoint>]\nlet main argv =\n    BenchmarkRunner.Run<$(BenchmarkName)>() |> ignore\n    0 // return an integer exit code"
  },
  {
    "path": "templates/templates/BenchmarkDotNet.BenchmarkProjectTemplate.FSharp/_BenchmarkName_.fs",
    "content": "﻿module _BenchmarkProjectName_ \n\nopen System\nopen BenchmarkDotNet\nopen BenchmarkDotNet.Attributes\n\n#if config\n[<Config(typedefof<Configs.BenchmarkConfig>)>]\n#endif\ntype $(BenchmarkName) () =\n    [<Params(0, 1, 15, 100)>]\n    member val public sleepTime = 0 with get, set\n\n    // [<GlobalSetup>]\n    // member self.GlobalSetup() =\n    //     printfn \"%s\" \"Global Setup\"\n\n    // [<GlobalCleanup>]\n    // member self.GlobalCleanup() =\n    //     printfn \"%s\" \"Global Cleanup\"\n\n    // [<IterationSetup>]\n    // member self.IterationSetup() =\n    //     printfn \"%s\" \"Iteration Setup\"\n    \n    // [<IterationCleanup>]\n    // member self.IterationCleanup() =\n    //     printfn \"%s\" \"Iteration Cleanup\"\n\n    [<Benchmark>]\n    member this.Thread () = System.Threading.Thread.Sleep(this.sleepTime)\n\n    [<Benchmark>]\n    member this.Task () = System.Threading.Tasks.Task.Delay(this.sleepTime)\n\n    [<Benchmark>]\n    member this.AsyncToTask () = Async.Sleep(this.sleepTime) |> Async.StartAsTask\n\n    [<Benchmark>]\n    member this.AsyncToSync () = Async.Sleep(this.sleepTime) |> Async.RunSynchronously\n\n\n"
  },
  {
    "path": "templates/templates/BenchmarkDotNet.BenchmarkProjectTemplate.FSharp/_BenchmarkProjectName_.fsproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\n  <PropertyGroup Condition=\"'$(consoleApp)' == 'true'\">\n    <TargetFramework>$(Framework)</TargetFramework>\n    <OutputType>Exe</OutputType>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(consoleApp)' == 'false'\">\n    <TargetFramework>$(Framework)</TargetFramework>\n  </PropertyGroup>\n  <PropertyGroup>\n    <PlatformTarget>AnyCPU</PlatformTarget>\n    <DebugType>pdbonly</DebugType>\n    <DebugSymbols>true</DebugSymbols>\n    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>\n    <Optimize>true</Optimize>\n    <Configuration>Release</Configuration>\n    <IsPackable>false</IsPackable>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)'=='Release'\">\n    <Tailcalls>true</Tailcalls>\n  </PropertyGroup>\n  <ItemGroup>\n    <PackageReference Include=\"BenchmarkDotNet\" Version=\"$(BenchmarkDotNetVersion)\" />\n    <PackageReference Include=\"BenchmarkDotNet.Diagnostics.Windows\" Version=\"$(BenchmarkDotNetVersion)\" Condition=\"'$(OS)' == 'Windows_NT'\"/>\n  </ItemGroup>\n  <ItemGroup Condition=\"'$(config)' == true\">\n    <Compile Include=\"BenchmarkConfig.fs\" />\n  </ItemGroup>\n  <ItemGroup>\n    <Compile Include=\"$(BenchmarkName).fs\" />\n  </ItemGroup>\n  <ItemGroup Condition=\"'$(consoleApp)' == true\">\n    <Compile Include=\"Program.fs\" />\n  </ItemGroup>\n</Project>\n"
  },
  {
    "path": "templates/templates/BenchmarkDotNet.BenchmarkProjectTemplate.VB/.template.config/dotnetcli.host.json",
    "content": "{\n  \"$schema\": \"http://json.schemastore.org/dotnetcli.host\",\n  \"symbolInfo\": {\n    \"skipRestore\": {\n      \"longName\": \"no-restore\",\n      \"shortName\": \"\"\n    },\n    \"consoleApp\": {\n      \"longName\": \"console-app\",\n      \"shortName\": \"\"\n    }\n  }\n}"
  },
  {
    "path": "templates/templates/BenchmarkDotNet.BenchmarkProjectTemplate.VB/.template.config/template.json",
    "content": "{\n  \"$schema\": \"http://json.schemastore.org/template\",\n  \"identity\": \"BenchmarkDotNet.BenchmarkProjectTemplate.VB\",\n  \"name\": \"Benchmark Project\",\n  \"shortName\": \"benchmark\",\n  \"groupIdentity\": \"BenchmarkDotNet\",\n  \"classifications\": [\n    \"Benchmark\",\n    \"Library\"\n  ],\n  \"precedence\": \"3000\",\n  \"tags\": {\n    \"language\": \"VB\",\n    \"type\": \"project\"\n  },\n  \"description\": \"A project template for creating benchmarks.\",\n  \"author\": \".NET Foundation and contributors\",\n  \"generatorVersions\": \"[1.0.0.0-*)\",\n\n  \"sourceName\": \"_BenchmarkProjectName_\",\n  \"preferNameDirectory\": true,\n  \"defaultName\": \"BenchmarkSuite\",\n  \"symbols\": {\n    \"benchmarkName\": {\n      \"type\": \"parameter\",\n      \"datatype\": \"string\",\n      \"description\": \"The name of the benchmark class.\",\n      \"defaultValue\": \"Benchmarks\",\n      \"FileRename\": \"_BenchmarkName_\",\n      \"replaces\": \"$(BenchmarkName)\"\n    },\n    \"framework\": {\n      \"type\": \"parameter\",\n      \"description\": \"The target framework for the project.\",\n      \"datatype\": \"choice\",\n      \"choices\": [\n        {\n          \"choice\": \"net11.0\",\n          \"description\": \".NET 11\"\n        },\n        {\n          \"choice\": \"net10.0\",\n          \"description\": \".NET 10\"\n        },\n        {\n          \"choice\": \"net9.0\",\n          \"description\": \".NET 9\"\n        },\n        {\n          \"choice\": \"net8.0\",\n          \"description\": \".NET 8\"\n        },\n        {\n          \"choice\": \"net7.0\",\n          \"description\": \".NET 7\"\n        },\n        {\n          \"choice\": \"net6.0\",\n          \"description\": \".NET 6\"\n        },\n        {\n          \"choice\": \"netstandard2.1\",\n          \"description\": \".NET Standard 2.1\"\n        },\n        {\n          \"choice\": \"netstandard2.0\",\n          \"description\": \".NET Standard 2.0\"\n        },\n        {\n          \"choice\": \"net481\",\n          \"description\": \".NET Framework 4.8.1\"\n        },\n        {\n          \"choice\": \"net48\",\n          \"description\": \".NET Framework 4.8\"\n        },\n        {\n          \"choice\": \"net472\",\n          \"description\": \".NET Framework 4.7.2\"\n        },\n        {\n          \"choice\": \"net471\",\n          \"description\": \".NET Framework 4.7.1\"\n        },\n        {\n          \"choice\": \"net47\",\n          \"description\": \".NET Framework 4.7\"\n        },\n        {\n          \"choice\": \"net462\",\n          \"description\": \".NET Framework 4.6.2\"\n        }\n      ],\n      \"defaultValue\": \"\"\n    },\n    \"frameworkDefault\": {\n      \"type\": \"generated\",\n      \"generator\": \"switch\",\n      \"description\": \"generate a default framework value based on consoleApp\",\n      \"parameters\": {\n        \"evaluator\": \"C++\",\n        \"datatype\": \"string\",\n        \"cases\": [\n          {\n            \"condition\": \"(consoleApp == true)\",\n            \"value\": \"net8.0\"\n          },\n          {\n            \"condition\": \"(consoleApp == false)\",\n            \"value\": \"netstandard2.0\"\n          }\n        ]\n      }\n    },\n    \"frameworkValue\": {\n      \"type\": \"generated\",\n      \"generator\": \"coalesce\",\n      \"parameters\": {\n        \"sourceVariableName\": \"framework\",\n        \"fallbackVariableName\": \"frameworkDefault\"\n      },\n      \"replaces\": \"$(Framework)\"\n    },\n    \"config\": {\n      \"type\": \"parameter\",\n      \"datatype\": \"bool\",\n      \"description\": \"Adds a benchmark config class.\",\n      \"defaultValue\": \"false\"\n    },\n    \"skipRestore\": {\n      \"type\": \"parameter\",\n      \"datatype\": \"bool\",\n      \"description\": \"If specified, skips the automatic restore of the project on create.\",\n      \"defaultValue\": \"false\"\n    },\n    \"consoleApp\": {\n      \"type\": \"parameter\",\n      \"datatype\": \"bool\",\n      \"description\": \"If specified, the project is set up as console app.\",\n      \"defaultValue\": \"true\"\n    },\n    \"version\": {\n      \"type\": \"parameter\",\n      \"datatype\": \"string\",\n      \"description\": \"Version of BenchmarkDotNet that will be referenced.\",\n      \"defaultValue\": \"0.16.0\",\n      \"replaces\": \"$(BenchmarkDotNetVersion)\"\n    }\n  },\n  \"sources\": [\n    {\n      \"source\": \"./\",\n      \"target\": \"./\",\n      \"exclude\": [\n        \".template.config/**\"\n      ],\n      \"modifiers\": [\n        {\n          \"condition\": \"(!config)\",\n          \"exclude\": [\n            \"BenchmarkConfig.vb\"\n          ]\n        },\n        {\n          \"condition\": \"(!consoleApp)\",\n          \"exclude\": [\n            \"Program.vb\"\n          ]\n        }\n      ]\n    }\n  ],\n  \"primaryOutputs\": [\n    {\n      \"path\": \"_BenchmarkProjectName_.vbproj\"\n    }\n  ],\n  \"postActions\": [\n    {\n      \"condition\": \"(!skipRestore)\",\n      \"description\": \"Restore NuGet packages required by this project.\",\n      \"manualInstructions\": [\n        {\n          \"text\": \"Run 'dotnet restore'\"\n        }\n      ],\n      \"actionId\": \"210D431B-A78B-4D2F-B762-4ED3E3EA9025\",\n      \"continueOnError\": true\n    }\n  ]\n}\n"
  },
  {
    "path": "templates/templates/BenchmarkDotNet.BenchmarkProjectTemplate.VB/BenchmarkConfig.vb",
    "content": "Imports BenchmarkDotNet.Analysers\nImports BenchmarkDotNet.Attributes\nImports BenchmarkDotNet.Columns\nImports BenchmarkDotNet.Configs\nImports BenchmarkDotNet.Exporters\nImports BenchmarkDotNet.Exporters.Csv\nImports BenchmarkDotNet.Jobs\nImports BenchmarkDotNet.Loggers\n\nNamespace _BenchmarkProjectName_\n    Public Class BenchmarkConfig\n        Inherits ManualConfig\n\n        Public Sub New()\n            ' Configure your benchmarks, see for more details: https://benchmarkdotnet.org/articles/configs/configs.html.\n            ' Add(Job.Dry);\n            ' Add(ConsoleLogger.Default);\n            ' Add(TargetMethodColumn.Method, StatisticColumn.Max);\n            ' Add(RPlotExporter.Default, CsvExporter.Default);\n            ' Add(EnvironmentAnalyser.Default);\n        End Sub\n    End Class\nEnd Namespace\n"
  },
  {
    "path": "templates/templates/BenchmarkDotNet.BenchmarkProjectTemplate.VB/Program.vb",
    "content": "Imports System\nImports BenchmarkDotNet.Running\n\nNamespace _BenchmarkProjectName_\n    Module Program\n        Sub Main(args As String())\n            Dim summary = BenchmarkRunner.Run(Of $(BenchmarkName))()\n        End Sub\n    End Module\nEnd Namespace\n"
  },
  {
    "path": "templates/templates/BenchmarkDotNet.BenchmarkProjectTemplate.VB/_BenchmarkName_.vb",
    "content": "﻿Imports System\nImports BenchmarkDotNet\nImports BenchmarkDotNet.Attributes\n\nNamespace _BenchmarkProjectName_\n\n#If config Then\n    <Config(GetType(BenchmarkConfig))>\n#End If\n    Public Class $(BenchmarkName)\n        <Benchmark>\n        Public Sub Scenario1()\n        \n        ' Implement your benchmark here\n\n        End Sub\n\n        <Benchmark>\n        Public Sub Scenario2()\n        \n        ' Implement your benchmark here\n\n        End Sub\n    End Class\nEnd Namespace"
  },
  {
    "path": "templates/templates/BenchmarkDotNet.BenchmarkProjectTemplate.VB/_BenchmarkProjectName_.vbproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n  <PropertyGroup Condition=\"'$(consoleApp)' == 'true'\">\n    <TargetFramework>$(Framework)</TargetFramework>\n    <OutputType>Exe</OutputType>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(consoleApp)' == 'false'\">\n    <TargetFramework>$(Framework)</TargetFramework>\n  </PropertyGroup>\n  <PropertyGroup>\n    <PlatformTarget>AnyCPU</PlatformTarget>\n    <DebugType>pdbonly</DebugType>\n    <DebugSymbols>true</DebugSymbols>\n    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>\n    <Optimize>true</Optimize>\n    <Configuration>Release</Configuration>\n    <IsPackable>false</IsPackable>\n  </PropertyGroup>\n  <ItemGroup>\n    <PackageReference Include=\"BenchmarkDotNet\" Version=\"$(BenchmarkDotNetVersion)\" />\n    <PackageReference Include=\"BenchmarkDotNet.Diagnostics.Windows\" Version=\"$(BenchmarkDotNetVersion)\" Condition=\"'$(OS)' == 'Windows_NT'\"/>\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "tests/BenchmarkDotNet.Analyzers.Tests/AnalyzerTests/Attributes/ArgumentsAttributeAnalyzerTests.cs",
    "content": "﻿using BenchmarkDotNet.Analyzers.Attributes;\r\nusing BenchmarkDotNet.Analyzers.Tests.Fixtures;\r\nusing Microsoft.CodeAnalysis.CSharp;\r\nusing System.Collections.Generic;\r\nusing System.Linq;\r\nusing System.Threading.Tasks;\r\nusing Xunit;\r\n\r\nnamespace BenchmarkDotNet.Analyzers.Tests.AnalyzerTests.Attributes;\r\n\r\npublic class ArgumentsAttributeAnalyzerTests\r\n{\r\n    public class RequiresParameters : AnalyzerTestFixture<ArgumentsAttributeAnalyzer>\r\n    {\r\n        public RequiresParameters() : base(ArgumentsAttributeAnalyzer.RequiresParametersRule) { }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task A_method_annotated_with_an_arguments_attribute_and_the_benchmark_attribute_and_having_no_parameters_should_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(ArgumentsAttributeUsagesWithLocationMarker))] string emptyArgumentsAttributeUsage)\r\n        {\r\n            const string benchmarkMethodName = \"BenchmarkMethod\";\r\n\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [Benchmark]\r\n                    {{emptyArgumentsAttributeUsage}}\r\n                    public void {{benchmarkMethodName}}()\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n\r\n            AddDefaultExpectedDiagnostic(benchmarkMethodName);\r\n            await RunAsync();\r\n        }\r\n\r\n        public static IEnumerable<string> ArgumentsAttributeUsagesWithLocationMarker()\r\n        {\r\n            yield return \"[{|#0:Arguments|}]\";\r\n            yield return \"[{|#0:Arguments()|}]\";\r\n            yield return \"[{|#0:Arguments(Priority = 1)|}]\";\r\n\r\n            string[] nameColonUsages =\r\n            [\r\n                \"\",\r\n                \"values: \"\r\n            ];\r\n\r\n            string[] priorityNamedParameterUsages =\r\n            [\r\n                \"\",\r\n                \", Priority = 1\"\r\n            ];\r\n\r\n            string[] attributeUsagesBase =\r\n            [\r\n                \"Arguments({0}new object[] {{ }}{1})\",\r\n                \"Arguments({0}new object[0]{1})\",\r\n                \"Arguments({0}[]{1})\",\r\n                \"Arguments({0}new object[] {{ 1, 2 }}{1})\",\r\n                \"Arguments({0}[1, 2]{1})\",\r\n            ];\r\n\r\n            foreach (var attributeUsageBase in attributeUsagesBase)\r\n            {\r\n                foreach (var nameColonUsage in nameColonUsages)\r\n                {\r\n                    foreach (var priorityNamedParameterUsage in priorityNamedParameterUsages)\r\n                    {\r\n                        yield return $\"[{{|#0:{string.Format(attributeUsageBase, nameColonUsage, priorityNamedParameterUsage)}|}}]\";\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    public class RequiresBenchmarkAttribute : AnalyzerTestFixture<ArgumentsAttributeAnalyzer>\r\n    {\r\n        public RequiresBenchmarkAttribute() : base(ArgumentsAttributeAnalyzer.RequiresBenchmarkAttributeRule) { }\r\n\r\n        [Theory]\r\n        [MemberData(nameof(ArgumentAttributeUsagesListLength))]\r\n        public async Task A_method_annotated_with_at_least_one_arguments_attribute_together_with_the_benchmark_attribute_should_not_trigger_diagnostic(int argumentAttributeUsagesListLength)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [Benchmark]\r\n                    [{{string.Join(\"]\\n[\", ArgumentAttributeUsages.Take(argumentAttributeUsagesListLength))}}]\r\n                    public void BenchmarkMethod()\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory]\r\n        [MemberData(nameof(ArgumentAttributeUsagesListLength))]\r\n        public async Task A_method_with_at_least_one_arguments_attribute_but_no_benchmark_attribute_should_trigger_diagnostic(int argumentAttributeUsagesListLength)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    {{string.Join(\"\\n\", ArgumentAttributeUsages.Take(argumentAttributeUsagesListLength).Select((a, i) => $\"[{{|#{i}:{a}|}}]\"))}}\r\n                    public void BenchmarkMethod()\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n\r\n            for (var i = 0; i < argumentAttributeUsagesListLength; i++)\r\n            {\r\n                AddExpectedDiagnostic(i);\r\n            }\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        public static TheoryData<int> ArgumentAttributeUsagesListLength => [.. Enumerable.Range(1, ArgumentAttributeUsages.Count)];\r\n\r\n        private static IReadOnlyCollection<string> ArgumentAttributeUsages =>\r\n        [\r\n            \"Arguments\",\r\n            \"Arguments()\",\r\n            \"Arguments(42, \\\"test\\\")\"\r\n        ];\r\n    }\r\n\r\n    public class MustHaveMatchingValueCount : AnalyzerTestFixture<ArgumentsAttributeAnalyzer>\r\n    {\r\n        public MustHaveMatchingValueCount() : base(ArgumentsAttributeAnalyzer.MustHaveMatchingValueCountRule) { }\r\n\r\n        [Fact]\r\n        public async Task A_method_not_annotated_with_any_arguments_attributes_should_not_trigger_diagnostic()\r\n        {\r\n            const string testCode = /* lang=c#-test */ \"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [Benchmark]\r\n                    public void BenchmarkMethod()\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory]\r\n        [MemberData(nameof(ArgumentsAttributeUsages))]\r\n        public async Task Having_a_matching_value_count_should_not_trigger_diagnostic(string argumentsAttributeUsage)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [Benchmark]\r\n                    {{argumentsAttributeUsage}}\r\n                    public void BenchmarkMethod(string a, bool b)\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory]\r\n        [MemberData(nameof(EmptyArgumentsAttributeUsagesWithLocationMarker))]\r\n        public async Task Having_a_mismatching_empty_value_count_targeting_a_method_with_parameters_should_trigger_diagnostic(string argumentsAttributeUsage)\r\n        {\r\n            const string benchmarkMethodName = \"BenchmarkMethod\";\r\n\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [Benchmark]\r\n                    {{argumentsAttributeUsage}}\r\n                    public void {{benchmarkMethodName}}(string a)\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n            TestCode = testCode;\r\n            AddDefaultExpectedDiagnostic(1, \"\", benchmarkMethodName, 0);\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Having_a_mismatching_value_count_should_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(ArgumentsAttributeUsagesWithLocationMarker))] string argumentsAttributeUsage)\r\n        {\r\n            const string benchmarkMethodName = \"BenchmarkMethod\";\r\n\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [Benchmark]\r\n                    {{argumentsAttributeUsage}}\r\n                    public void {{benchmarkMethodName}}(string a)\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n            TestCode = testCode;\r\n            AddExpectedDiagnostic(0, 1, \"\", benchmarkMethodName, 2);\r\n            AddExpectedDiagnostic(1, 1, \"\", benchmarkMethodName, 3);\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        public static TheoryData<string> ArgumentsAttributeUsages()\r\n        {\r\n            return [.. GenerateData().Distinct()];\r\n\r\n            static IEnumerable<string> GenerateData()\r\n            {\r\n                string[] nameColonUsages =\r\n                [\r\n                    \"\",\r\n                    \"values: \"\r\n                ];\r\n\r\n                string[] priorityNamedParameterUsages =\r\n                [\r\n                    \"\",\r\n                    \", Priority = 1\"\r\n                ];\r\n\r\n                string[] attributeUsagesBase =\r\n                [\r\n                    \"[Arguments({1}{2})]\",\r\n                    \"[Arguments({0}new object[] {{ {1} }}{2})]\",\r\n                    \"[Arguments({0}[ {1} ]{2})]\"\r\n                ];\r\n\r\n                string[] valueLists =\r\n                [\r\n                    \"42, \\\"test\\\"\",\r\n                    \"\\\"value\\\", 100\"\r\n                ];\r\n\r\n                foreach (var attributeUsageBase in attributeUsagesBase)\r\n                {\r\n                    foreach (var nameColonUsage in nameColonUsages)\r\n                    {\r\n                        foreach (var priorityNamedParameterUsage in priorityNamedParameterUsages)\r\n                        {\r\n                            yield return string.Join(\"\\n    \", valueLists.Select(vv => string.Format(attributeUsageBase, nameColonUsage, vv, priorityNamedParameterUsage)));\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        public static TheoryData<string> EmptyArgumentsAttributeUsagesWithLocationMarker()\r\n        {\r\n            return [.. GenerateData()];\r\n\r\n            static IEnumerable<string> GenerateData()\r\n            {\r\n                yield return \"[{|#0:Arguments|}]\";\r\n                yield return \"[{|#0:Arguments()|}]\";\r\n                yield return \"[{|#0:Arguments(Priority = 1)|}]\";\r\n\r\n                string[] nameColonUsages =\r\n                [\r\n                    \"\",\r\n                    \"values: \"\r\n                ];\r\n\r\n                string[] priorityNamedParameterUsages =\r\n                [\r\n                    \"\",\r\n                    \", Priority = 1\"\r\n                ];\r\n\r\n                string[] attributeUsagesBase =\r\n                [\r\n                    \"Arguments({0}new object[] {{ }}{1})\",\r\n                    \"Arguments({0}new object[0]{1})\",\r\n                    \"Arguments({0}[]{1})\",\r\n                ];\r\n\r\n                foreach (var attributeUsageBase in attributeUsagesBase)\r\n                {\r\n                    foreach (var nameColonUsage in nameColonUsages)\r\n                    {\r\n                        foreach (var priorityNamedParameterUsage in priorityNamedParameterUsages)\r\n                        {\r\n                            yield return $\"[{{|#0:{string.Format(attributeUsageBase, nameColonUsage, priorityNamedParameterUsage)}|}}]\";\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        public static IEnumerable<string> ArgumentsAttributeUsagesWithLocationMarker()\r\n        {\r\n            string[] nameColonUsages =\r\n            [\r\n                \"\",\r\n                \"values: \"\r\n            ];\r\n\r\n            string[] priorityNamedParameterUsages =\r\n            [\r\n                \"\",\r\n                \", Priority = 1\"\r\n            ];\r\n\r\n            string[] attributeUsagesBase =\r\n            [\r\n                \"Arguments({1}{2})\",\r\n                \"Arguments({0}new object[] {{ {1} }}{2})\",\r\n                \"Arguments({0}[ {1} ]{2})\"\r\n            ];\r\n\r\n            string[] valueLists =\r\n            [\r\n                \"42, \\\"test\\\"\",\r\n                \"\\\"value\\\", 100, false\"\r\n            ];\r\n\r\n            foreach (var attributeUsageBase in attributeUsagesBase)\r\n            {\r\n                foreach (var nameColonUsage in nameColonUsages)\r\n                {\r\n                    foreach (var priorityNamedParameterUsage in priorityNamedParameterUsages)\r\n                    {\r\n                        yield return string.Join(\"\\n    \", valueLists.Select((vv, i) => $\"[{{|#{i}:{string.Format(attributeUsageBase, nameColonUsage, vv, priorityNamedParameterUsage)}|}}]\"));\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    public class MustHaveMatchingValueType : AnalyzerTestFixture<ArgumentsAttributeAnalyzer>\r\n    {\r\n        public MustHaveMatchingValueType() : base(ArgumentsAttributeAnalyzer.MustHaveMatchingValueTypeRule) { }\r\n\r\n        [Fact]\r\n        public async Task A_method_not_annotated_with_any_arguments_attributes_should_not_trigger_diagnostic()\r\n        {\r\n            const string testCode = /* lang=c#-test */ \"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [Benchmark]\r\n                    public void BenchmarkMethod()\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Analyzing_an_arguments_attribute_should_not_throw_an_inconsistent_language_versions_exception(\r\n            [CombinatorialMemberData(nameof(DummyAttributeUsage))] string dummyAttributeUsage,\r\n            [CombinatorialMemberData(nameof(ScalarValuesContainerAttributeArgumentEnumerableLocal))] string scalarValuesContainerAttributeArgument)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [Benchmark]\r\n                    [{{dummyAttributeUsage}}{{string.Format(scalarValuesContainerAttributeArgument, \"42\")}}]\r\n                    public void BenchmarkMethod(int a)\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceDummyAttribute();\r\n            ReferenceDummyEnum();\r\n            SetParseOptions(LanguageVersion.CSharp14);\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Analyzing_an_arguments_attribute_should_not_throw_an_inconsistent_syntax_tree_features_exception(\r\n            [CombinatorialMemberData(nameof(DummyAttributeUsage))] string dummyAttributeUsage,\r\n            [CombinatorialMemberData(nameof(ScalarValuesContainerAttributeArgumentEnumerableLocal))] string scalarValuesContainerAttributeArgument)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [Benchmark]\r\n                    [{{dummyAttributeUsage}}{{string.Format(scalarValuesContainerAttributeArgument, \"42\")}}]\r\n                    public void BenchmarkMethod(int a)\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceDummyAttribute();\r\n            ReferenceDummyEnum();\r\n            SetParseOptions(LanguageVersion.Default, true);\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory]\r\n        [MemberData(nameof(EmptyArgumentsAttributeUsagesWithMismatchingValueCount))]\r\n        public async Task Having_a_mismatching_value_count_with_empty_argument_attribute_usages_should_not_trigger_diagnostic(string argumentsAttributeUsage)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n                public class BenchmarkClass\r\n                {\r\n                    [Benchmark]\r\n                    {{argumentsAttributeUsage}}\r\n                    public void BenchmarkMethod(string a)\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n            TestCode = testCode;\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Having_a_mismatching_value_count_with_nonempty_argument_attribute_usages_should_not_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(ScalarValuesContainerAttributeArgumentEnumerableLocal))] string scalarValuesContainerAttributeArgument,\r\n            [CombinatorialValues(\"string a\", \"\")] string parameters)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n                public class BenchmarkClass\r\n                {\r\n                    [Benchmark]\r\n                    [{{string.Format(scalarValuesContainerAttributeArgument, \"\"\"\r\n                                                                                42, \"test\"\r\n                                                                                \"\"\")}}]\r\n                    [{{string.Format(scalarValuesContainerAttributeArgument, \"\"\"\r\n                                                                                \"value\", 100, true\r\n                                                                                \"\"\")}}]\r\n                    public void BenchmarkMethod({{parameters}})\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n            TestCode = testCode;\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Providing_an_unknown_value_type_should_not_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(DummyAttributeUsage))] string dummyAttributeUsage,\r\n            [CombinatorialMemberData(nameof(ScalarValuesContainerAttributeArgumentEnumerableLocal))] string scalarValuesContainerAttributeArgument)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [Benchmark]\r\n                    [{{dummyAttributeUsage}}{{string.Format(scalarValuesContainerAttributeArgument, \"dummy_literal, true\")}}]\r\n                    public void BenchmarkMethod(byte a, bool b)\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceDummyAttribute();\r\n\r\n            DisableCompilerDiagnostics();\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Providing_an_unknown_type_in_typeof_expression_should_not_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(DummyAttributeUsage))] string dummyAttributeUsage,\r\n            [CombinatorialMemberData(nameof(ScalarValuesContainerAttributeArgumentEnumerableLocal))] string scalarValuesContainerAttributeArgument)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [Benchmark]\r\n                    [{{dummyAttributeUsage}}{{string.Format(scalarValuesContainerAttributeArgument, \"typeof(int), typeof(dummy_literal)\")}}]\r\n                    public void BenchmarkMethod(System.Type a, System.Type b)\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceDummyAttribute();\r\n\r\n            DisableCompilerDiagnostics();\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Providing_expected_value_type_should_not_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(DummyAttributeUsage))] string dummyAttributeUsage,\r\n            [CombinatorialMemberData(nameof(ValuesAndTypes))] ValueTupleDouble<string, string> valueAndType,\r\n            [CombinatorialMemberData(nameof(ScalarValuesContainerAttributeArgumentEnumerableLocal))] string scalarValuesContainerAttributeArgument)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using DifferentNamespace;\r\n                \r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [Benchmark]\r\n                    [{{dummyAttributeUsage}}{{string.Format(scalarValuesContainerAttributeArgument, valueAndType.Value1)}}]\r\n                    public void BenchmarkMethod({{valueAndType.Value2}} a)\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceDummyAttribute();\r\n            ReferenceDummyEnum();\r\n            ReferenceDummyEnumInDifferentNamespace();\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Providing_expected_enum_value_type_using_not_fully_qualified_name_located_in_a_different_namespace_should_not_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(DummyAttributeUsage))] string dummyAttributeUsage,\r\n            [CombinatorialMemberData(nameof(ScalarValuesContainerAttributeArgumentEnumerableLocal))] string scalarValuesContainerAttributeArgument,\r\n            bool isNullable)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using DifferentNamespace;\r\n\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [Benchmark]\r\n                    [{{dummyAttributeUsage}}{{string.Format(scalarValuesContainerAttributeArgument, \"DummyEnumInDifferentNamespace.Value1\")}}]\r\n                    public void BenchmarkMethod(DummyEnumInDifferentNamespace{{(isNullable ? \"?\" : \"\")}} a)\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceDummyAttribute();\r\n            ReferenceDummyEnum();\r\n            ReferenceDummyEnumInDifferentNamespace();\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Providing_expected_enum_value_type_using_not_fully_qualified_name_located_in_same_namespace_should_not_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(DummyAttributeUsage))] string dummyAttributeUsage,\r\n            [CombinatorialMemberData(nameof(ScalarValuesContainerAttributeArgumentEnumerableLocal))] string scalarValuesContainerAttributeArgument,\r\n            bool isNullable)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                namespace DifferentNamespace;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [Benchmark]\r\n                    [{{dummyAttributeUsage}}{{string.Format(scalarValuesContainerAttributeArgument, \"DummyEnumInDifferentNamespace.Value1\")}}]\r\n                    public void BenchmarkMethod(DummyEnumInDifferentNamespace{{(isNullable ? \"?\" : \"\")}} a)\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceDummyAttribute();\r\n            ReferenceDummyEnum();\r\n            ReferenceDummyEnumInDifferentNamespace();\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Providing_expected_enum_value_type_array_using_not_fully_qualified_name_located_in_a_different_namespace_should_not_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(DummyAttributeUsage))] string dummyAttributeUsage,\r\n            [CombinatorialMemberData(nameof(ArrayValuesContainerAttributeArgumentEnumerableLocal))] string arrayValuesContainerAttributeArgument,\r\n            bool isNullable)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using DifferentNamespace;\r\n\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [{{dummyAttributeUsage}}{{string.Format(arrayValuesContainerAttributeArgument, \"DummyEnumInDifferentNamespace.Value1\", $\"DummyEnumInDifferentNamespace{(isNullable ? \"?\" : \"\")}\")}}]\r\n                    public void BenchmarkMethod(DummyEnumInDifferentNamespace{{(isNullable ? \"?\" : \"\")}} a)\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceDummyAttribute();\r\n            ReferenceDummyEnum();\r\n            ReferenceDummyEnumInDifferentNamespace();\r\n            DisableCompilerDiagnostics();                   // Nullable struct arrays are not supported in attributes\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Providing_expected_enum_value_type_array_using_not_fully_qualified_name_located_in_same_namespace_should_not_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(DummyAttributeUsage))] string dummyAttributeUsage,\r\n            [CombinatorialMemberData(nameof(ArrayValuesContainerAttributeArgumentEnumerableLocal))] string arrayValuesContainerAttributeArgument,\r\n            bool isNullable)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                namespace DifferentNamespace;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [{{dummyAttributeUsage}}{{string.Format(arrayValuesContainerAttributeArgument, \"DummyEnumInDifferentNamespace.Value1\", $\"DummyEnumInDifferentNamespace{(isNullable ? \"?\" : \"\")}\")}}]\r\n                    public void BenchmarkMethod(DummyEnumInDifferentNamespace{{(isNullable ? \"?\" : \"\")}} a)\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceDummyAttribute();\r\n            ReferenceDummyEnum();\r\n            ReferenceDummyEnumInDifferentNamespace();\r\n            DisableCompilerDiagnostics();                   // Nullable struct arrays are not supported in attributes\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Providing_expected_type_using_not_fully_qualified_name_located_in_same_namespace_should_not_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(DummyAttributeUsage))] string dummyAttributeUsage,\r\n            [CombinatorialMemberData(nameof(ValuesAndTypesInDifferentNamespace))] ValueTupleDouble<string, string> valueAndType,\r\n            [CombinatorialMemberData(nameof(ScalarValuesContainerAttributeArgumentEnumerableLocal))] string scalarValuesContainerAttributeArgument)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                namespace DifferentNamespace;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [Benchmark]\r\n                    [{{dummyAttributeUsage}}{{string.Format(scalarValuesContainerAttributeArgument, valueAndType.Value1)}}]\r\n                    public void BenchmarkMethod({{valueAndType.Value2}} a)\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceDummyAttribute();\r\n            ReferenceDummyEnumInDifferentNamespace();\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Providing_expected_type_using_not_fully_qualified_name_located_in_a_different_namespace_should_not_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(DummyAttributeUsage))] string dummyAttributeUsage,\r\n            [CombinatorialMemberData(nameof(ValuesAndTypesInDifferentNamespace))] ValueTupleDouble<string, string> valueAndType,\r\n            [CombinatorialMemberData(nameof(ScalarValuesContainerAttributeArgumentEnumerableLocal))] string scalarValuesContainerAttributeArgument)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using DifferentNamespace;\r\n\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [Benchmark]\r\n                    [{{dummyAttributeUsage}}{{string.Format(scalarValuesContainerAttributeArgument, valueAndType.Value1)}}]\r\n                    public void BenchmarkMethod({{valueAndType.Value2}} a)\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceDummyAttribute();\r\n            ReferenceDummyEnumInDifferentNamespace();\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Providing_integer_value_types_within_target_type_range_should_not_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(DummyAttributeUsage))] string dummyAttributeUsage,\r\n            [CombinatorialMemberData(nameof(ScalarValuesContainerAttributeArgumentEnumerableLocal))] string scalarValuesContainerAttributeArgument,\r\n            [CombinatorialMemberData(nameof(IntegerValuesAndTypesWithinTargetTypeRange))] ValueTupleDouble<string, string> integerValueAndType,\r\n            bool explicitCast)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [Benchmark]\r\n                    [{{dummyAttributeUsage}}{{string.Format(scalarValuesContainerAttributeArgument, $\"{(explicitCast ? $\"({integerValueAndType.Value2})\" : \"\")}{integerValueAndType.Value1}\")}}]\r\n                    public void BenchmarkMethod({{integerValueAndType.Value2}} a)\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceDummyAttribute();\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Providing_null_to_nullable_struct_value_type_should_not_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(DummyAttributeUsage))] string dummyAttributeUsage,\r\n            [CombinatorialMemberData(nameof(NullableStructTypes))] string type,\r\n            [CombinatorialMemberData(nameof(ScalarValuesContainerAttributeArgumentEnumerableLocal))] string scalarValuesContainerAttributeArgument)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [Benchmark]\r\n                    [{{dummyAttributeUsage}}{{string.Format(scalarValuesContainerAttributeArgument, \"null\")}}]\r\n                    public void BenchmarkMethod({{type}}? a)\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n            TestCode = testCode;\r\n            ReferenceDummyAttribute();\r\n            ReferenceDummyEnum();\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Providing_expected_constant_value_type_should_not_trigger_diagnostic(\r\n            bool useConstantFromOtherClass,\r\n            bool useLocalConstant,\r\n            [CombinatorialMemberData(nameof(DummyAttributeUsage))] string dummyAttributeUsage,\r\n            [CombinatorialMemberData(nameof(ConstantValuesAndTypes))] ValueTupleDouble<string, string> valueAndType,\r\n            [CombinatorialMemberData(nameof(ScalarValuesContainerAttributeArgumentEnumerableLocal))] string scalarValuesContainerAttributeArgument)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    {{(useLocalConstant ? $\"private const {valueAndType.Value2} _x = {(useConstantFromOtherClass ? \"Constants.Value\" : valueAndType.Value1!)};\" : \"\")}}\r\n\r\n                    [Benchmark]\r\n                    [{{dummyAttributeUsage}}{{string.Format(scalarValuesContainerAttributeArgument, useLocalConstant ? \"_x\" : useConstantFromOtherClass ? \"Constants.Value\" : valueAndType.Value1!)}}]\r\n                    public void BenchmarkMethod({{valueAndType.Value2}} a)\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n            TestCode = testCode;\r\n            ReferenceDummyAttribute();\r\n            ReferenceDummyEnum();\r\n\r\n            if (useConstantFromOtherClass)\r\n            {\r\n                ReferenceConstants($\"{valueAndType.Value2!}\", valueAndType.Value1!);\r\n            }\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Providing_expected_null_reference_constant_value_type_should_not_trigger_diagnostic(\r\n            bool useConstantFromOtherClass,\r\n            bool useLocalConstant,\r\n            [CombinatorialMemberData(nameof(DummyAttributeUsage))] string dummyAttributeUsage,\r\n            [CombinatorialMemberData(nameof(NullReferenceConstantTypes))] string type,\r\n            [CombinatorialMemberData(nameof(ScalarValuesContainerAttributeArgumentEnumerableLocal))] string scalarValuesContainerAttributeArgument)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    {{(useLocalConstant ? $\"private const {type}? _x = {(useConstantFromOtherClass ? \"Constants.Value\" : \"null\")};\" : \"\")}}\r\n\r\n                    [Benchmark]\r\n                    [{{dummyAttributeUsage}}{{string.Format(scalarValuesContainerAttributeArgument, useLocalConstant ? \"_x\" : useConstantFromOtherClass ? \"Constants.Value\" : \"null\")}}]\r\n                    public void BenchmarkMethod({{type}} a)\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n            TestCode = testCode;\r\n            ReferenceDummyAttribute();\r\n            ReferenceDummyEnum();\r\n\r\n            if (useConstantFromOtherClass)\r\n            {\r\n                ReferenceConstants($\"{type}?\", \"null\");\r\n            }\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Providing_implicitly_convertible_value_type_should_not_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(DummyAttributeUsage))] string dummyAttributeUsage,\r\n            [CombinatorialMemberData(nameof(ScalarValuesContainerAttributeArgumentEnumerableLocal))] string scalarValuesContainerAttributeArgument,\r\n            [CombinatorialValues(\"(byte)42\", \"'c'\")] string value)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [Benchmark]\r\n                    [{{dummyAttributeUsage}}{{string.Format(scalarValuesContainerAttributeArgument, value)}}]\r\n                    public void BenchmarkMethod(int a)\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceDummyAttribute();\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Providing_an_implicitly_convertible_array_value_type_should_not_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(DummyAttributeUsage))] string dummyAttributeUsage,\r\n            [CombinatorialMemberData(nameof(ScalarValuesContainerAttributeArgumentEnumerableLocal))] string scalarValuesContainerAttributeArgument)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [Benchmark]\r\n                    [{{dummyAttributeUsage}}{{string.Format(scalarValuesContainerAttributeArgument, \"new[] { 0, 1, 2 }\")}}]\r\n                    public void BenchmarkMethod(System.Span<int> a)\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceDummyAttribute();\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Having_unknown_parameter_type_should_not_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(DummyAttributeUsage))] string dummyAttributeUsage,\r\n            [CombinatorialMemberData(nameof(ScalarValuesContainerAttributeArgumentEnumerableLocal))] string scalarValuesContainerAttributeArgument)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [Benchmark]\r\n                    [{{dummyAttributeUsage}}{{string.Format(scalarValuesContainerAttributeArgument, \"42, \\\"test\\\"\")}}]\r\n                    [{{dummyAttributeUsage}}{{string.Format(scalarValuesContainerAttributeArgument, \"43, \\\"test2\\\"\")}}]\r\n                    public void BenchmarkMethod(unkown a, string b)\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceDummyAttribute();\r\n\r\n            DisableCompilerDiagnostics();\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Providing_an_unexpected_or_not_implicitly_convertible_value_type_should_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(DummyAttributeUsage))] string dummyAttributeUsage,\r\n            [CombinatorialMemberData(nameof(NotConvertibleValuesAndTypes))] ValueTupleDouble<string, string> valueAndType,\r\n            [CombinatorialMemberData(nameof(ScalarValuesContainerAttributeArgumentEnumerableLocal))] string scalarValuesContainerAttributeArgument)\r\n        {\r\n            const string expectedArgumentType = \"decimal\";\r\n\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [Benchmark]\r\n                    [{{dummyAttributeUsage}}{{string.Format(scalarValuesContainerAttributeArgument, $\"{{|#0:{valueAndType.Value1}|}}\")}}]\r\n                    public void BenchmarkMethod({{expectedArgumentType}} a)\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceDummyAttribute();\r\n            ReferenceDummyEnum();\r\n\r\n            AddDefaultExpectedDiagnostic(valueAndType.Value1!, expectedArgumentType, valueAndType.Value2!);\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Providing_an_unexpected_or_not_implicitly_convertible_constant_value_type_should_trigger_diagnostic(\r\n            bool useConstantFromOtherClass,\r\n            bool useLocalConstant,\r\n            [CombinatorialMemberData(nameof(DummyAttributeUsage))] string dummyAttributeUsage,\r\n            [CombinatorialMemberData(nameof(NotConvertibleConstantValuesAndTypes))] ValueTupleDouble<string, string> valueAndType,\r\n            [CombinatorialMemberData(nameof(ScalarValuesContainerAttributeArgumentEnumerableLocal))] string scalarValuesContainerAttributeArgument)\r\n        {\r\n            const string expectedArgumentType = \"decimal\";\r\n\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    {{(useLocalConstant ? $\"private const {valueAndType.Value2} _x = {(useConstantFromOtherClass ? \"Constants.Value\" : valueAndType.Value1)};\" : \"\")}}\r\n\r\n                    [Benchmark]\r\n                    [{{dummyAttributeUsage}}{{string.Format(scalarValuesContainerAttributeArgument, $\"{{|#0:{(useLocalConstant ? \"_x\" : useConstantFromOtherClass ? \"Constants.Value\" : valueAndType.Value1)}|}}\")}}]\r\n                    public void BenchmarkMethod({{expectedArgumentType}} a)\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n            TestCode = testCode;\r\n            ReferenceDummyAttribute();\r\n            ReferenceDummyEnum();\r\n\r\n            if (useConstantFromOtherClass)\r\n            {\r\n                ReferenceConstants(valueAndType.Value2!, valueAndType.Value1!);\r\n            }\r\n\r\n            AddDefaultExpectedDiagnostic(useLocalConstant ? \"_x\" : useConstantFromOtherClass ? \"Constants.Value\" : valueAndType.Value1!, expectedArgumentType, valueAndType.Value2!);\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Providing_null_to_nonnullable_struct_value_type_should_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(DummyAttributeUsage))] string dummyAttributeUsage,\r\n            [CombinatorialMemberData(nameof(NullableStructTypes))] string type,\r\n            [CombinatorialMemberData(nameof(ScalarValuesContainerAttributeArgumentEnumerableLocal))] string scalarValuesContainerAttributeArgument)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [Benchmark]\r\n                    [{{dummyAttributeUsage}}{{string.Format(scalarValuesContainerAttributeArgument, \"{|#0:null|}\")}}]\r\n                    public void BenchmarkMethod({{type}} a)\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n            TestCode = testCode;\r\n            ReferenceDummyAttribute();\r\n            ReferenceDummyEnum();\r\n\r\n            AddDefaultExpectedDiagnostic(\"null\", type, \"null\");\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Providing_a_not_implicitly_convertible_array_value_type_should_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(DummyAttributeUsage))] string dummyAttributeUsage,\r\n            [CombinatorialMemberData(nameof(ScalarValuesContainerAttributeArgumentEnumerableLocal))] string scalarValuesContainerAttributeArgument,\r\n            [CombinatorialValues(\"System.Span<string>\", \"string[]\")] string expectedArgumentType)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [Benchmark]\r\n                    [{{dummyAttributeUsage}}{{string.Format(scalarValuesContainerAttributeArgument, \"{|#0:new[] { 0, 1, 2 }|}\")}}]\r\n                    public void BenchmarkMethod({{expectedArgumentType}} a)\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceDummyAttribute();\r\n\r\n            AddDefaultExpectedDiagnostic(\"new[] { 0, 1, 2 }\", expectedArgumentType, \"int[]\");\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Providing_integer_value_types_not_within_target_type_range_should_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(DummyAttributeUsage))] string dummyAttributeUsage,\r\n            [CombinatorialMemberData(nameof(ScalarValuesContainerAttributeArgumentEnumerableLocal))] string scalarValuesContainerAttributeArgument,\r\n            [CombinatorialMemberData(nameof(IntegerValuesAndTypesNotWithinTargetTypeRange))] ValueTupleTriple<string, string, string> integerValueAndType)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [Benchmark]\r\n                    [{{dummyAttributeUsage}}{{string.Format(scalarValuesContainerAttributeArgument, $\"{{|#0:{integerValueAndType.Value1}|}}\")}}]\r\n                    public void BenchmarkMethod({{integerValueAndType.Value2}} a)\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n            TestCode = testCode;\r\n            ReferenceDummyAttribute();\r\n            AddDefaultExpectedDiagnostic(integerValueAndType.Value1!, integerValueAndType.Value2!, integerValueAndType.Value3!);\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        public static IEnumerable<string> DummyAttributeUsage\r\n            => DummyAttributeUsageTheoryData;\r\n\r\n        public static TheoryData<string> EmptyArgumentsAttributeUsagesWithMismatchingValueCount()\r\n        {\r\n            return [.. GenerateData()];\r\n\r\n            static IEnumerable<string> GenerateData()\r\n            {\r\n                yield return \"[Arguments]\";\r\n                yield return \"[Arguments()]\";\r\n                yield return \"[Arguments(Priority = 1)]\";\r\n\r\n                string[] nameColonUsages = [\"\", \"values: \"];\r\n\r\n                string[] priorityNamedParameterUsages = [\"\", \", Priority = 1\"];\r\n\r\n                string[] attributeUsagesBase =\r\n                [\r\n                    \"[Arguments({0}new object[] {{ }}{1})]\",\r\n                    \"[Arguments({0}new object[0]{1})]\",\r\n                    \"[Arguments({0}[]{1})]\",\r\n                ];\r\n\r\n                foreach (var attributeUsageBase in attributeUsagesBase)\r\n                {\r\n                    foreach (var nameColonUsage in nameColonUsages)\r\n                    {\r\n                        foreach (var priorityNamedParameterUsage in priorityNamedParameterUsages)\r\n                        {\r\n                            yield return string.Format(attributeUsageBase, nameColonUsage, priorityNamedParameterUsage);\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        public static IEnumerable<string> ScalarValuesContainerAttributeArgumentEnumerableLocal\r\n            => ScalarValuesContainerAttributeArgumentEnumerable();\r\n\r\n        public static IEnumerable<ValueTupleDouble<string, string>> IntegerValuesAndTypesWithinTargetTypeRange =>\r\n        [\r\n            // byte (0 to 255)\r\n            (\"0\", \"byte\"),\r\n            (\"100\", \"byte\"),\r\n            (\"255\", \"byte\"),\r\n\r\n            // sbyte (-128 to 127)\r\n            (\"-128\", \"sbyte\"),\r\n            (\"0\", \"sbyte\"),\r\n            (\"127\", \"sbyte\"),\r\n\r\n            // short (-32,768 to 32,767)\r\n            (\"-32768\", \"short\"),\r\n            (\"0\", \"short\"),\r\n            (\"32767\", \"short\"),\r\n\r\n            // ushort (0 to 65,535)\r\n            (\"0\", \"ushort\"),\r\n            (\"1000\", \"ushort\"),\r\n            (\"65535\", \"ushort\"),\r\n\r\n            // int (-2,147,483,648 to 2,147,483,647)\r\n            (\"-2147483648\", \"int\"),\r\n            (\"0\", \"int\"),\r\n            (\"2147483647\", \"int\"),\r\n\r\n            // uint (0 to 4,294,967,295)\r\n            (\"0\", \"uint\"),\r\n            (\"1000000\", \"uint\"),\r\n            (\"4294967295\", \"uint\"),\r\n\r\n            // long (-9,223,372,036,854,775,808 to 9,223,372,036,854,775,807)\r\n            (\"-9223372036854775808\", \"long\"),\r\n            (\"0\", \"long\"),\r\n            (\"9223372036854775807\", \"long\"),\r\n\r\n            // ulong (0 to 18,446,744,073,709,551,615)\r\n            (\"0\", \"ulong\"),\r\n            (\"1000000\", \"ulong\"),\r\n            (\"18446744073709551615\", \"ulong\"),\r\n        ];\r\n\r\n        public static IEnumerable<ValueTupleTriple<string, string, string>> IntegerValuesAndTypesNotWithinTargetTypeRange =>\r\n        [\r\n            // byte (0 to 255) - out of range values\r\n            (\"-1\", \"byte\", \"int\"),\r\n            (\"256\", \"byte\", \"int\"),\r\n            (\"1000\", \"byte\", \"int\"),\r\n\r\n            // sbyte (-128 to 127) - out of range values\r\n            (\"-129\", \"sbyte\", \"int\"),\r\n            (\"128\", \"sbyte\", \"int\"),\r\n            (\"500\", \"sbyte\", \"int\"),\r\n\r\n            // short (-32,768 to 32,767) - out of range values\r\n            (\"-32769\", \"short\", \"int\"),\r\n            (\"32768\", \"short\", \"int\"),\r\n            (\"100000\", \"short\", \"int\"),\r\n\r\n            // ushort (0 to 65,535) - out of range values\r\n            (\"-1\", \"ushort\", \"int\"),\r\n            (\"65536\", \"ushort\", \"int\"),\r\n            (\"100000\", \"ushort\", \"int\"),\r\n\r\n            // int (-2,147,483,648 to 2,147,483,647) - out of range values\r\n            (\"-2147483649\", \"int\", \"long\"),\r\n            (\"2147483648\", \"int\", \"uint\"),\r\n            (\"5000000000\", \"int\", \"long\"),\r\n\r\n            // uint (0 to 4,294,967,295) - out of range values\r\n            (\"-1\", \"uint\", \"int\"),\r\n            (\"4294967296\", \"uint\", \"long\"),\r\n            (\"5000000000\", \"uint\", \"long\"),\r\n\r\n            // long - out of range values (exceeding long range)\r\n            (\"9223372036854775808\", \"long\", \"ulong\"),\r\n\r\n            // ulong - negative values\r\n            (\"-1\", \"ulong\", \"int\"),\r\n            (\"-100\", \"ulong\", \"int\"),\r\n            (\"-9223372036854775808\", \"ulong\", \"long\"),\r\n        ];\r\n\r\n        public static IEnumerable<string> ArrayValuesContainerAttributeArgumentEnumerableLocal()\r\n        {\r\n            string[] nameColonUsages =\r\n            [\r\n                \"\",\r\n                \"values: \"\r\n            ];\r\n\r\n            string[] priorityNamedParameterUsages =\r\n            [\r\n                \"\",\r\n                \", Priority = 1\"\r\n            ];\r\n\r\n            List<string> arrayValuesContainers =\r\n            [\r\n                \"{0}new object[] {{{{ new[] {{{{ {{0}} }}}} }}}}{1}\",         // new object[] { new[] { 42 } }\r\n                \"{0}new object[] {{{{ new {{1}}[] {{{{ {{0}} }}}} }}}}{1}\",   // new object[] { new int[] { 42 } }\r\n                \"{0}[ new[] {{{{ {{0}} }}}} ]{1}\",                            // [ new[] { 42 } ]\r\n                \"{0}[ new {{1}}[] {{{{ {{0}} }}}} ]{1}\",                      // [ new int[] { 42 } ]\r\n                \"{0}new object[] {{{{ new {{1}}[] {{{{ }}}} }}}}{1}\",         // new object[] { new int[] { } }\r\n                \"{0}[ new {{1}}[] {{{{ }}}} ]{1}\",                            // [ new int[] { } ]\r\n                \"{0}new object[] {{{{ new {{1}}[0] }}}}{1}\",                  // new object[] { new int[0] }\r\n                \"{0}[ new {{1}}[0] ]{1}\"                                      // [ new int[0] ]\r\n            ];\r\n\r\n            foreach (var arrayValuesContainer in arrayValuesContainers)\r\n            {\r\n                foreach (var nameColonUsage in nameColonUsages)\r\n                {\r\n                    foreach (var priorityNamedParameterUsage in priorityNamedParameterUsages)\r\n                    {\r\n                        yield return string.Format(arrayValuesContainer, nameColonUsage, priorityNamedParameterUsage);\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        public static IEnumerable<ValueTupleDouble<string, string>> ValuesAndTypes =>\r\n        [\r\n            ( \"true\", \"bool\" ),\r\n            ( \"(byte)123\", \"byte\" ),\r\n            ( \"'A'\", \"char\" ),\r\n            ( \"1.0D\", \"double\" ),\r\n            ( \"1.0F\", \"float\" ),\r\n            ( \"123\", \"int\" ),\r\n            ( \"123L\", \"long\" ),\r\n            ( \"(sbyte)-100\", \"sbyte\" ),\r\n            ( \"(short)-123\", \"short\" ),\r\n            ( \"\"\"\r\n              \"test\"\r\n              \"\"\", \"string\" ),\r\n            ( \"123U\", \"uint\" ),\r\n            ( \"123UL\", \"ulong\" ),\r\n            ( \"(ushort)123\", \"ushort\" ),\r\n\r\n            ( \"\"\"\r\n              (object)\"test_object\"\r\n              \"\"\", \"object\" ),\r\n            ( \"typeof(string)\", \"System.Type\" ),\r\n            ( \"typeof(DummyEnumInDifferentNamespace?)\", \"System.Type\" ),\r\n            ( \"DummyEnum.Value1\", \"DummyEnum\" ),\r\n\r\n            ( \"new[] { 0, 1, 2 }\", \"int[]\" ),\r\n        ];\r\n\r\n        public static IEnumerable<ValueTupleDouble<string, string>> ValuesAndTypesInDifferentNamespace =>\r\n        [\r\n            ( \"typeof(DummyEnumInDifferentNamespace)\", \"System.Type\" ),\r\n            ( \"typeof(DummyEnumInDifferentNamespace?)\", \"System.Type\" ),\r\n            ( \"DummyEnumInDifferentNamespace.Value1\", \"DummyEnumInDifferentNamespace\" ),\r\n        ];\r\n\r\n        public static IEnumerable<ValueTupleDouble<string, string>> NotConvertibleValuesAndTypes =>\r\n        [\r\n            ( \"true\", \"bool\" ),\r\n            ( \"1.0D\", \"double\" ),\r\n            ( \"1.0F\", \"float\" ),\r\n            ( \"\"\"\r\n              \"test\"\r\n              \"\"\", \"string\" ),\r\n\r\n            ( \"\"\"\r\n              (object)\"test_object\"\r\n              \"\"\", \"string\" ),\r\n            ( \"typeof(string)\", \"System.Type\" ),\r\n            ( \"DummyEnum.Value1\", \"DummyEnum\" )\r\n        ];\r\n\r\n        public static IEnumerable<ValueTupleDouble<string, string>> ConstantValuesAndTypes =>\r\n        [\r\n            ( \"true\", \"bool\" ),\r\n            ( \"(byte)123\", \"byte\" ),\r\n            ( \"'A'\", \"char\" ),\r\n            ( \"1.0D\", \"double\" ),\r\n            ( \"1.0F\", \"float\" ),\r\n            ( \"123\", \"int\" ),\r\n            ( \"123L\", \"long\" ),\r\n            ( \"(sbyte)-100\", \"sbyte\" ),\r\n            ( \"(short)-123\", \"short\" ),\r\n            ( \"\"\"\r\n              \"test\"\r\n              \"\"\", \"string\" ),\r\n            ( \"123U\", \"uint\" ),\r\n            ( \"123UL\", \"ulong\" ),\r\n            ( \"(ushort)123\", \"ushort\" ),\r\n\r\n            ( \"DummyEnum.Value1\", \"DummyEnum\" ),\r\n        ];\r\n\r\n        public static IEnumerable<string> NullableStructTypes =>\r\n        [\r\n            \"bool\",\r\n            \"byte\",\r\n            \"char\",\r\n            \"double\",\r\n            \"float\",\r\n            \"int\",\r\n            \"long\",\r\n            \"sbyte\",\r\n            \"short\",\r\n            \"uint\",\r\n            \"ulong\",\r\n            \"ushort\",\r\n            \"DummyEnum\",\r\n        ];\r\n\r\n        public static IEnumerable<string> NullReferenceConstantTypes =>\r\n        [\r\n            \"object\",\r\n            \"string\",\r\n            \"System.Type\",\r\n        ];\r\n\r\n        public static IEnumerable<ValueTupleDouble<string, string>> NotConvertibleConstantValuesAndTypes =>\r\n        [\r\n            ( \"true\", \"bool\" ),\r\n            ( \"1.0D\", \"double\" ),\r\n            ( \"1.0F\", \"float\" ),\r\n            ( \"\"\"\r\n              \"test\"\r\n              \"\"\", \"string\" ),\r\n\r\n            ( \"DummyEnum.Value1\", \"DummyEnum\" )\r\n        ];\r\n    }\r\n\r\n    public static TheoryData<string> DummyAttributeUsageTheoryData => [\"\", \"Dummy, \"];\r\n\r\n    private static IEnumerable<string> ScalarValuesContainerAttributeArgumentEnumerable()\r\n    {\r\n        return GenerateData().Distinct();\r\n\r\n        static IEnumerable<string> GenerateData()\r\n        {\r\n            string[] nameColonUsages = [\"\", \"values: \"];\r\n\r\n            string[] priorityNamedParameterUsages = [\"\", \", Priority = 1\"];\r\n\r\n            string[] attributeUsagesBase =\r\n            [\r\n                \"Arguments({{0}}{1})\",\r\n                \"Arguments({0}new object[] {{{{ {{0}} }}}}{1})\",\r\n                \"Arguments({0}[ {{0}} ]{1})\"\r\n            ];\r\n\r\n            foreach (var attributeUsageBase in attributeUsagesBase)\r\n            {\r\n                foreach (var nameColonUsage in nameColonUsages)\r\n                {\r\n                    foreach (var priorityNamedParameterUsage in priorityNamedParameterUsages)\r\n                    {\r\n                        yield return string.Format(attributeUsageBase, nameColonUsage, priorityNamedParameterUsage);\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    }\r\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Analyzers.Tests/AnalyzerTests/Attributes/GeneralArgumentAttributesAnalyzerTests.cs",
    "content": "﻿using BenchmarkDotNet.Analyzers.Attributes;\r\nusing BenchmarkDotNet.Analyzers.Tests.Fixtures;\r\nusing System.Collections.Generic;\r\nusing System.Linq;\r\nusing System.Threading.Tasks;\r\nusing Xunit;\r\n\r\nnamespace BenchmarkDotNet.Analyzers.Tests.AnalyzerTests.Attributes;\r\npublic class GeneralArgumentAttributesAnalyzerTests\r\n{\r\n    public class MethodWithoutAttributeMustHaveNoParameters : AnalyzerTestFixture<GeneralArgumentAttributesAnalyzer>\r\n    {\r\n        public MethodWithoutAttributeMustHaveNoParameters() : base(GeneralArgumentAttributesAnalyzer.MethodWithoutAttributeMustHaveNoParametersRule) { }\r\n\r\n        [Theory]\r\n        [InlineData(\"\"\"ArgumentsSource(\"test\")\"\"\")]\r\n        [InlineData(\"\"\"Arguments(42, \"test\")\"\"\")]\r\n        [InlineData(\"\"\"\r\n                    Arguments(42, \"test\"), Arguments(1, \"test2\")\r\n                    \"\"\")]\r\n        public async Task A_method_with_parameters_annotated_with_an_argumentssource_or_arguments_attribute_and_the_benchmark_attribute_should_not_trigger_diagnostic(string attributeUsage)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [Benchmark]\r\n                    [{{attributeUsage}}]\r\n                    public void BenchmarkMethod(int a, string b)\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory]\r\n        [MemberData(nameof(ParametersListLength))]\r\n        public async Task A_method_with_parameters_and_no_argumentssource_arguments_or_benchmark_attributes_should_not_trigger_diagnostic(int parametersListLength)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    public void BenchmarkMethod({{string.Join(\", \", Parameters.Take(parametersListLength))}})\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory]\r\n        [MemberData(nameof(ParametersListLength))]\r\n        public async Task A_method_with_parameters_annotated_with_the_benchmark_attribute_and_an_argumentssource_attribute_but_no_arguments_attribute_should_not_trigger_diagnostic(int parametersListLength)\r\n        {\r\n            const string benchmarkMethodName = \"BenchmarkMethod\";\r\n\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [Benchmark]\r\n                    [ArgumentsSource(\"test\")]\r\n                    public void {{benchmarkMethodName}}({|#0:{{string.Join(\", \", Parameters.Take(parametersListLength))}}|})\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory]\r\n        [MemberData(nameof(ParametersListLength))]\r\n        public async Task A_method_with_parameters_annotated_with_the_benchmark_attribute_but_no_argumentssource_or_arguments_attribute_should_trigger_diagnostic(int parametersListLength)\r\n        {\r\n            const string benchmarkMethodName = \"BenchmarkMethod\";\r\n\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [Benchmark]\r\n                    public void {{benchmarkMethodName}}({|#0:{{string.Join(\", \", Parameters.Take(parametersListLength))}}|})\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            AddDefaultExpectedDiagnostic(benchmarkMethodName);\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        public static TheoryData<int> ParametersListLength => [.. Enumerable.Range(1, Parameters.Count)];\r\n\r\n        private static IReadOnlyCollection<string> Parameters => [\"int a\", \"string b\", \"bool c\"];\r\n    }\r\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Analyzers.Tests/AnalyzerTests/Attributes/GeneralParameterAttributesAnalyzerTests.cs",
    "content": "using BenchmarkDotNet.Analyzers.Attributes;\r\nusing BenchmarkDotNet.Analyzers.Tests.Fixtures;\r\nusing Microsoft.CodeAnalysis;\r\nusing System;\r\nusing System.Collections.Generic;\r\nusing System.Collections.ObjectModel;\r\nusing System.Linq;\r\nusing System.Threading.Tasks;\r\nusing Xunit;\r\n\r\nnamespace BenchmarkDotNet.Analyzers.Tests.AnalyzerTests.Attributes;\r\npublic class GeneralParameterAttributesAnalyzerTests\r\n{\r\n    public class MutuallyExclusiveOnField : AnalyzerTestFixture<GeneralParameterAttributesAnalyzer>\r\n    {\r\n        public MutuallyExclusiveOnField() : base(GeneralParameterAttributesAnalyzer.MutuallyExclusiveOnFieldRule) { }\r\n\r\n        [Fact]\r\n        public async Task A_field_not_annotated_with_any_parameter_attribute_should_not_trigger_diagnostic()\r\n        {\r\n            const string testCode = /* lang=c#-test */ \"\"\"\r\n                public class BenchmarkClass\r\n                {\r\n                    public int _field = 0, _field2 = 1;\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Fact]\r\n        public async Task A_field_annotated_with_a_nonparameter_attribute_should_not_trigger_diagnostic()\r\n        {\r\n            const string testCode = /* lang=c#-test */ \"\"\"\r\n                public class BenchmarkClass\r\n                {\r\n                    [Dummy]\r\n                    public int _field = 0, _field2 = 1;\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceDummyAttribute();\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Fact]\r\n        public async Task A_field_annotated_with_a_duplicate_nonparameter_attribute_should_not_trigger_diagnostic()\r\n        {\r\n            const string testCode = /* lang=c#-test */ \"\"\"\r\n                public class BenchmarkClass\r\n                {\r\n                    [Dummy]\r\n                    [Dummy]\r\n                    public int _field = 0, _field2 = 1;\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceDummyAttribute();\r\n            DisableCompilerDiagnostics();\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory]\r\n        [MemberData(nameof(UniqueParameterAttributeUsages))]\r\n        public async Task A_field_annotated_with_a_unique_parameter_attribute_should_not_trigger_diagnostic(string attributeUsage)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [{{attributeUsage}}]\r\n                    public int _field = 0, _field2 = 1;\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory]\r\n        [MemberData(nameof(DuplicateSameParameterAttributeUsages))]\r\n        public async Task A_field_annotated_with_the_same_duplicate_parameter_attribute_should_not_trigger_diagnostic(string currentUniqueAttributeUsage, int currentUniqueAttributeUsagePosition, int[] counts)\r\n        {\r\n            var duplicateAttributeUsages = new List<string>(1 + counts.Sum());\r\n\r\n            var uniqueParameterAttributeUsages = UniqueParameterAttributeUsages.AsReadOnly();\r\n\r\n            for (var i = 0; i < counts.Length; i++)\r\n            {\r\n                if (i == currentUniqueAttributeUsagePosition)\r\n                {\r\n                    duplicateAttributeUsages.Add($\"[{currentUniqueAttributeUsage}]\");\r\n                }\r\n\r\n                for (var j = 0; j < counts[i]; j++)\r\n                {\r\n                    duplicateAttributeUsages.Add($\"[{uniqueParameterAttributeUsages[i]}]\");\r\n                }\r\n            }\r\n\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    {{string.Join($\"{Environment.NewLine}    \", duplicateAttributeUsages)}}\r\n                    public int _field = 0, _field2 = 1;\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            DisableCompilerDiagnostics();\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory]\r\n        [MemberData(nameof(DuplicateParameterAttributeUsageCounts))]\r\n        public async Task A_field_annotated_with_more_than_one_parameter_attribute_should_trigger_diagnostic_for_each_attribute_usage(int[] duplicateAttributeUsageCounts)\r\n        {\r\n            const string fieldIdentifier = \"_field\";\r\n\r\n            var duplicateAttributeUsages = new List<string>(duplicateAttributeUsageCounts.Sum());\r\n\r\n            var uniqueParameterAttributeUsages = UniqueParameterAttributeUsages.AsReadOnly();\r\n\r\n            var diagnosticCounter = 0;\r\n            for (var i = 0; i < duplicateAttributeUsageCounts.Length; i++)\r\n            {\r\n                for (var j = 0; j < duplicateAttributeUsageCounts[i]; j++)\r\n                {\r\n                    duplicateAttributeUsages.Add($\"[{{|#{diagnosticCounter++}:{uniqueParameterAttributeUsages[i]}|}}]\");\r\n                }\r\n            }\r\n\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    {{string.Join($\"{Environment.NewLine}    \", duplicateAttributeUsages)}}\r\n                    public int {{fieldIdentifier}} = 0, field2 = 1;\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n\r\n            for (var i = 0; i < diagnosticCounter; i++)\r\n            {\r\n                AddExpectedDiagnostic(i, fieldIdentifier);\r\n            }\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        public static TheoryData<string> UniqueParameterAttributeUsages\r\n            => [.. UniqueParameterAttributesTheoryData.Select(tdr => (tdr[1] as string)!)];\r\n\r\n        public static TheoryData<string, int, int[]> DuplicateSameParameterAttributeUsages\r\n            => DuplicateSameAttributeUsagesTheoryData;\r\n\r\n        public static TheoryData<int[]> DuplicateParameterAttributeUsageCounts\r\n            => DuplicateAttributeUsageCountsTheoryData;\r\n    }\r\n\r\n    public class MutuallyExclusiveOnProperty : AnalyzerTestFixture<GeneralParameterAttributesAnalyzer>\r\n    {\r\n        public MutuallyExclusiveOnProperty() : base(GeneralParameterAttributesAnalyzer.MutuallyExclusiveOnPropertyRule) { }\r\n\r\n        [Fact]\r\n        public async Task A_property_not_annotated_with_any_parameter_attribute_should_not_trigger_diagnostic()\r\n        {\r\n            const string testCode = /* lang=c#-test */ \"\"\"\r\n                public class BenchmarkClass\r\n                {\r\n                    public int Property { get; set; }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Fact]\r\n        public async Task A_property_annotated_with_a_nonparameter_attribute_should_not_trigger_diagnostic()\r\n        {\r\n            const string testCode = /* lang=c#-test */ \"\"\"\r\n                public class BenchmarkClass\r\n                {\r\n                    [Dummy]\r\n                    public int Property { get; set; }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceDummyAttribute();\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Fact]\r\n        public async Task A_property_annotated_with_a_duplicate_nonparameter_attribute_should_not_trigger_diagnostic()\r\n        {\r\n            const string testCode = /* lang=c#-test */ \"\"\"\r\n                public class BenchmarkClass\r\n                {\r\n                    [Dummy]\r\n                    [Dummy]\r\n                    public int Property { get; set; }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceDummyAttribute();\r\n            DisableCompilerDiagnostics();\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory]\r\n        [MemberData(nameof(UniqueParameterAttributeUsages))]\r\n        public async Task A_property_annotated_with_a_unique_parameter_attribute_should_not_trigger_diagnostic(string attributeUsage)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [{{attributeUsage}}]\r\n                    public int Property { get; set; }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory]\r\n        [MemberData(nameof(DuplicateSameParameterAttributeUsages))]\r\n        public async Task A_property_annotated_with_the_same_duplicate_parameter_attribute_should_not_trigger_diagnostic(\r\n            string currentAttributeUsage,\r\n            int currentUniqueAttributeUsagePosition,\r\n            int[] duplicateSameAttributeUsageCounts)\r\n        {\r\n            var duplicateAttributeUsages = new List<string>(1 + duplicateSameAttributeUsageCounts.Sum());\r\n\r\n            var uniqueParameterAttributeUsages = UniqueParameterAttributeUsages.AsReadOnly();\r\n\r\n            for (var i = 0; i < duplicateSameAttributeUsageCounts.Length; i++)\r\n            {\r\n                if (i == currentUniqueAttributeUsagePosition)\r\n                {\r\n                    duplicateAttributeUsages.Add($\"[{currentAttributeUsage}]\");\r\n                }\r\n\r\n                for (var j = 0; j < duplicateSameAttributeUsageCounts[i]; j++)\r\n                {\r\n                    duplicateAttributeUsages.Add($\"[{uniqueParameterAttributeUsages[i]}]\");\r\n                }\r\n            }\r\n\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    {{string.Join($\"{Environment.NewLine}    \", duplicateAttributeUsages)}}\r\n                    public int Property { get; set; }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            DisableCompilerDiagnostics();\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory]\r\n        [MemberData(nameof(DuplicateParameterAttributeUsages))]\r\n        public async Task A_property_annotated_with_more_than_one_parameter_attribute_should_trigger_diagnostic_for_each_attribute_usage(int[] duplicateAttributeUsageCounts)\r\n        {\r\n            const string propertyIdentifier = \"Property\";\r\n\r\n            var duplicateAttributeUsages = new List<string>(duplicateAttributeUsageCounts.Sum());\r\n\r\n            var uniqueParameterAttributeUsages = UniqueParameterAttributeUsages.AsReadOnly();\r\n\r\n            var diagnosticCounter = 0;\r\n            for (var i = 0; i < duplicateAttributeUsageCounts.Length; i++)\r\n            {\r\n                for (var j = 0; j < duplicateAttributeUsageCounts[i]; j++)\r\n                {\r\n                    duplicateAttributeUsages.Add($\"[{{|#{diagnosticCounter++}:{uniqueParameterAttributeUsages[i]}|}}]\");\r\n                }\r\n            }\r\n\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    {{string.Join($\"{Environment.NewLine}    \", duplicateAttributeUsages)}}\r\n                    public int {{propertyIdentifier}} { get; set; }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n\r\n            for (var i = 0; i < diagnosticCounter; i++)\r\n            {\r\n                AddExpectedDiagnostic(i, propertyIdentifier);\r\n            }\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        public static TheoryData<string> UniqueParameterAttributeUsages => [.. UniqueParameterAttributesTheoryData.Select(tdr => (tdr[1] as string)!)];\r\n\r\n        public static TheoryData<string, int, int[]> DuplicateSameParameterAttributeUsages => DuplicateSameAttributeUsagesTheoryData;\r\n\r\n        public static TheoryData<int[]> DuplicateParameterAttributeUsages => DuplicateAttributeUsageCountsTheoryData;\r\n    }\r\n\r\n    public class FieldMustBePublic : AnalyzerTestFixture<GeneralParameterAttributesAnalyzer>\r\n    {\r\n        public FieldMustBePublic() : base(GeneralParameterAttributesAnalyzer.FieldMustBePublic) { }\r\n\r\n        [Theory]\r\n        [ClassData(typeof(NonPublicClassMemberAccessModifiersTheoryData))]\r\n        public async Task A_nonpublic_field_not_annotated_with_any_parameter_attribute_should_not_trigger_diagnostic(string classMemberAccessModifier)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                public class BenchmarkClass\r\n                {\r\n                    {{classMemberAccessModifier}}int _field = 0, _field2 = 1;\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory]\r\n        [ClassData(typeof(NonPublicClassMemberAccessModifiersTheoryData))]\r\n        public async Task A_nonpublic_field_annotated_with_a_nonparameter_attribute_should_not_trigger_diagnostic(string classMemberAccessModifier)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                public class BenchmarkClass\r\n                {\r\n                    [Dummy]\r\n                    {{classMemberAccessModifier}}int _field = 0, _field2 = 1;\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceDummyAttribute();\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory]\r\n        [MemberData(nameof(UniqueParameterAttributeUsages))]\r\n        public async Task A_public_field_annotated_with_a_unique_parameter_attribute_should_not_trigger_diagnostic(string attributeUsage)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [{{attributeUsage}}]\r\n                    public int _field = 0, _field2 = 2;\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task A_nonpublic_field_annotated_with_the_same_duplicate_parameter_attribute_should_not_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(DuplicateSameParameterAttributeUsages))] (string CurrentUniqueAttributeUsage, int CurrentUniqueAttributeUsagePosition, int[] Counts) duplicateSameParameterAttributeUsages,\r\n            [CombinatorialMemberData(nameof(NonPublicClassMemberAccessModifiers))] string classMemberAccessModifier)\r\n        {\r\n            var duplicateAttributeUsages = new List<string>(1 + duplicateSameParameterAttributeUsages.Counts.Sum());\r\n\r\n            var uniqueParameterAttributeUsages = UniqueParameterAttributeUsages.AsReadOnly();\r\n\r\n            for (var i = 0; i < duplicateSameParameterAttributeUsages.Counts.Length; i++)\r\n            {\r\n                if (i == duplicateSameParameterAttributeUsages.CurrentUniqueAttributeUsagePosition)\r\n                {\r\n                    duplicateAttributeUsages.Add($\"[{duplicateSameParameterAttributeUsages.CurrentUniqueAttributeUsage}]\");\r\n                }\r\n\r\n                for (var j = 0; j < duplicateSameParameterAttributeUsages.Counts[i]; j++)\r\n                {\r\n                    duplicateAttributeUsages.Add($\"[{uniqueParameterAttributeUsages[i]}]\");\r\n                }\r\n            }\r\n\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    {{string.Join($\"{Environment.NewLine}    \", duplicateAttributeUsages)}}\r\n                    {{classMemberAccessModifier}}int _field = 0, _field2 = 1;\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            DisableCompilerDiagnostics();\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory]\r\n        [MemberData(nameof(DuplicateAttributeUsageCountsAndNonPublicClassMemberAccessModifiersCombinations))]\r\n        public async Task A_nonpublic_field_annotated_with_more_than_one_parameter_attribute_should_not_trigger_diagnostic(int[] duplicateAttributeUsageCounts, string classMemberAccessModifier)\r\n        {\r\n            var duplicateAttributeUsages = new List<string>(duplicateAttributeUsageCounts.Sum());\r\n\r\n            var uniqueParameterAttributeUsages = UniqueParameterAttributeUsages.AsReadOnly();\r\n\r\n            for (var i = 0; i < duplicateAttributeUsageCounts.Length; i++)\r\n            {\r\n                for (var j = 0; j < duplicateAttributeUsageCounts[i]; j++)\r\n                {\r\n                    duplicateAttributeUsages.Add($\"[{uniqueParameterAttributeUsages[i]}]\");\r\n                }\r\n            }\r\n\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    {{string.Join($\"{Environment.NewLine}    \", duplicateAttributeUsages)}}\r\n                    {{classMemberAccessModifier}}int _field = 0, _field2 = 1;\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task A_nonpublic_field_annotated_with_a_unique_parameter_attribute_should_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(UniqueParameterAttributes))] (string AttributeName, string AttributeUsage) attribute,\r\n            [CombinatorialMemberData(nameof(NonPublicClassMemberAccessModifiers))] string classMemberAccessModifier)\r\n        {\r\n            const string fieldIdentifier = \"_field\";\r\n\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [{{attribute.AttributeUsage}}]\r\n                    {{classMemberAccessModifier}}int {|#0:{{fieldIdentifier}}|} = 0, field2 = 0;\r\n                }\r\n                \"\"\";\r\n            TestCode = testCode;\r\n            AddDefaultExpectedDiagnostic(fieldIdentifier, attribute.AttributeName);\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        public static IEnumerable<object[]> DuplicateAttributeUsageCountsAndNonPublicClassMemberAccessModifiersCombinations\r\n            => CombinationsGenerator.CombineArguments(DuplicateParameterAttributeUsageCounts, NonPublicClassMemberAccessModifiers);\r\n\r\n        public static TheoryData<string> UniqueParameterAttributeUsages\r\n            => [.. UniqueParameterAttributesTheoryData.Select(tdr => (tdr[1] as string)!)];\r\n\r\n        public static IEnumerable<(string AttributeName, string AttributeUsage)> UniqueParameterAttributes\r\n            => UniqueParameterAttributesTheoryData.Select(tdr => ((tdr[0] as string)!, (tdr[1] as string)!));\r\n\r\n        public static IEnumerable<string> NonPublicClassMemberAccessModifiers\r\n#pragma warning disable IDE0028 // Simplify collection initialization\r\n            => new NonPublicClassMemberAccessModifiersTheoryData();\r\n#pragma warning restore IDE0028 // Simplify collection initialization\r\n\r\n        public static IEnumerable<(string CurrentUniqueAttributeUsage, int CurrentUniqueAttributeUsagePosition, int[] Counts)> DuplicateSameParameterAttributeUsages\r\n            => DuplicateSameAttributeUsagesTheoryData.Select(tdr => ((tdr[0] as string)!, (int) tdr[1], (tdr[2] as int[])!));\r\n\r\n        public static IEnumerable<int[]> DuplicateParameterAttributeUsageCounts\r\n            => DuplicateAttributeUsageCountsTheoryData;\r\n    }\r\n\r\n    public class PropertyMustBePublic : AnalyzerTestFixture<GeneralParameterAttributesAnalyzer>\r\n    {\r\n        public PropertyMustBePublic() : base(GeneralParameterAttributesAnalyzer.PropertyMustBePublic) { }\r\n\r\n        [Theory]\r\n        [ClassData(typeof(NonPublicClassMemberAccessModifiersTheoryData))]\r\n        public async Task A_nonpublic_property_not_annotated_with_any_parameter_attribute_should_not_trigger_diagnostic(string classMemberAccessModifier)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                public class BenchmarkClass\r\n                {\r\n                    {{classMemberAccessModifier}}int Property { get; set; }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory]\r\n        [ClassData(typeof(NonPublicClassMemberAccessModifiersTheoryData))]\r\n        public async Task A_nonpublic_property_annotated_with_a_nonparameter_attribute_should_not_trigger_diagnostic(string classMemberAccessModifier)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                public class BenchmarkClass\r\n                {\r\n                    [Dummy]\r\n                    {{classMemberAccessModifier}}int Property { get; set; }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceDummyAttribute();\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory]\r\n        [MemberData(nameof(UniqueParameterAttributeUsages))]\r\n        public async Task A_public_property_annotated_with_a_unique_parameter_attribute_should_not_trigger_diagnostic(string attributeUsage)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [{{attributeUsage}}]\r\n                    public int Property { get; set; }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task A_nonpublic_property_annotated_with_the_same_duplicate_parameter_attribute_should_not_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(DuplicateSameParameterAttributeUsages))] (string CurrentUniqueAttributeUsage, int CurrentUniqueAttributeUsagePosition, int[] Counts) duplicateSameParameterAttributeUsages,\r\n            [CombinatorialMemberData(nameof(NonPublicClassMemberAccessModifiers))] string classMemberAccessModifier)\r\n        {\r\n            var duplicateAttributeUsages = new List<string>(1 + duplicateSameParameterAttributeUsages.Counts.Sum());\r\n\r\n            var uniqueParameterAttributeUsages = UniqueParameterAttributeUsages.AsReadOnly();\r\n\r\n            for (var i = 0; i < duplicateSameParameterAttributeUsages.Counts.Length; i++)\r\n            {\r\n                if (i == duplicateSameParameterAttributeUsages.CurrentUniqueAttributeUsagePosition)\r\n                {\r\n                    duplicateAttributeUsages.Add($\"[{duplicateSameParameterAttributeUsages.CurrentUniqueAttributeUsage}]\");\r\n                }\r\n\r\n                for (var j = 0; j < duplicateSameParameterAttributeUsages.Counts[i]; j++)\r\n                {\r\n                    duplicateAttributeUsages.Add($\"[{uniqueParameterAttributeUsages[i]}]\");\r\n                }\r\n            }\r\n\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    {{string.Join($\"{Environment.NewLine}    \", duplicateAttributeUsages)}}\r\n                    {{classMemberAccessModifier}}int Property { get; set; }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            DisableCompilerDiagnostics();\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory]\r\n        [MemberData(nameof(DuplicateAttributeUsageCountsAndNonPublicClassMemberAccessModifiersCombinations))]\r\n        public async Task A_nonpublic_property_annotated_with_more_than_one_parameter_attribute_should_not_trigger_diagnostic(int[] duplicateAttributeUsageCounts, string classMemberAccessModifier)\r\n        {\r\n            var duplicateAttributeUsages = new List<string>(duplicateAttributeUsageCounts.Sum());\r\n\r\n            var uniqueParameterAttributeUsages = UniqueParameterAttributeUsages.AsReadOnly();\r\n\r\n            for (var i = 0; i < duplicateAttributeUsageCounts.Length; i++)\r\n            {\r\n                for (var j = 0; j < duplicateAttributeUsageCounts[i]; j++)\r\n                {\r\n                    duplicateAttributeUsages.Add($\"[{uniqueParameterAttributeUsages[i]}]\");\r\n                }\r\n            }\r\n\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    {{string.Join($\"{Environment.NewLine}    \", duplicateAttributeUsages)}}\r\n                    {{classMemberAccessModifier}}int Property { get; set; }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task A_nonpublic_property_annotated_with_a_unique_parameter_attribute_should_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(UniqueParameterAttributes))] (string AttributeName, string AttributeUsage) attribute,\r\n            [CombinatorialMemberData(nameof(NonPublicClassMemberAccessModifiers))] string classMemberAccessModifier)\r\n        {\r\n            const string propertyIdentifier = \"Property\";\r\n\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [{{attribute.AttributeUsage}}]\r\n                    {{classMemberAccessModifier}}int {|#0:{{propertyIdentifier}}|} { get; set; }\r\n                }\r\n                \"\"\";\r\n            TestCode = testCode;\r\n            AddDefaultExpectedDiagnostic(propertyIdentifier, attribute.AttributeName);\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        public static IEnumerable<object[]> DuplicateAttributeUsageCountsAndNonPublicClassMemberAccessModifiersCombinations\r\n            => CombinationsGenerator.CombineArguments(DuplicateParameterAttributeUsageCounts, NonPublicClassMemberAccessModifiers);\r\n\r\n        public static TheoryData<string> UniqueParameterAttributeUsages\r\n            => [.. UniqueParameterAttributesTheoryData.Select(tdr => (tdr[1] as string)!)];\r\n\r\n        public static IEnumerable<(string AttributeName, string AttributeUsage)> UniqueParameterAttributes\r\n            => UniqueParameterAttributesTheoryData.Select(tdr => ((tdr[0] as string)!, (tdr[1] as string)!));\r\n\r\n        public static IEnumerable<string> NonPublicClassMemberAccessModifiers\r\n#pragma warning disable IDE0028 // Simplify collection initialization\r\n            => new NonPublicClassMemberAccessModifiersTheoryData();\r\n#pragma warning restore IDE0028 // Simplify collection initialization\r\n\r\n        public static IEnumerable<(string CurrentUniqueAttributeUsage, int CurrentUniqueAttributeUsagePosition, int[] Counts)> DuplicateSameParameterAttributeUsages\r\n            => DuplicateSameAttributeUsagesTheoryData.Select(tdr => ((tdr[0] as string)!, (int) tdr[1], (tdr[2] as int[])!));\r\n\r\n        public static TheoryData<int[]> DuplicateParameterAttributeUsageCounts\r\n            => DuplicateAttributeUsageCountsTheoryData;\r\n    }\r\n\r\n    public class NotValidOnReadonlyField : AnalyzerTestFixture<GeneralParameterAttributesAnalyzer>\r\n    {\r\n        public NotValidOnReadonlyField() : base(GeneralParameterAttributesAnalyzer.NotValidOnReadonlyFieldRule) { }\r\n\r\n        [Fact]\r\n        public async Task A_readonly_field_not_annotated_with_any_parameter_attribute_should_not_trigger_diagnostic()\r\n        {\r\n            const string testCode = /* lang=c#-test */ \"\"\"\r\n                public class BenchmarkClass\r\n                {\r\n                    public readonly int _field = 0, _field2 = 1;\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Fact]\r\n        public async Task A_readonly_field_annotated_with_a_nonparameter_attribute_should_not_trigger_diagnostic()\r\n        {\r\n            const string testCode = /* lang=c#-test */ \"\"\"\r\n                public class BenchmarkClass\r\n                {\r\n                    [Dummy]\r\n                    public readonly int _field = 0, _field2 = 1;\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceDummyAttribute();\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory]\r\n        [MemberData(nameof(UniqueParameterAttributeUsages))]\r\n        public async Task A_field_without_a_readonly_modifier_annotated_with_a_unique_parameter_attribute_should_not_trigger_diagnostic(string attributeUsage)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [{{attributeUsage}}]\r\n                    public int _field = 0, _field2 = 1;\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory]\r\n        [MemberData(nameof(DuplicateSameParameterAttributeUsages))]\r\n        public async Task A_readonly_field_annotated_with_the_same_duplicate_parameter_attribute_should_not_trigger_diagnostic(\r\n            string currentAttributeUsage,\r\n            int currentUniqueAttributeUsagePosition,\r\n            int[] duplicateSameAttributeUsageCounts)\r\n        {\r\n            var duplicateAttributeUsages = new List<string>(1 + duplicateSameAttributeUsageCounts.Sum());\r\n\r\n            var uniqueParameterAttributeUsages = UniqueParameterAttributeUsages.AsReadOnly();\r\n\r\n            for (var i = 0; i < duplicateSameAttributeUsageCounts.Length; i++)\r\n            {\r\n                if (i == currentUniqueAttributeUsagePosition)\r\n                {\r\n                    duplicateAttributeUsages.Add($\"[{currentAttributeUsage}]\");\r\n                }\r\n\r\n                for (var j = 0; j < duplicateSameAttributeUsageCounts[i]; j++)\r\n                {\r\n                    duplicateAttributeUsages.Add($\"[{uniqueParameterAttributeUsages[i]}]\");\r\n                }\r\n            }\r\n\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    {{string.Join($\"{Environment.NewLine}    \", duplicateAttributeUsages)}}\r\n                    public readonly int _field = 0, _field2 = 1;\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            DisableCompilerDiagnostics();\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory]\r\n        [MemberData(nameof(DuplicateParameterAttributeUsageCounts))]\r\n        public async Task A_readonly_field_annotated_with_more_than_one_parameter_attribute_should_not_trigger_diagnostic(int[] duplicateAttributeUsageCounts)\r\n        {\r\n            var duplicateAttributeUsages = new List<string>(duplicateAttributeUsageCounts.Sum());\r\n\r\n            var uniqueParameterAttributeUsages = UniqueParameterAttributeUsages.AsReadOnly();\r\n\r\n            for (var i = 0; i < duplicateAttributeUsageCounts.Length; i++)\r\n            {\r\n                for (var j = 0; j < duplicateAttributeUsageCounts[i]; j++)\r\n                {\r\n                    duplicateAttributeUsages.Add($\"[{uniqueParameterAttributeUsages[i]}]\");\r\n                }\r\n            }\r\n\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    {{string.Join($\"{Environment.NewLine}    \", duplicateAttributeUsages)}}\r\n                    public readonly int _field = 0, _field2 = 1;\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory]\r\n        [MemberData(nameof(UniqueParameterAttributes))]\r\n        public async Task A_readonly_field_annotated_with_a_unique_parameter_attribute_should_trigger_diagnostic(string attributeName, string attributeUsage)\r\n        {\r\n            const string fieldIdentifier = \"_field\";\r\n\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [{{attributeUsage}}]\r\n                    public {|#0:readonly|} int {{fieldIdentifier}} = 0, field2 = 1;\r\n                }\r\n                \"\"\";\r\n            TestCode = testCode;\r\n            AddDefaultExpectedDiagnostic(fieldIdentifier, attributeName);\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        public static TheoryData<string> UniqueParameterAttributeUsages\r\n            => [.. UniqueParameterAttributesTheoryData.Select(tdr => (tdr[1] as string)!)];\r\n\r\n        public static TheoryData<string, string> UniqueParameterAttributes\r\n            => UniqueParameterAttributesTheoryData;\r\n\r\n        public static TheoryData<string, int, int[]> DuplicateSameParameterAttributeUsages\r\n            => DuplicateSameAttributeUsagesTheoryData;\r\n\r\n        public static TheoryData<int[]> DuplicateParameterAttributeUsageCounts\r\n            => DuplicateAttributeUsageCountsTheoryData;\r\n    }\r\n\r\n    public class NotValidOnConstantField : AnalyzerTestFixture<GeneralParameterAttributesAnalyzer>\r\n    {\r\n        public NotValidOnConstantField() : base(GeneralParameterAttributesAnalyzer.NotValidOnConstantFieldRule) { }\r\n\r\n        [Fact]\r\n        public async Task A_constant_field_not_annotated_with_any_parameter_attribute_should_not_trigger_diagnostic()\r\n        {\r\n            const string testCode = /* lang=c#-test */ \"\"\"\r\n                public class BenchmarkClass\r\n                {\r\n                    public const int Constant = 0;\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Fact]\r\n        public async Task A_constant_field_annotated_with_a_nonparameter_attribute_should_not_trigger_diagnostic()\r\n        {\r\n            const string testCode = /* lang=c#-test */ \"\"\"\r\n                public class BenchmarkClass\r\n                {\r\n                    [Dummy]\r\n                    public const int Constant = 0;\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceDummyAttribute();\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory]\r\n        [MemberData(nameof(DuplicateSameParameterAttributeUsages))]\r\n        public async Task A_constant_field_annotated_with_the_same_duplicate_parameter_attribute_should_not_trigger_diagnostic(\r\n            string currentAttributeUsage,\r\n            int currentUniqueAttributeUsagePosition,\r\n            int[] duplicateSameAttributeUsageCounts)\r\n        {\r\n            var duplicateAttributeUsages = new List<string>(1 + duplicateSameAttributeUsageCounts.Sum());\r\n            var uniqueParameterAttributeUsages = UniqueParameterAttributeUsages.AsReadOnly();\r\n\r\n            for (var i = 0; i < duplicateSameAttributeUsageCounts.Length; i++)\r\n            {\r\n                if (i == currentUniqueAttributeUsagePosition)\r\n                {\r\n                    duplicateAttributeUsages.Add($\"[{currentAttributeUsage}]\");\r\n                }\r\n\r\n                for (var j = 0; j < duplicateSameAttributeUsageCounts[i]; j++)\r\n                {\r\n                    duplicateAttributeUsages.Add($\"[{uniqueParameterAttributeUsages[i]}]\");\r\n                }\r\n            }\r\n\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    {{string.Join($\"{Environment.NewLine}    \", duplicateAttributeUsages)}}\r\n                    public const int Constant = 0;\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            DisableCompilerDiagnostics();\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory]\r\n        [MemberData(nameof(DuplicateParameterAttributeUsageCounts))]\r\n        public async Task A_constant_field_annotated_with_more_than_one_parameter_attribute_should_not_trigger_diagnostic(int[] duplicateAttributeUsageCounts)\r\n        {\r\n            var duplicateAttributeUsages = new List<string>(duplicateAttributeUsageCounts.Sum());\r\n\r\n            var uniqueParameterAttributeUsages = UniqueParameterAttributeUsages.AsReadOnly();\r\n\r\n            for (var i = 0; i < duplicateAttributeUsageCounts.Length; i++)\r\n            {\r\n                for (var j = 0; j < duplicateAttributeUsageCounts[i]; j++)\r\n                {\r\n                    duplicateAttributeUsages.Add($\"[{uniqueParameterAttributeUsages[i]}]\");\r\n                }\r\n            }\r\n\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    {{string.Join($\"{Environment.NewLine}    \", duplicateAttributeUsages)}}\r\n                    public const int Constant = 0;\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory]\r\n        [MemberData(nameof(UniqueParameterAttributes))]\r\n        public async Task A_constant_field_annotated_with_a_unique_parameter_attribute_should_trigger_diagnostic(string attributeName, string attributeUsage)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [{{attributeUsage}}]\r\n                    public {|#0:const|} int Constant = 0;\r\n                }\r\n                \"\"\";\r\n            TestCode = testCode;\r\n            AddDefaultExpectedDiagnostic(attributeName);\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        public static TheoryData<string> UniqueParameterAttributeUsages\r\n            => [.. UniqueParameterAttributesTheoryData.Select(tdr => (tdr[1] as string)!)];\r\n\r\n        public static TheoryData<string, string> UniqueParameterAttributes\r\n            => UniqueParameterAttributesTheoryData;\r\n\r\n        public static TheoryData<string, int, int[]> DuplicateSameParameterAttributeUsages\r\n            => DuplicateSameAttributeUsagesTheoryData;\r\n\r\n        public static TheoryData<int[]> DuplicateParameterAttributeUsageCounts\r\n            => DuplicateAttributeUsageCountsTheoryData;\r\n    }\r\n\r\n#if NET5_0_OR_GREATER\r\n    public class PropertyCannotBeInitOnly : AnalyzerTestFixture<GeneralParameterAttributesAnalyzer>\r\n    {\r\n        public PropertyCannotBeInitOnly() : base(GeneralParameterAttributesAnalyzer.PropertyCannotBeInitOnlyRule) { }\r\n\r\n        [Fact]\r\n        public async Task An_initonly_property_not_annotated_with_any_parameter_attribute_should_not_trigger_diagnostic()\r\n        {\r\n            const string testCode = /* lang=c#-test */ \"\"\"\r\n                public class BenchmarkClass\r\n                {\r\n                    public int Property { get; init; }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Fact]\r\n        public async Task An_initonly_property_annotated_with_a_nonparameter_attribute_should_not_trigger_diagnostic()\r\n        {\r\n            const string testCode = /* lang=c#-test */ \"\"\"\r\n                public class BenchmarkClass\r\n                {\r\n                    [Dummy]\r\n                    public int Property { get; init; }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceDummyAttribute();\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory]\r\n        [MemberData(nameof(UniqueParameterAttributeUsages))]\r\n        public async Task A_property_with_an_assignable_setter_annotated_with_a_unique_parameter_attribute_should_not_trigger_diagnostic(string attributeUsage)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [{{attributeUsage}}]\r\n                    public int Property { get; set; }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory]\r\n        [MemberData(nameof(DuplicateSameParameterAttributeUsages))]\r\n        public async Task An_initonly_property_annotated_with_the_same_duplicate_parameter_attribute_should_not_trigger_diagnostic(\r\n            string currentAttributeUsage,\r\n            int currentUniqueAttributeUsagePosition,\r\n            int[] duplicateSameAttributeUsageCounts)\r\n        {\r\n            var duplicateAttributeUsages = new List<string>(1 + duplicateSameAttributeUsageCounts.Sum());\r\n\r\n            var uniqueParameterAttributeUsages = UniqueParameterAttributeUsages.AsReadOnly();\r\n\r\n            for (var i = 0; i < duplicateSameAttributeUsageCounts.Length; i++)\r\n            {\r\n                if (i == currentUniqueAttributeUsagePosition)\r\n                {\r\n                    duplicateAttributeUsages.Add($\"[{currentAttributeUsage}]\");\r\n                }\r\n\r\n                for (var j = 0; j < duplicateSameAttributeUsageCounts[i]; j++)\r\n                {\r\n                    duplicateAttributeUsages.Add($\"[{uniqueParameterAttributeUsages[i]}]\");\r\n                }\r\n            }\r\n\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    {{string.Join($\"{Environment.NewLine}    \", duplicateAttributeUsages)}}\r\n                    public int Property { get; init; }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            DisableCompilerDiagnostics();\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory]\r\n        [MemberData(nameof(DuplicateParameterAttributeUsageCounts))]\r\n        public async Task An_initonly_property_annotated_with_more_than_one_parameter_attribute_should_not_trigger_diagnostic(int[] duplicateAttributeUsageCounts)\r\n        {\r\n            var duplicateAttributeUsages = new List<string>(duplicateAttributeUsageCounts.Sum());\r\n\r\n            var uniqueParameterAttributeUsages = UniqueParameterAttributeUsages.AsReadOnly();\r\n\r\n            for (var i = 0; i < duplicateAttributeUsageCounts.Length; i++)\r\n            {\r\n                for (var j = 0; j < duplicateAttributeUsageCounts[i]; j++)\r\n                {\r\n                    duplicateAttributeUsages.Add($\"[{uniqueParameterAttributeUsages[i]}]\");\r\n                }\r\n            }\r\n\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    {{string.Join($\"{Environment.NewLine}    \", duplicateAttributeUsages)}}\r\n                    public int Property { get; init; }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory]\r\n        [MemberData(nameof(UniqueParameterAttributes))]\r\n        public async Task An_initonly_property_annotated_with_a_unique_parameter_attribute_should_trigger_diagnostic(string attributeName, string attributeUsage)\r\n        {\r\n            const string propertyIdentifier = \"Property\";\r\n\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [{{attributeUsage}}]\r\n                    public int {{propertyIdentifier}} { get; {|#0:init|}; }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            AddDefaultExpectedDiagnostic(propertyIdentifier, attributeName);\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        public static TheoryData<string> UniqueParameterAttributeUsages\r\n            => [.. UniqueParameterAttributesTheoryData.Select(tdr => (tdr[1] as string)!)];\r\n\r\n        public static TheoryData<string, string> UniqueParameterAttributes\r\n            => UniqueParameterAttributesTheoryData;\r\n\r\n        public static TheoryData<string, int, int[]> DuplicateSameParameterAttributeUsages\r\n            => DuplicateSameAttributeUsagesTheoryData;\r\n\r\n        public static TheoryData<int[]> DuplicateParameterAttributeUsageCounts\r\n            => DuplicateAttributeUsageCountsTheoryData;\r\n    }\r\n#endif\r\n    public class PropertyMustHavePublicSetter : AnalyzerTestFixture<GeneralParameterAttributesAnalyzer>\r\n    {\r\n        public PropertyMustHavePublicSetter() : base(GeneralParameterAttributesAnalyzer.PropertyMustHavePublicSetterRule) { }\r\n\r\n        [Theory]\r\n        [MemberData(nameof(NonPublicPropertySettersTheoryData))]\r\n        public async Task A_property_with_a_nonpublic_setter_not_annotated_with_any_parameter_attribute_should_not_trigger_diagnostic(string nonPublicPropertySetter)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                public class BenchmarkClass\r\n                {\r\n                    public int Property {{nonPublicPropertySetter}}\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory]\r\n        [MemberData(nameof(NonPublicPropertySettersTheoryData))]\r\n        public async Task A_property_with_a_nonpublic_setter_annotated_with_a_nonparameter_attribute_should_not_trigger_diagnostic(string nonPublicPropertySetter)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                public class BenchmarkClass\r\n                {\r\n                    [Dummy]\r\n                    public int Property {{nonPublicPropertySetter}}\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceDummyAttribute();\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory]\r\n        [MemberData(nameof(UniqueParameterAttributeUsages))]\r\n        public async Task A_property_with_an_assignable_setter_annotated_with_a_unique_parameter_attribute_should_not_trigger_diagnostic(string attributeUsage)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [{{attributeUsage}}]\r\n                    public int Property { get; set; }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task A_property_with_a_nonpublic_setter_annotated_with_the_same_duplicate_parameter_attribute_should_not_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(DuplicateSameParameterAttributeUsages))] (string CurrentUniqueAttributeUsage, int CurrentUniqueAttributeUsagePosition, int[] Counts) duplicateSameParameterAttributeUsages,\r\n            [CombinatorialMemberData(nameof(NonPublicPropertySetters))] string nonPublicPropertySetter)\r\n        {\r\n            var duplicateAttributeUsages = new List<string>(1 + duplicateSameParameterAttributeUsages.Counts.Sum());\r\n\r\n            var uniqueParameterAttributeUsages = UniqueParameterAttributeUsages.AsReadOnly();\r\n\r\n            for (var i = 0; i < duplicateSameParameterAttributeUsages.Counts.Length; i++)\r\n            {\r\n                if (i == duplicateSameParameterAttributeUsages.CurrentUniqueAttributeUsagePosition)\r\n                {\r\n                    duplicateAttributeUsages.Add($\"[{duplicateSameParameterAttributeUsages.CurrentUniqueAttributeUsage}]\");\r\n                }\r\n\r\n                for (var j = 0; j < duplicateSameParameterAttributeUsages.Counts[i]; j++)\r\n                {\r\n                    duplicateAttributeUsages.Add($\"[{uniqueParameterAttributeUsages[i]}]\");\r\n                }\r\n            }\r\n\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    {{string.Join($\"{Environment.NewLine}    \", duplicateAttributeUsages)}}\r\n                    public int Property {{nonPublicPropertySetter}}\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            DisableCompilerDiagnostics();\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory]\r\n        [MemberData(nameof(DuplicateAttributeUsageCountsAndNonPublicPropertySetterCombinations))]\r\n        public async Task A_property_with_a_nonpublic_setter_annotated_with_more_than_one_parameter_attribute_should_not_trigger_diagnostic(int[] duplicateAttributeUsageCounts, string nonPublicPropertySetter)\r\n        {\r\n            var duplicateAttributeUsages = new List<string>(duplicateAttributeUsageCounts.Sum());\r\n\r\n            var uniqueParameterAttributeUsages = UniqueParameterAttributeUsages.AsReadOnly();\r\n\r\n            for (var i = 0; i < duplicateAttributeUsageCounts.Length; i++)\r\n            {\r\n                for (var j = 0; j < duplicateAttributeUsageCounts[i]; j++)\r\n                {\r\n                    duplicateAttributeUsages.Add($\"[{uniqueParameterAttributeUsages[i]}]\");\r\n                }\r\n            }\r\n\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    {{string.Join($\"{Environment.NewLine}    \", duplicateAttributeUsages)}}\r\n                    public int Property {{nonPublicPropertySetter}}\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task A_property_with_a_nonpublic_setter_annotated_with_a_unique_parameter_attribute_should_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(UniqueParameterAttributes))] (string AttributeName, string AttributeUsage) attribute,\r\n            [CombinatorialMemberData(nameof(NonPublicPropertySetters))] string nonPublicPropertySetter)\r\n        {\r\n            const string propertyIdentifier = \"Property\";\r\n\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [{{attribute.AttributeUsage}}]\r\n                    public int {|#0:{{propertyIdentifier}}|} {{nonPublicPropertySetter}}\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            AddDefaultExpectedDiagnostic(propertyIdentifier, attribute.AttributeName);\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        public static IEnumerable<object[]> DuplicateAttributeUsageCountsAndNonPublicPropertySetterCombinations\r\n            => CombinationsGenerator.CombineArguments(DuplicateParameterAttributeUsageCounts, NonPublicPropertySetters());\r\n\r\n        public static TheoryData<string> UniqueParameterAttributeUsages\r\n            => [.. UniqueParameterAttributesTheoryData.Select(tdr => (tdr[1] as string)!)];\r\n\r\n        public static IEnumerable<(string AttributeName, string AttributeUsage)> UniqueParameterAttributes\r\n            => UniqueParameterAttributesTheoryData.Select(tdr => ((tdr[0] as string)!, (tdr[1] as string)!));\r\n\r\n        public static IEnumerable<(string CurrentUniqueAttributeUsage, int CurrentUniqueAttributeUsagePosition, int[] Counts)> DuplicateSameParameterAttributeUsages\r\n            => DuplicateSameAttributeUsagesTheoryData.Select(tdr => ((tdr[0] as string)!, (int) tdr[1], (tdr[2] as int[])!));\r\n\r\n        public static TheoryData<int[]> DuplicateParameterAttributeUsageCounts\r\n            => DuplicateAttributeUsageCountsTheoryData;\r\n\r\n        public static IEnumerable<string> NonPublicPropertySetters()\r\n            => new NonPublicPropertySetterAccessModifiersTheoryData()\r\n            .Select<string, string>(m => $\"{{ get; {m} set; }}\")\r\n            .Concat([\"{ get; }\", \"=> 0;\"]);\r\n\r\n        public static TheoryData<string> NonPublicPropertySettersTheoryData()\r\n            => [.. NonPublicPropertySetters()];\r\n    }\r\n\r\n    public class ParamsSourceCannotUseWriteOnlyProperty : AnalyzerTestFixture<GeneralParameterAttributesAnalyzer>\r\n    {\r\n        public ParamsSourceCannotUseWriteOnlyProperty() : base(GeneralParameterAttributesAnalyzer.ParamsSourceCannotUseWriteOnlyPropertyRule) { }\r\n\r\n        [Fact]\r\n        public async Task UsingNameofWithWriteOnlyProperty_ShouldReportError()\r\n        {\r\n            var testCode = /* lang=c#-test */ \"\"\"\r\n                using System.Collections.Generic;\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    private int _value;\r\n\r\n                    public int WriteOnlyProperty\r\n                    {\r\n                        set { _value = value; }\r\n                    }\r\n\r\n                    [ParamsSource({|#0:nameof(WriteOnlyProperty)|})]\r\n                    public int MyParam { get; set; }\r\n\r\n                    [Benchmark]\r\n                    public void Run() { }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            AddExpectedDiagnostic(0, DiagnosticSeverity.Error, \"WriteOnlyProperty\");\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Fact]\r\n        public async Task UsingStringLiteralWithWriteOnlyProperty_ShouldReportError()\r\n        {\r\n            var testCode = /* lang=c#-test */ \"\"\"\r\n                using System.Collections.Generic;\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    private int _value;\r\n\r\n                    public int WriteOnlyProperty\r\n                    {\r\n                        set { _value = value; }\r\n                    }\r\n\r\n                    [ParamsSource({|#0:\"WriteOnlyProperty\"|})]\r\n                    public int MyParam { get; set; }\r\n\r\n                    [Benchmark]\r\n                    public void Run() { }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            AddExpectedDiagnostic(0, DiagnosticSeverity.Error, \"WriteOnlyProperty\");\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Fact]\r\n        public async Task UsingTwoParameterConstructorWithWriteOnlyProperty_ShouldReportError()\r\n        {\r\n            var testCode = /* lang=c#-test */ \"\"\"\r\n                using System.Collections.Generic;\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class OtherClass\r\n                {\r\n                    private int _value;\r\n\r\n                    public int WriteOnlyProperty\r\n                    {\r\n                        set { _value = value; }\r\n                    }\r\n                }\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [ParamsSource(typeof(OtherClass), {|#0:nameof(OtherClass.WriteOnlyProperty)|})]\r\n                    public int MyParam { get; set; }\r\n\r\n                    [Benchmark]\r\n                    public void Run() { }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            AddExpectedDiagnostic(0, DiagnosticSeverity.Error, \"WriteOnlyProperty\");\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Fact]\r\n        public async Task UsingNameofWithReadWriteProperty_ShouldNotReportError()\r\n        {\r\n            var testCode = /* lang=c#-test */ \"\"\"\r\n                using System.Collections.Generic;\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    public static int[] ValidValues { get; set; } = new[] { 1, 2, 3 };\r\n\r\n                    [ParamsSource(nameof(ValidValues))]\r\n                    public int MyParam { get; set; }\r\n\r\n                    [Benchmark]\r\n                    public void Run() { }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            await RunAsync();\r\n        }\r\n\r\n        [Fact]\r\n        public async Task UsingNameofWithReadOnlyProperty_ShouldNotReportError()\r\n        {\r\n            var testCode = /* lang=c#-test */ \"\"\"\r\n                using System.Collections.Generic;\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    public static IEnumerable<int> ValidValues => new[] { 1, 2, 3 };\r\n\r\n                    [ParamsSource(nameof(ValidValues))]\r\n                    public int MyParam { get; set; }\r\n\r\n                    [Benchmark]\r\n                    public void Run() { }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            await RunAsync();\r\n        }\r\n    }\r\n    \r\n    public static TheoryData<string, string> UniqueParameterAttributesTheoryData\r\n        => new()\r\n        {\r\n            { \"Params\", \"Params(3)\" },\r\n            { \"ParamsSource\", \"ParamsSource(\\\"test\\\")\" },\r\n            { \"ParamsAllValues\", \"ParamsAllValues\" }\r\n        };\r\n\r\n    public static TheoryData<string, int, int[]> DuplicateSameAttributeUsagesTheoryData\r\n    {\r\n        get\r\n        {\r\n            var theoryData = new TheoryData<string, int, int[]>();\r\n\r\n            foreach (var (CurrentUniqueAttributeUsage, CurrentUniqueAttributeUsagePosition, Counts) in GenerateDuplicateSameAttributeUsageCombinations(UniqueParameterAttributesTheoryData))\r\n            {\r\n                theoryData.Add(CurrentUniqueAttributeUsage, CurrentUniqueAttributeUsagePosition, Counts);\r\n            }\r\n\r\n            return theoryData;\r\n        }\r\n    }\r\n\r\n    public static TheoryData<int[]> DuplicateAttributeUsageCountsTheoryData\r\n        => [.. GenerateDuplicateAttributeUsageCombinations(UniqueParameterAttributesTheoryData)];\r\n\r\n    private static IEnumerable<int[]> GenerateDuplicateAttributeUsageCombinations(TheoryData<string, string> uniqueAttributeUsages)\r\n    {\r\n        var uniqueAttributeUsagesList = uniqueAttributeUsages.ToList().AsReadOnly();\r\n\r\n        var allCombinations = CombinationsGenerator.GenerateCombinationsCounts(uniqueAttributeUsagesList.Count, 1);\r\n\r\n        foreach (var currentCombination in allCombinations)\r\n        {\r\n            if (currentCombination.Sum() >= 2)\r\n            {\r\n                yield return currentCombination;\r\n            }\r\n        }\r\n    }\r\n\r\n    private static ReadOnlyCollection<(string CurrentUniqueAttributeUsage, int CurrentUniqueAttributeUsagePosition, int[] Counts)> GenerateDuplicateSameAttributeUsageCombinations(TheoryData<string, string> uniqueAttributeUsages)\r\n    {\r\n        var uniqueAttributeUsagesList = uniqueAttributeUsages\r\n            .Select(tdr => (tdr[1] as string)!)\r\n            .ToList()\r\n            .AsReadOnly();\r\n\r\n        var finalCombinationsList = new List<(string CurrentUniqueAttributeUsage, int CurrentUniqueAttributeUsagePosition, int[] Counts)>();\r\n\r\n        var allCombinations = CombinationsGenerator.GenerateCombinationsCounts(uniqueAttributeUsagesList.Count, 2)\r\n            .ToList()\r\n            .AsReadOnly();\r\n\r\n        for (var i = 0; i < uniqueAttributeUsagesList.Count; i++)\r\n        {\r\n            foreach (var currentCombination in allCombinations)\r\n            {\r\n                if (currentCombination[i] > 0)\r\n                {\r\n                    finalCombinationsList.Add((uniqueAttributeUsagesList[i], i, currentCombination));\r\n                }\r\n            }\r\n        }\r\n\r\n        return finalCombinationsList.AsReadOnly();\r\n    }\r\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Analyzers.Tests/AnalyzerTests/Attributes/ParamsAllValuesAttributeAnalyzerTests.cs",
    "content": "﻿using BenchmarkDotNet.Analyzers.Attributes;\r\nusing BenchmarkDotNet.Analyzers.Tests.Fixtures;\r\nusing System.Collections.Generic;\r\nusing System.Linq;\r\nusing System.Threading.Tasks;\r\nusing Xunit;\r\n\r\nnamespace BenchmarkDotNet.Analyzers.Tests.AnalyzerTests.Attributes;\r\n\r\npublic class ParamsAllValuesAttributeAnalyzerTests\r\n{\r\n    public class General : AnalyzerTestFixture<ParamsAllValuesAttributeAnalyzer>\r\n    {\r\n        [Theory, CombinatorialData]\r\n        public async Task A_field_or_property_not_annotated_with_the_paramsallvalues_attribute_should_not_trigger_diagnostic(\r\n            [CombinatorialValues(\"\", \"[Dummy]\")] string missingParamsAttributeUsage,\r\n            [CombinatorialMemberData(nameof(FieldOrPropertyDeclarations))] string fieldOrPropertyDeclaration,\r\n            [CombinatorialMemberData(nameof(InvalidTypes))] string invalidType)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    {{missingParamsAttributeUsage}}\r\n                    public {{invalidType}} {{fieldOrPropertyDeclaration}}\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceDummyAttribute();\r\n            ReferenceDummyEnumWithFlagsAttribute();\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        public static IEnumerable<string> FieldOrPropertyDeclarations\r\n#pragma warning disable IDE0028 // Simplify collection initialization\r\n            => new FieldOrPropertyDeclarationsTheoryData();\r\n#pragma warning restore IDE0028 // Simplify collection initialization\r\n\r\n        public static IEnumerable<string> InvalidTypes =>\r\n        [\r\n            \"byte\",\r\n            \"char\",\r\n            \"double\",\r\n            \"float\",\r\n            \"int\",\r\n            \"long\",\r\n            \"sbyte\",\r\n            \"short\",\r\n            \"string\",\r\n            \"uint\",\r\n            \"ulong\",\r\n            \"ushort\",\r\n\r\n            \"DummyEnumWithFlagsAttribute\",\r\n\r\n            \"object\",\r\n            \"System.Type\"\r\n        ];\r\n    }\r\n\r\n    public class NotAllowedOnFlagsEnumPropertyOrFieldType : AnalyzerTestFixture<ParamsAllValuesAttributeAnalyzer>\r\n    {\r\n        public NotAllowedOnFlagsEnumPropertyOrFieldType() : base(ParamsAllValuesAttributeAnalyzer.NotAllowedOnFlagsEnumPropertyOrFieldTypeRule) { }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task A_field_or_property_of_nonnullable_nonenum_type_should_not_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(FieldOrPropertyDeclarations))] string fieldOrPropertyDeclaration,\r\n            [CombinatorialMemberData(nameof(NonEnumTypes))] string nonEnumType)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [ParamsAllValues]\r\n                    public {{nonEnumType}} {{fieldOrPropertyDeclaration}}\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task A_field_or_property_of_nullable_nonenum_type_should_not_trigger_diagnostic(\r\n            bool isNullable,\r\n            [CombinatorialMemberData(nameof(FieldOrPropertyDeclarations))] string fieldOrPropertyDeclaration,\r\n            [CombinatorialMemberData(nameof(NonEnumStructs))] string nonEnumType)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [ParamsAllValues]\r\n                    public {{nonEnumType}}{{(isNullable ? \"?\" : \"\")}} {{fieldOrPropertyDeclaration}}\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task A_field_or_property_of_enum_type_without_a_flags_attribute_should_not_trigger_diagnostic(\r\n            bool isNullable,\r\n            [CombinatorialMemberData(nameof(FieldOrPropertyDeclarations))] string fieldOrPropertyDeclaration)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [ParamsAllValues]\r\n                    public DummyEnum{{(isNullable ? \"?\" : \"\")}} {{fieldOrPropertyDeclaration}}\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceDummyEnum();\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task A_field_or_property_of_enum_type_with_a_flags_attribute_should_trigger_diagnostic(\r\n            bool isNullable,\r\n            [CombinatorialMemberData(nameof(FieldOrPropertyDeclarations))] string fieldOrPropertyDeclaration)\r\n        {\r\n            const string enumTypeName = \"DummyEnumWithFlagsAttribute\";\r\n\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [ParamsAllValues]\r\n                    public {|#0:{{enumTypeName}}|}{{(isNullable ? \"?\" : \"\")}} {{fieldOrPropertyDeclaration}}\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceDummyEnumWithFlagsAttribute();\r\n            AddDefaultExpectedDiagnostic(enumTypeName);\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        public static IEnumerable<string> FieldOrPropertyDeclarations\r\n#pragma warning disable IDE0028 // Simplify collection initialization\r\n            => new FieldOrPropertyDeclarationsTheoryData();\r\n#pragma warning restore IDE0028 // Simplify collection initialization\r\n\r\n        public static IEnumerable<string> NonEnumStructs =>\r\n        [\r\n            \"bool\",\r\n            \"byte\",\r\n            \"char\",\r\n            \"double\",\r\n            \"float\",\r\n            \"int\",\r\n            \"long\",\r\n            \"sbyte\",\r\n            \"short\",\r\n            \"uint\",\r\n            \"ulong\",\r\n            \"ushort\",\r\n        ];\r\n\r\n        public static IEnumerable<string> NonEnumTypes => NonEnumStructs.Concat(\r\n        [\r\n            \"string\",\r\n            \"object\",\r\n            \"System.Type\"\r\n        ]);\r\n    }\r\n\r\n    public class PropertyOrFieldTypeMustBeEnumOrBool : AnalyzerTestFixture<ParamsAllValuesAttributeAnalyzer>\r\n    {\r\n        public PropertyOrFieldTypeMustBeEnumOrBool() : base(ParamsAllValuesAttributeAnalyzer.PropertyOrFieldTypeMustBeEnumOrBoolRule) { }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task A_field_or_property_of_enum_or_bool_type_should_not_trigger_diagnostic(\r\n            bool isNullable,\r\n            [CombinatorialValues(\"DummyEnum\", \"bool\")] string enumOrBoolType,\r\n            [CombinatorialMemberData(nameof(FieldOrPropertyDeclarations))] string fieldOrPropertyDeclaration)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [ParamsAllValues]\r\n                    public {{enumOrBoolType}}{{(isNullable ? \"?\" : \"\")}}  {{fieldOrPropertyDeclaration}}\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceDummyEnum();\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task A_field_or_property_not_of_nonnullable_enum_or_bool_type_should_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(NonEnumOrBoolTypes))] string nonEnumOrBoolType,\r\n            [CombinatorialMemberData(nameof(FieldOrPropertyDeclarations))] string fieldOrPropertyDeclaration)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [ParamsAllValues]\r\n                    public {|#0:{{nonEnumOrBoolType}}|} {{fieldOrPropertyDeclaration}}\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceDummyEnum();\r\n            AddDefaultExpectedDiagnostic();\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task A_field_or_property_not_of_nullable_enum_or_bool_type_should_trigger_diagnostic(\r\n            bool isNullable,\r\n            [CombinatorialMemberData(nameof(NonEnumOrBoolStructs))] string nonEnumOrBoolType,\r\n            [CombinatorialMemberData(nameof(FieldOrPropertyDeclarations))] string fieldOrPropertyDeclaration)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [ParamsAllValues]\r\n                    public {|#0:{{nonEnumOrBoolType}}|}{{(isNullable ? \"?\" : \"\")}} {{fieldOrPropertyDeclaration}}\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceDummyEnum();\r\n            AddDefaultExpectedDiagnostic();\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        public static IEnumerable<string> FieldOrPropertyDeclarations\r\n#pragma warning disable IDE0028 // Simplify collection initialization\r\n            => new FieldOrPropertyDeclarationsTheoryData();\r\n#pragma warning restore IDE0028 // Simplify collection initialization\r\n\r\n        public static IEnumerable<string> NonEnumOrBoolStructs =>\r\n        [\r\n            \"byte\",\r\n            \"char\",\r\n            \"double\",\r\n            \"float\",\r\n            \"int\",\r\n            \"long\",\r\n            \"sbyte\",\r\n            \"short\",\r\n            \"uint\",\r\n            \"ulong\",\r\n            \"ushort\"\r\n        ];\r\n\r\n        public static IEnumerable<string> NonEnumOrBoolTypes => NonEnumOrBoolStructs.Concat(\r\n        [\r\n           \"string\",\r\n           \"object\",\r\n           \"System.Type\"\r\n        ]);\r\n    }\r\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Analyzers.Tests/AnalyzerTests/Attributes/ParamsAttributeAnalyzerTests.cs",
    "content": "﻿using BenchmarkDotNet.Analyzers.Attributes;\r\nusing BenchmarkDotNet.Analyzers.Tests.Fixtures;\r\nusing Microsoft.CodeAnalysis.CSharp;\r\nusing System.Collections.Generic;\r\nusing System.Collections.ObjectModel;\r\nusing System.Linq;\r\nusing System.Threading.Tasks;\r\nusing Xunit;\r\n\r\nnamespace BenchmarkDotNet.Analyzers.Tests.AnalyzerTests.Attributes;\r\n\r\npublic class ParamsAttributeAnalyzerTests\r\n{\r\n    public class General : AnalyzerTestFixture<ParamsAttributeAnalyzer>\r\n    {\r\n        [Theory, CombinatorialData]\r\n        public async Task A_field_or_property_not_annotated_with_the_params_attribute_should_not_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(FieldOrPropertyDeclarations))] string fieldOrPropertyDeclaration,\r\n            [CombinatorialValues(\"\", \"[Dummy]\")] string missingParamsAttributeUsage)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    {{missingParamsAttributeUsage}}\r\n                    public string {{fieldOrPropertyDeclaration}}\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceDummyAttribute();\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        public static IEnumerable<string> FieldOrPropertyDeclarations\r\n#pragma warning disable IDE0028 // Simplify collection initialization\r\n            => new FieldOrPropertyDeclarationsTheoryData();\r\n#pragma warning restore IDE0028 // Simplify collection initialization\r\n    }\r\n\r\n    public class MustHaveValues : AnalyzerTestFixture<ParamsAttributeAnalyzer>\r\n    {\r\n        public MustHaveValues() : base(ParamsAttributeAnalyzer.MustHaveValuesRule) { }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Providing_one_or_more_values_should_not_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(FieldOrPropertyDeclarations))] string fieldOrPropertyDeclaration,\r\n            [CombinatorialMemberData(nameof(DummyAttributeUsage))] string dummyAttributeUsage,\r\n            [CombinatorialMemberData(nameof(ScalarValuesListLength))] int scalarValuesListLength,\r\n            [CombinatorialMemberData(nameof(ScalarValuesContainerAttributeArgument))] string scalarValuesContainerAttributeArgument)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [{{dummyAttributeUsage}}Params({{string.Format(scalarValuesContainerAttributeArgument, string.Join(\", \", ScalarValues.Take(scalarValuesListLength)))}})]\r\n                    public string {{fieldOrPropertyDeclaration}}\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceDummyAttribute();\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Providing_an_array_with_a_rank_specifier_size_higher_than_zero_should_not_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(FieldOrPropertyDeclarations))] string fieldOrPropertyDeclaration,\r\n            [CombinatorialMemberData(nameof(DummyAttributeUsage))] string dummyAttributeUsage,\r\n            [CombinatorialRange(1, 2)] int rankSpecifierSize)\r\n        {\r\n            Assert.True(rankSpecifierSize > 0);\r\n\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [{{dummyAttributeUsage}}Params(new object[{{rankSpecifierSize}}])]\r\n                    public string {{fieldOrPropertyDeclaration}}\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            DisableCompilerDiagnostics();\r\n            ReferenceDummyAttribute();\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Providing_no_values_should_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(FieldOrPropertyDeclarations))] string fieldOrPropertyDeclaration,\r\n            [CombinatorialMemberData(nameof(DummyAttributeUsage))] string dummyAttributeUsage,\r\n            [CombinatorialMemberData(nameof(EmptyParamsAttributeUsagesWithLocationMarker))] string emptyParamsAttributeUsage)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [{{dummyAttributeUsage}}{{emptyParamsAttributeUsage}}]\r\n                    public string {{fieldOrPropertyDeclaration}}\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceDummyAttribute();\r\n            AddDefaultExpectedDiagnostic();\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        public static IEnumerable<string> FieldOrPropertyDeclarations\r\n#pragma warning disable IDE0028 // Simplify collection initialization\r\n            => new FieldOrPropertyDeclarationsTheoryData();\r\n#pragma warning restore IDE0028 // Simplify collection initialization\r\n\r\n        public static IEnumerable<string> DummyAttributeUsage\r\n            => DummyAttributeUsageTheoryData;\r\n\r\n        public static IEnumerable<int> ScalarValuesListLength\r\n            => Enumerable.Range(1, ScalarValues.Count);\r\n\r\n        private static ReadOnlyCollection<string> ScalarValues\r\n            => Enumerable.Range(1, 3)\r\n            .Select(i => $\"\\\"test{i}\\\"\")\r\n            .ToList()\r\n            .AsReadOnly();\r\n\r\n        public static IEnumerable<string> ScalarValuesContainerAttributeArgument\r\n            => ScalarValuesContainerAttributeArgumentTheoryData();\r\n\r\n        public static IEnumerable<string> EmptyParamsAttributeUsagesWithLocationMarker()\r\n        {\r\n            yield return \"{|#0:Params|}\";\r\n            yield return \"{|#0:Params()|}\";\r\n            yield return \"{|#0:Params(Priority = 1)|}\";\r\n\r\n            string[] nameColonUsages =\r\n            [\r\n                \"\",\r\n                \"values: \"\r\n            ];\r\n\r\n            string[] priorityNamedParameterUsages =\r\n            [\r\n                \"\",\r\n                \", Priority = 1\"\r\n            ];\r\n\r\n            string[] attributeUsagesBase =\r\n            [\r\n                \"{{|#0:Params({0}new object[] {{ }}{1})|}}\",\r\n                \"{{|#0:Params({0}new object[0]{1})|}}\",\r\n                \"{{|#0:Params({0}[ ]{1})|}}\",\r\n            ];\r\n\r\n            foreach (var attributeUsageBase in attributeUsagesBase)\r\n            {\r\n                foreach (var nameColonUsage in nameColonUsages)\r\n                {\r\n                    foreach (var priorityNamedParameterUsage in priorityNamedParameterUsages)\r\n                    {\r\n                        yield return string.Format(attributeUsageBase, nameColonUsage, priorityNamedParameterUsage);\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    public class MustHaveMatchingValueType : AnalyzerTestFixture<ParamsAttributeAnalyzer>\r\n    {\r\n        public MustHaveMatchingValueType() : base(ParamsAttributeAnalyzer.MustHaveMatchingValueTypeRule) { }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Analyzing_a_params_attribute_should_not_throw_an_inconsistent_language_versions_exception(\r\n            [CombinatorialMemberData(nameof(FieldOrPropertyDeclarations))] string fieldOrPropertyDeclaration,\r\n            [CombinatorialMemberData(nameof(DummyAttributeUsage))] string dummyAttributeUsage,\r\n            [CombinatorialMemberData(nameof(ScalarValuesContainerAttributeArgumentEnumerable))] string scalarValuesContainerAttributeArgument)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [{{dummyAttributeUsage}}Params({{string.Format(scalarValuesContainerAttributeArgument, \"42\")}})]\r\n                    public int {{fieldOrPropertyDeclaration}}\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceDummyAttribute();\r\n            SetParseOptions(LanguageVersion.CSharp14);\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Analyzing_a_params_attribute_should_not_throw_an_inconsistent_syntax_tree_features_exception(\r\n            [CombinatorialMemberData(nameof(FieldOrPropertyDeclarations))] string fieldOrPropertyDeclaration,\r\n            [CombinatorialMemberData(nameof(DummyAttributeUsage))] string dummyAttributeUsage,\r\n            [CombinatorialMemberData(nameof(ScalarValuesContainerAttributeArgumentEnumerable))] string scalarValuesContainerAttributeArgument)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [{{dummyAttributeUsage}}Params({{string.Format(scalarValuesContainerAttributeArgument, \"42\")}})]\r\n                    public int {{fieldOrPropertyDeclaration}}\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceDummyAttribute();\r\n            SetParseOptions(LanguageVersion.Default, true);\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Providing_a_field_or_property_with_an_unknown_type_should_not_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(FieldOrPropertyDeclarations))] string fieldOrPropertyDeclaration,\r\n            [CombinatorialMemberData(nameof(DummyAttributeUsage))] string dummyAttributeUsage,\r\n            [CombinatorialMemberData(nameof(ScalarValuesContainerAttributeArgumentEnumerable))] string scalarValuesContainerAttributeArgument)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [{{dummyAttributeUsage}}Params({{string.Format(scalarValuesContainerAttributeArgument, \"42, 51, 33\")}})]\r\n                    public unknown {{fieldOrPropertyDeclaration}}\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceDummyAttribute();\r\n            DisableCompilerDiagnostics();\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Providing_expected_value_type_should_not_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(DummyAttributeUsage))] string dummyAttributeUsage,\r\n            [CombinatorialMemberData(nameof(ValuesAndTypes))] ValueTupleDouble<string, string> valueAndType,\r\n            [CombinatorialMemberData(nameof(ScalarValuesContainerAttributeArgumentEnumerable))] string scalarValuesContainerAttributeArgument,\r\n            [CombinatorialMemberData(nameof(FieldOrPropertyDeclarations))] string fieldOrPropertyDeclaration)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using DifferentNamespace;\r\n                \r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [{{dummyAttributeUsage}}Params({{string.Format(scalarValuesContainerAttributeArgument, valueAndType.Value1)}})]\r\n                    public {{valueAndType.Value2}} {{fieldOrPropertyDeclaration}}\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceDummyAttribute();\r\n            ReferenceDummyEnum();\r\n            ReferenceDummyEnumInDifferentNamespace();\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Providing_expected_enum_value_type_using_not_fully_qualified_name_located_in_a_different_namespace_should_not_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(DummyAttributeUsage))] string dummyAttributeUsage,\r\n            [CombinatorialMemberData(nameof(ScalarValuesContainerAttributeArgumentEnumerable))] string scalarValuesContainerAttributeArgument,\r\n            bool isNullable,\r\n            [CombinatorialMemberData(nameof(FieldOrPropertyDeclarations))] string fieldOrPropertyDeclaration)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using DifferentNamespace;\r\n\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [{{dummyAttributeUsage}}Params({{string.Format(scalarValuesContainerAttributeArgument, \"DummyEnumInDifferentNamespace.Value1\")}})]\r\n                    public DummyEnumInDifferentNamespace{{(isNullable ? \"?\" : \"\")}} {{fieldOrPropertyDeclaration}}\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceDummyAttribute();\r\n            ReferenceDummyEnum();\r\n            ReferenceDummyEnumInDifferentNamespace();\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Providing_expected_enum_value_type_using_not_fully_qualified_name_located_in_same_namespace_should_not_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(DummyAttributeUsage))] string dummyAttributeUsage,\r\n            [CombinatorialMemberData(nameof(ScalarValuesContainerAttributeArgumentEnumerable))] string scalarValuesContainerAttributeArgument,\r\n            bool isNullable,\r\n            [CombinatorialMemberData(nameof(FieldOrPropertyDeclarations))] string fieldOrPropertyDeclaration)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                namespace DifferentNamespace;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [{{dummyAttributeUsage}}Params({{string.Format(scalarValuesContainerAttributeArgument, \"DummyEnumInDifferentNamespace.Value1\")}})]\r\n                    public DummyEnumInDifferentNamespace{{(isNullable ? \"?\" : \"\")}} {{fieldOrPropertyDeclaration}}\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceDummyAttribute();\r\n            ReferenceDummyEnum();\r\n            ReferenceDummyEnumInDifferentNamespace();\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Providing_expected_enum_value_type_array_using_not_fully_qualified_name_located_in_a_different_namespace_should_not_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(DummyAttributeUsage))] string dummyAttributeUsage,\r\n            [CombinatorialMemberData(nameof(ArrayValuesContainerAttributeArgumentEnumerableLocal))] string arrayValuesContainerAttributeArgument,\r\n            bool isNullable,\r\n            [CombinatorialMemberData(nameof(FieldOrPropertyDeclarations))] string fieldOrPropertyDeclaration)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using DifferentNamespace;\r\n                \r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [{{dummyAttributeUsage}}Params({{string.Format(arrayValuesContainerAttributeArgument, \"DummyEnumInDifferentNamespace.Value1\", $\"DummyEnumInDifferentNamespace{(isNullable ? \"?\" : \"\")}\")}})]\r\n                    public DummyEnumInDifferentNamespace[] {{fieldOrPropertyDeclaration}}\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceDummyAttribute();\r\n            ReferenceDummyEnum();\r\n            ReferenceDummyEnumInDifferentNamespace();\r\n            DisableCompilerDiagnostics();                   // Nullable struct arrays are not supported in attributes\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Providing_expected_enum_value_type_array_using_not_fully_qualified_name_located_in_same_namespace_should_not_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(DummyAttributeUsage))] string dummyAttributeUsage,\r\n            [CombinatorialMemberData(nameof(ArrayValuesContainerAttributeArgumentEnumerableLocal))] string arrayValuesContainerAttributeArgument,\r\n            bool isNullable,\r\n            [CombinatorialMemberData(nameof(FieldOrPropertyDeclarations))] string fieldOrPropertyDeclaration)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                namespace DifferentNamespace;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [{{dummyAttributeUsage}}Params({{string.Format(arrayValuesContainerAttributeArgument, \"DummyEnumInDifferentNamespace.Value1\", $\"DummyEnumInDifferentNamespace{(isNullable ? \"?\" : \"\")}\")}})]\r\n                    public DummyEnumInDifferentNamespace[] {{fieldOrPropertyDeclaration}}\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceDummyAttribute();\r\n            ReferenceDummyEnum();\r\n            ReferenceDummyEnumInDifferentNamespace();\r\n            DisableCompilerDiagnostics();                   // Nullable struct arrays are not supported in attributes\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Providing_expected_type_using_not_fully_qualified_name_located_in_same_namespace_should_not_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(DummyAttributeUsage))] string dummyAttributeUsage,\r\n            [CombinatorialMemberData(nameof(ValuesAndTypesInDifferentNamespace))] ValueTupleDouble<string, string> valueAndType,\r\n            [CombinatorialMemberData(nameof(ScalarValuesContainerAttributeArgumentEnumerable))] string scalarValuesContainerAttributeArgument,\r\n            [CombinatorialMemberData(nameof(FieldOrPropertyDeclarations))] string fieldOrPropertyDeclaration)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                namespace DifferentNamespace;\r\n                \r\n                public class BenchmarkClass\r\n                {\r\n                    [{{dummyAttributeUsage}}Params({{string.Format(scalarValuesContainerAttributeArgument, valueAndType.Value1)}})]\r\n                    public {{valueAndType.Value2}} {{fieldOrPropertyDeclaration}}\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceDummyAttribute();\r\n            ReferenceDummyEnumInDifferentNamespace();\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Providing_expected_type_using_not_fully_qualified_name_located_in_a_different_namespace_should_not_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(DummyAttributeUsage))] string dummyAttributeUsage,\r\n            [CombinatorialMemberData(nameof(ValuesAndTypesInDifferentNamespace))] ValueTupleDouble<string, string> valueAndType,\r\n            [CombinatorialMemberData(nameof(ScalarValuesContainerAttributeArgumentEnumerable))] string scalarValuesContainerAttributeArgument,\r\n            [CombinatorialMemberData(nameof(FieldOrPropertyDeclarations))] string fieldOrPropertyDeclaration)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using DifferentNamespace;\r\n                \r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [{{dummyAttributeUsage}}Params({{string.Format(scalarValuesContainerAttributeArgument, valueAndType.Value1)}})]\r\n                    public {{valueAndType.Value2}} {{fieldOrPropertyDeclaration}}\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceDummyAttribute();\r\n            ReferenceDummyEnumInDifferentNamespace();\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Providing_null_to_nullable_struct_value_type_should_not_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(DummyAttributeUsage))] string dummyAttributeUsage,\r\n            [CombinatorialMemberData(nameof(NullableStructTypes))] string type,\r\n            [CombinatorialMemberData(nameof(ScalarValuesContainerAttributeArgumentEnumerable))] string scalarValuesContainerAttributeArgument,\r\n            [CombinatorialMemberData(nameof(FieldOrPropertyDeclarations))] string fieldOrPropertyDeclaration)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [{{dummyAttributeUsage}}Params({{string.Format(scalarValuesContainerAttributeArgument, \"null\")}})]\r\n                    public {{type}}? {{fieldOrPropertyDeclaration}}\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceDummyAttribute();\r\n            ReferenceDummyEnum();\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Providing_expected_constant_value_type_should_not_trigger_diagnostic(\r\n            bool useConstantFromOtherClass,\r\n            bool useLocalConstant,\r\n            [CombinatorialMemberData(nameof(DummyAttributeUsage))] string dummyAttributeUsage,\r\n            [CombinatorialMemberData(nameof(ConstantValuesAndTypes))] ValueTupleDouble<string, string> valueAndType,\r\n            [CombinatorialMemberData(nameof(ScalarValuesContainerAttributeArgumentEnumerable))] string scalarValuesContainerAttributeArgument,\r\n            [CombinatorialMemberData(nameof(FieldOrPropertyDeclarations))] string fieldOrPropertyDeclaration)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    {{(useLocalConstant ? $\"private const {valueAndType.Value2} _x = {(useConstantFromOtherClass ? \"Constants.Value\" : valueAndType.Value1!)};\" : \"\")}}\r\n\r\n                    [{{dummyAttributeUsage}}Params({{string.Format(scalarValuesContainerAttributeArgument, useLocalConstant ? \"_x\" : useConstantFromOtherClass ? \"Constants.Value\" : valueAndType.Value1!)}})]\r\n                    public {{valueAndType.Value2}} {{fieldOrPropertyDeclaration}}\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceDummyAttribute();\r\n            ReferenceDummyEnum();\r\n\r\n            if (useConstantFromOtherClass)\r\n            {\r\n                ReferenceConstants($\"{valueAndType.Value2!}\", valueAndType.Value1!);\r\n            }\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Providing_expected_null_reference_constant_value_type_should_not_trigger_diagnostic(\r\n            bool useConstantFromOtherClass,\r\n            bool useLocalConstant,\r\n            [CombinatorialMemberData(nameof(DummyAttributeUsage))] string dummyAttributeUsage,\r\n            [CombinatorialMemberData(nameof(NullReferenceConstantTypes))] string type,\r\n            [CombinatorialMemberData(nameof(ScalarValuesContainerAttributeArgumentEnumerable))] string scalarValuesContainerAttributeArgument,\r\n            [CombinatorialMemberData(nameof(FieldOrPropertyDeclarations))] string fieldOrPropertyDeclaration)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    {{(useLocalConstant ? $\"private const {type}? _x = {(useConstantFromOtherClass ? \"Constants.Value\" : \"null\")};\" : \"\")}}\r\n\r\n                    [{{dummyAttributeUsage}}Params({{string.Format(scalarValuesContainerAttributeArgument, useLocalConstant ? \"_x\" : useConstantFromOtherClass ? \"Constants.Value\" : \"null\")}})]\r\n                    public {{type}}? {{fieldOrPropertyDeclaration}}\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceDummyAttribute();\r\n            ReferenceDummyEnum();\r\n\r\n            if (useConstantFromOtherClass)\r\n            {\r\n                ReferenceConstants($\"{type}?\", \"null\");\r\n            }\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Providing_implicitly_convertible_value_type_should_not_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(DummyAttributeUsage))] string dummyAttributeUsage,\r\n            [CombinatorialMemberData(nameof(ScalarValuesContainerAttributeArgumentEnumerable))] string scalarValuesContainerAttributeArgument,\r\n            [CombinatorialValues(\"(byte)42\", \"'c'\")] string value,\r\n            [CombinatorialMemberData(nameof(FieldOrPropertyDeclarations))] string fieldOrPropertyDeclaration)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [{{dummyAttributeUsage}}Params({{string.Format(scalarValuesContainerAttributeArgument, value)}})]\r\n                    public int {{fieldOrPropertyDeclaration}}\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceDummyAttribute();\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Providing_integer_value_types_within_target_type_range_should_not_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(DummyAttributeUsage))] string dummyAttributeUsage,\r\n            [CombinatorialMemberData(nameof(ScalarValuesContainerAttributeArgumentEnumerable))] string scalarValuesContainerAttributeArgument,\r\n            [CombinatorialMemberData(nameof(IntegerValuesAndTypesWithinTargetTypeRange))] ValueTupleDouble<string, string> integerValueAndType,\r\n            bool explicitCast,\r\n            [CombinatorialMemberData(nameof(FieldOrPropertyDeclarations))] string fieldOrPropertyDeclaration)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [{{dummyAttributeUsage}}Params({{string.Format(scalarValuesContainerAttributeArgument, $\"{(explicitCast ? $\"({integerValueAndType.Value2})\" : \"\")}{integerValueAndType.Value1}\")}})]\r\n                    public {{integerValueAndType.Value2}} {{fieldOrPropertyDeclaration}}\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceDummyAttribute();\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Providing_an_unknown_value_type_should_not_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(DummyAttributeUsage))] string dummyAttributeUsage,\r\n            [CombinatorialMemberData(nameof(ScalarValuesContainerAttributeArgumentEnumerable))] string scalarValuesContainerAttributeArgument,\r\n            [CombinatorialMemberData(nameof(FieldOrPropertyDeclarations))] string fieldOrPropertyDeclaration)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [{{dummyAttributeUsage}}Params({{string.Format(scalarValuesContainerAttributeArgument, \"42, dummy_literal, 33\")}})]\r\n                    public int {{fieldOrPropertyDeclaration}}\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceDummyAttribute();\r\n\r\n            DisableCompilerDiagnostics();\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Providing_an_unknown_type_in_typeof_expression_should_not_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(DummyAttributeUsage))] string dummyAttributeUsage,\r\n            [CombinatorialMemberData(nameof(ScalarValuesContainerAttributeArgumentEnumerable))] string scalarValuesContainerAttributeArgument,\r\n            [CombinatorialMemberData(nameof(FieldOrPropertyDeclarations))] string fieldOrPropertyDeclaration)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [{{dummyAttributeUsage}}Params({{string.Format(scalarValuesContainerAttributeArgument, \"typeof(int), typeof(dummy_literal)\")}})]\r\n                    public System.Type {{fieldOrPropertyDeclaration}}\r\n                }\r\n                \"\"\";\r\n            TestCode = testCode;\r\n            ReferenceDummyAttribute();\r\n\r\n            DisableCompilerDiagnostics();\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Providing_both_expected_and_unexpected_value_types_should_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(DummyAttributeUsage))] string dummyAttributeUsage,\r\n            [CombinatorialMemberData(nameof(ScalarValuesContainerAttributeArgumentEnumerable))] string scalarValuesContainerAttributeArgument,\r\n            [CombinatorialMemberData(nameof(FieldOrPropertyDeclarations))] string fieldOrPropertyDeclaration)\r\n        {\r\n            const string expectedFieldOrPropertyType = \"int\";\r\n            const string valueWithUnexpectedType = \"\\\"test1\\\"\";\r\n\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [{{dummyAttributeUsage}}Params({{string.Format(scalarValuesContainerAttributeArgument, $\"42, {{|#0:{valueWithUnexpectedType}|}}, 33\")}})]\r\n                    public {{expectedFieldOrPropertyType}} {{fieldOrPropertyDeclaration}}\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceDummyAttribute();\r\n\r\n            AddDefaultExpectedDiagnostic(valueWithUnexpectedType, expectedFieldOrPropertyType, \"string\");\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Providing_an_unexpected_or_not_implicitly_convertible_value_type_should_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(DummyAttributeUsage))] string dummyAttributeUsage,\r\n            [CombinatorialMemberData(nameof(NotConvertibleValuesAndTypes))] ValueTupleDouble<string, string> valueAndType,\r\n            [CombinatorialMemberData(nameof(ScalarValuesContainerAttributeArgumentEnumerable))] string scalarValuesContainerAttributeArgument,\r\n            [CombinatorialMemberData(nameof(FieldOrPropertyDeclarations))] string fieldOrPropertyDeclaration)\r\n        {\r\n            const string expectedFieldOrPropertyType = \"decimal\";\r\n\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [{{dummyAttributeUsage}}Params({{string.Format(scalarValuesContainerAttributeArgument, $\"{{|#0:{valueAndType.Value1}|}}\")}})]\r\n                    public {{expectedFieldOrPropertyType}} {{fieldOrPropertyDeclaration}}\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceDummyAttribute();\r\n            ReferenceDummyEnum();\r\n\r\n            AddDefaultExpectedDiagnostic(valueAndType.Value1!, expectedFieldOrPropertyType, valueAndType.Value2!);\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Providing_an_unexpected_or_not_implicitly_convertible_constant_value_type_should_trigger_diagnostic(\r\n            bool useConstantFromOtherClass,\r\n            bool useLocalConstant,\r\n            [CombinatorialMemberData(nameof(DummyAttributeUsage))] string dummyAttributeUsage,\r\n            [CombinatorialMemberData(nameof(NotConvertibleConstantValuesAndTypes))] ValueTupleDouble<string, string> valueAndType,\r\n            [CombinatorialMemberData(nameof(ScalarValuesContainerAttributeArgumentEnumerable))] string scalarValuesContainerAttributeArgument,\r\n            [CombinatorialMemberData(nameof(FieldOrPropertyDeclarations))] string fieldOrPropertyDeclaration)\r\n        {\r\n            const string expectedFieldOrPropertyType = \"decimal\";\r\n\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    {{(useLocalConstant ? $\"private const {valueAndType.Value2} _x = {(useConstantFromOtherClass ? \"Constants.Value\" : valueAndType.Value1)};\" : \"\")}}\r\n\r\n                    [{{dummyAttributeUsage}}Params({{string.Format(scalarValuesContainerAttributeArgument, $\"{{|#0:{(useLocalConstant ? \"_x\" : useConstantFromOtherClass ? \"Constants.Value\" : valueAndType.Value1)}|}}\")}})]\r\n                    public {{expectedFieldOrPropertyType}} {{fieldOrPropertyDeclaration}}\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceDummyAttribute();\r\n            ReferenceDummyEnum();\r\n\r\n            if (useConstantFromOtherClass)\r\n            {\r\n                ReferenceConstants(valueAndType.Value2!, valueAndType.Value1!);\r\n            }\r\n\r\n            AddDefaultExpectedDiagnostic(useLocalConstant ? \"_x\" : useConstantFromOtherClass ? \"Constants.Value\" : valueAndType.Value1!, expectedFieldOrPropertyType, valueAndType.Value2!);\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Providing_null_to_nonnullable_struct_value_type_should_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(DummyAttributeUsage))] string dummyAttributeUsage,\r\n            [CombinatorialMemberData(nameof(NullableStructTypes))] string type,\r\n            [CombinatorialMemberData(nameof(ScalarValuesContainerAttributeArgumentEnumerable))] string scalarValuesContainerAttributeArgument,\r\n            [CombinatorialMemberData(nameof(FieldOrPropertyDeclarations))] string fieldOrPropertyDeclaration)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [{{dummyAttributeUsage}}Params({{string.Format(scalarValuesContainerAttributeArgument, \"{|#0:null|}\")}})]\r\n                    public {{type}} {{fieldOrPropertyDeclaration}}\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceDummyAttribute();\r\n            ReferenceDummyEnum();\r\n\r\n            AddDefaultExpectedDiagnostic(\"null\", type, \"null\");\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Providing_integer_value_types_not_within_target_type_range_should_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(DummyAttributeUsage))] string dummyAttributeUsage,\r\n            [CombinatorialMemberData(nameof(ScalarValuesContainerAttributeArgumentEnumerable))] string scalarValuesContainerAttributeArgument,\r\n            [CombinatorialMemberData(nameof(IntegerValuesAndTypesNotWithinTargetTypeRange))] ValueTupleTriple<string, string, string> integerValueAndType,\r\n            [CombinatorialMemberData(nameof(FieldOrPropertyDeclarations))] string fieldOrPropertyDeclaration)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [{{dummyAttributeUsage}}Params({{string.Format(scalarValuesContainerAttributeArgument, $\"{{|#0:{integerValueAndType.Value1}|}}\")}})]\r\n                    public {{integerValueAndType.Value2}} {{fieldOrPropertyDeclaration}}\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceDummyAttribute();\r\n            AddDefaultExpectedDiagnostic(integerValueAndType.Value1!, integerValueAndType.Value2!, integerValueAndType.Value3!);\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Providing_an_unexpected_array_value_type_to_params_attribute_should_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(DummyAttributeUsage))] string dummyAttributeUsage,\r\n            [CombinatorialMemberData(nameof(ValuesAndTypes))] ValueTupleDouble<string, string> valueAndType,\r\n            [CombinatorialMemberData(nameof(ArrayValuesContainerAttributeArgumentWithLocationMarkerEnumerableLocal))] ValueTupleDouble<string, string> arrayValuesContainerAttributeArgument,\r\n            [CombinatorialMemberData(nameof(FieldOrPropertyDeclarations))] string fieldOrPropertyDeclaration)\r\n        {\r\n            const string expectedFieldOrPropertyType = \"decimal\";\r\n\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using DifferentNamespace;\r\n                \r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [{{dummyAttributeUsage}}Params({{string.Format(arrayValuesContainerAttributeArgument.Value1!, valueAndType.Value1, valueAndType.Value2)}})]\r\n                    public {{expectedFieldOrPropertyType}} {{fieldOrPropertyDeclaration}}\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceDummyAttribute();\r\n            ReferenceDummyEnum();\r\n            ReferenceDummyEnumInDifferentNamespace();\r\n\r\n            AddDefaultExpectedDiagnostic(\r\n                string.Format(arrayValuesContainerAttributeArgument.Value2!, valueAndType.Value1, valueAndType.Value2),\r\n                expectedFieldOrPropertyType,\r\n                $\"{valueAndType.Value2}[]\"\r\n            );\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Providing_an_empty_array_value_when_type_of_attribute_target_is_not_object_array_should_not_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(DummyAttributeUsage))] string dummyAttributeUsage,\r\n            [CombinatorialMemberData(nameof(EmptyValuesAttributeArgument))] string emptyValuesAttributeArgument,\r\n            [CombinatorialMemberData(nameof(FieldOrPropertyDeclarations))] string fieldOrPropertyDeclaration)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [{{dummyAttributeUsage}}Params{{emptyValuesAttributeArgument}}]\r\n                    public decimal {{fieldOrPropertyDeclaration}}\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceDummyAttribute();\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Providing_an_empty_array_value_when_type_of_attribute_target_is_object_array_should_not_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(DummyAttributeUsage))] string dummyAttributeUsage,\r\n            [CombinatorialMemberData(nameof(EmptyValuesAttributeArgument))] string emptyValuesAttributeArgument,\r\n            [CombinatorialMemberData(nameof(FieldOrPropertyDeclarations))] string fieldOrPropertyDeclaration)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [{{dummyAttributeUsage}}Params{{emptyValuesAttributeArgument}}]\r\n                    public object[] {{fieldOrPropertyDeclaration}}\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceDummyAttribute();\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        public static IEnumerable<string> FieldOrPropertyDeclarations\r\n#pragma warning disable IDE0028 // Simplify collection initialization\r\n            => new FieldOrPropertyDeclarationsTheoryData();\r\n#pragma warning restore IDE0028 // Simplify collection initialization\r\n\r\n        public static IEnumerable<string> DummyAttributeUsage\r\n            => DummyAttributeUsageTheoryData;\r\n\r\n        public static IEnumerable<ValueTupleDouble<string, string>> IntegerValuesAndTypesWithinTargetTypeRange =>\r\n        [\r\n            // byte (0 to 255)\r\n            (\"0\", \"byte\"),\r\n            (\"100\", \"byte\"),\r\n            (\"255\", \"byte\"),\r\n\r\n            // sbyte (-128 to 127)\r\n            (\"-128\", \"sbyte\"),\r\n            (\"0\", \"sbyte\"),\r\n            (\"127\", \"sbyte\"),\r\n\r\n            // short (-32,768 to 32,767)\r\n            (\"-32768\", \"short\"),\r\n            (\"0\", \"short\"),\r\n            (\"32767\", \"short\"),\r\n\r\n            // ushort (0 to 65,535)\r\n            (\"0\", \"ushort\"),\r\n            (\"1000\", \"ushort\"),\r\n            (\"65535\", \"ushort\"),\r\n\r\n            // int (-2,147,483,648 to 2,147,483,647)\r\n            (\"-2147483648\", \"int\"),\r\n            (\"0\", \"int\"),\r\n            (\"2147483647\", \"int\"),\r\n\r\n            // uint (0 to 4,294,967,295)\r\n            (\"0\", \"uint\"),\r\n            (\"1000000\", \"uint\"),\r\n            (\"4294967295\", \"uint\"),\r\n\r\n            // long (-9,223,372,036,854,775,808 to 9,223,372,036,854,775,807)\r\n            (\"-9223372036854775808\", \"long\"),\r\n            (\"0\", \"long\"),\r\n            (\"9223372036854775807\", \"long\"),\r\n\r\n            // ulong (0 to 18,446,744,073,709,551,615)\r\n            (\"0\", \"ulong\"),\r\n            (\"1000000\", \"ulong\"),\r\n            (\"18446744073709551615\", \"ulong\"),\r\n        ];\r\n\r\n        public static IEnumerable<ValueTupleTriple<string, string, string>> IntegerValuesAndTypesNotWithinTargetTypeRange =>\r\n        [\r\n            // byte (0 to 255) - out of range values\r\n            (\"-1\", \"byte\", \"int\"),\r\n            (\"256\", \"byte\", \"int\"),\r\n            (\"1000\", \"byte\", \"int\"),\r\n\r\n            // sbyte (-128 to 127) - out of range values\r\n            (\"-129\", \"sbyte\", \"int\"),\r\n            (\"128\", \"sbyte\", \"int\"),\r\n            (\"500\", \"sbyte\", \"int\"),\r\n\r\n            // short (-32,768 to 32,767) - out of range values\r\n            (\"-32769\", \"short\", \"int\"),\r\n            (\"32768\", \"short\", \"int\"),\r\n            (\"100000\", \"short\", \"int\"),\r\n\r\n            // ushort (0 to 65,535) - out of range values\r\n            (\"-1\", \"ushort\", \"int\"),\r\n            (\"65536\", \"ushort\", \"int\"),\r\n            (\"100000\", \"ushort\", \"int\"),\r\n\r\n            // int (-2,147,483,648 to 2,147,483,647) - out of range values\r\n            (\"-2147483649\", \"int\", \"long\"),\r\n            (\"2147483648\", \"int\", \"uint\"),\r\n            (\"5000000000\", \"int\", \"long\"),\r\n\r\n            // uint (0 to 4,294,967,295) - out of range values\r\n            (\"-1\", \"uint\", \"int\"),\r\n            (\"4294967296\", \"uint\", \"long\"),\r\n            (\"5000000000\", \"uint\", \"long\"),\r\n\r\n            // long - out of range values (exceeding long range)\r\n            (\"9223372036854775808\", \"long\", \"ulong\"),\r\n\r\n            // ulong - negative values\r\n            (\"-1\", \"ulong\", \"int\"),\r\n            (\"-100\", \"ulong\", \"int\"),\r\n            (\"-9223372036854775808\", \"ulong\", \"long\"),\r\n        ];\r\n\r\n        public static IEnumerable<string> EmptyValuesAttributeArgument()\r\n        {\r\n            yield return \"\";\r\n            yield return \"()\";\r\n            yield return \"(Priority = 1)\";\r\n\r\n            string[] nameColonUsages =\r\n            [\r\n                \"\",\r\n                \"values: \"\r\n            ];\r\n\r\n            string[] priorityNamedParameterUsages =\r\n            [\r\n                \"\",\r\n                \", Priority = 1\"\r\n            ];\r\n\r\n            string[] attributeUsagesBase =\r\n            [\r\n                \"({0}new object[] {{ }}{1})\",\r\n                \"({0}new object[0]{1})\",\r\n                \"({0}[ ]{1})\"\r\n            ];\r\n\r\n            foreach (var attributeUsageBase in attributeUsagesBase)\r\n            {\r\n                foreach (var nameColonUsage in nameColonUsages)\r\n                {\r\n                    foreach (var priorityNamedParameterUsage in priorityNamedParameterUsages)\r\n                    {\r\n                        yield return string.Format(attributeUsageBase, nameColonUsage, priorityNamedParameterUsage);\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        public static IEnumerable<string> ScalarValuesContainerAttributeArgumentEnumerable\r\n            => ScalarValuesContainerAttributeArgumentTheoryData();\r\n\r\n        public static IEnumerable<string> ArrayValuesContainerAttributeArgumentEnumerableLocal()\r\n        {\r\n            string[] nameColonUsages =\r\n            [\r\n                \"\",\r\n                \"values: \"\r\n            ];\r\n\r\n            string[] priorityNamedParameterUsages =\r\n            [\r\n                \"\",\r\n                \", Priority = 1\"\r\n            ];\r\n\r\n            List<string> arrayValuesContainers =\r\n            [\r\n                \"{0}new object[] {{{{ new[] {{{{ {{0}} }}}} }}}}{1}\",         // new object[] { new[] { 42 } }\r\n                \"{0}new object[] {{{{ new {{1}}[] {{{{ {{0}} }}}} }}}}{1}\",   // new object[] { new int[] { 42 } }\r\n                \"{0}[ new[] {{{{ {{0}} }}}} ]{1}\",                            // [ new[] { 42 } ]\r\n                \"{0}[ new {{1}}[] {{{{ {{0}} }}}} ]{1}\",                      // [ new int[] { 42 } ]\r\n                \"{0}new object[] {{{{ new {{1}}[] {{{{ }}}} }}}}{1}\",         // new object[] { new int[] { } }\r\n                \"{0}[ new {{1}}[] {{{{ }}}} ]{1}\",                            // [ new int[] { } ]\r\n                \"{0}new object[] {{{{ new {{1}}[0] }}}}{1}\",                  // new object[] { new int[0] }\r\n                \"{0}[ new {{1}}[0] ]{1}\"                                      // [ new int[0] ]\r\n            ];\r\n\r\n            foreach (var arrayValuesContainer in arrayValuesContainers)\r\n            {\r\n                foreach (var nameColonUsage in nameColonUsages)\r\n                {\r\n                    foreach (var priorityNamedParameterUsage in priorityNamedParameterUsages)\r\n                    {\r\n                        yield return string.Format(arrayValuesContainer, nameColonUsage, priorityNamedParameterUsage);\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        public static IEnumerable<ValueTupleDouble<string, string>> ArrayValuesContainerAttributeArgumentWithLocationMarkerEnumerableLocal()\r\n        {\r\n            string[] nameColonUsages =\r\n            [\r\n                \"\",\r\n                \"values: \"\r\n            ];\r\n\r\n            string[] priorityNamedParameterUsages =\r\n            [\r\n                \"\",\r\n                \", Priority = 1\"\r\n            ];\r\n\r\n            (string, string)[] arrayValuesContainers =\r\n            [\r\n                (\"{0}new object[] {{{{ {{{{|#0:new[] {{{{ {{0}} }}}}|}}}} }}}}{1}\",       \"new[] {{ {0} }}\"),       // new object[] { new[] { 42 } }\r\n                (\"{0}new object[] {{{{ {{{{|#0:new {{1}}[] {{{{ {{0}} }}}}|}}}} }}}}{1}\", \"new {1}[] {{ {0} }}\"),   // new object[] { new int[] { 42 } }\r\n                (\"{0}[ {{{{|#0:new[] {{{{ {{0}} }}}}|}}}} ]{1}\",                          \"new[] {{ {0} }}\"),       // [ new[] { 42 } ]\r\n                (\"{0}[ {{{{|#0:new {{1}}[] {{{{ {{0}} }}}}|}}}} ]{1}\",                    \"new {1}[] {{ {0} }}\"),   // [ new int[] { 42 } ]\r\n                (\"{0}new object[] {{{{ {{{{|#0:new {{1}}[] {{{{ }}}}|}}}} }}}}{1}\",       \"new {1}[] {{ }}\"),       // new object[] { new int[] { } }\r\n                (\"{0}[ {{{{|#0:new {{1}}[] {{{{ }}}}|}}}} ]{1}\",                          \"new {1}[] {{ }}\"),       // [ new int[] { } ]\r\n                (\"{0}new object[] {{{{ {{{{|#0:new {{1}}[0]|}}}} }}}}{1}\",                \"new {1}[0]\"),            // new object[] { new int[0] }\r\n                (\"{0}[ {{{{|#0:new {{1}}[0]|}}}} ]{1}\",                                   \"new {1}[0]\"),            // [ new int[0] ]\r\n            ];\r\n\r\n            foreach (var arrayValuesContainer in arrayValuesContainers)\r\n            {\r\n                foreach (var nameColonUsage in nameColonUsages)\r\n                {\r\n                    foreach (var priorityNamedParameterUsage in priorityNamedParameterUsages)\r\n                    {\r\n                        yield return new ValueTupleDouble<string, string>\r\n                        {\r\n                            Value1 = string.Format(arrayValuesContainer.Item1, nameColonUsage, priorityNamedParameterUsage),\r\n                            Value2 = arrayValuesContainer.Item2\r\n                        };\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        public static IEnumerable<ValueTupleDouble<string, string>> ValuesAndTypes =>\r\n        [\r\n            ( \"true\", \"bool\" ),\r\n            ( \"(byte)123\", \"byte\" ),\r\n            ( \"'A'\", \"char\" ),\r\n            ( \"1.0D\", \"double\" ),\r\n            ( \"1.0F\", \"float\" ),\r\n            ( \"123\", \"int\" ),\r\n            ( \"123L\", \"long\" ),\r\n            ( \"(sbyte)-100\", \"sbyte\" ),\r\n            ( \"(short)-123\", \"short\" ),\r\n            ( \"\"\"\r\n              \"test\"\r\n              \"\"\", \"string\" ),\r\n            ( \"123U\", \"uint\" ),\r\n            ( \"123UL\", \"ulong\" ),\r\n            ( \"(ushort)123\", \"ushort\" ),\r\n\r\n            ( \"\"\"\r\n              (object)\"test_object\"\r\n              \"\"\", \"object\" ),\r\n            ( \"typeof(string)\", \"System.Type\" ),\r\n            ( \"typeof(DummyEnumInDifferentNamespace?)\", \"System.Type\" ),\r\n            ( \"DummyEnum.Value1\", \"DummyEnum\" ),\r\n        ];\r\n\r\n        public static IEnumerable<ValueTupleDouble<string, string>> ValuesAndTypesInDifferentNamespace =>\r\n        [\r\n            ( \"typeof(DummyEnumInDifferentNamespace)\", \"System.Type\" ),\r\n            ( \"typeof(DummyEnumInDifferentNamespace?)\", \"System.Type\" ),\r\n            ( \"DummyEnumInDifferentNamespace.Value1\", \"DummyEnumInDifferentNamespace\" ),\r\n        ];\r\n\r\n        public static IEnumerable<ValueTupleDouble<string, string>> NotConvertibleValuesAndTypes =>\r\n        [\r\n            ( \"true\", \"bool\" ),\r\n            ( \"1.0D\", \"double\" ),\r\n            ( \"1.0F\", \"float\" ),\r\n            ( \"\"\"\r\n              \"test\"\r\n              \"\"\", \"string\" ),\r\n\r\n            ( \"\"\"\r\n              (object)\"test_object\"\r\n              \"\"\", \"string\" ),\r\n            ( \"typeof(string)\", \"System.Type\" ),\r\n            ( \"DummyEnum.Value1\", \"DummyEnum\" )\r\n        ];\r\n\r\n        public static IEnumerable<ValueTupleDouble<string, string>> ConstantValuesAndTypes =>\r\n        [\r\n            ( \"true\", \"bool\" ),\r\n            ( \"(byte)123\", \"byte\" ),\r\n            ( \"'A'\", \"char\" ),\r\n            ( \"1.0D\", \"double\" ),\r\n            ( \"1.0F\", \"float\" ),\r\n            ( \"123\", \"int\" ),\r\n            ( \"123L\", \"long\" ),\r\n            ( \"(sbyte)-100\", \"sbyte\" ),\r\n            ( \"(short)-123\", \"short\" ),\r\n            ( \"\"\"\r\n              \"test\"\r\n              \"\"\", \"string\" ),\r\n            ( \"123U\", \"uint\" ),\r\n            ( \"123UL\", \"ulong\" ),\r\n            ( \"(ushort)123\", \"ushort\" ),\r\n\r\n            ( \"DummyEnum.Value1\", \"DummyEnum\" ),\r\n        ];\r\n\r\n        public static IEnumerable<string> NullableStructTypes =>\r\n        [\r\n            \"bool\",\r\n            \"byte\",\r\n            \"char\",\r\n            \"double\",\r\n            \"float\",\r\n            \"int\",\r\n            \"long\",\r\n            \"sbyte\",\r\n            \"short\",\r\n            \"uint\",\r\n            \"ulong\",\r\n            \"ushort\",\r\n            \"DummyEnum\",\r\n        ];\r\n\r\n        public static IEnumerable<string> NullReferenceConstantTypes =>\r\n        [\r\n            \"object\",\r\n            \"string\",\r\n            \"System.Type\",\r\n        ];\r\n\r\n        public static IEnumerable<ValueTupleDouble<string, string>> NotConvertibleConstantValuesAndTypes =>\r\n        [\r\n            ( \"true\", \"bool\" ),\r\n            ( \"1.0D\", \"double\" ),\r\n            ( \"1.0F\", \"float\" ),\r\n            ( \"\"\"\r\n              \"test\"\r\n              \"\"\", \"string\" ),\r\n\r\n            ( \"DummyEnum.Value1\", \"DummyEnum\" )\r\n        ];\r\n    }\r\n\r\n    public class UnnecessarySingleValuePassedToAttribute : AnalyzerTestFixture<ParamsAttributeAnalyzer>\r\n    {\r\n        public UnnecessarySingleValuePassedToAttribute() : base(ParamsAttributeAnalyzer.UnnecessarySingleValuePassedToAttributeRule) { }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Providing_two_or_more_values_should_not_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(FieldOrPropertyDeclarations))] string fieldOrPropertyDeclaration,\r\n            [CombinatorialMemberData(nameof(DummyAttributeUsage))] string dummyAttributeUsage,\r\n            [CombinatorialMemberData(nameof(ScalarValuesListLength))] int scalarValuesListLength,\r\n            [CombinatorialMemberData(nameof(ScalarValuesContainerAttributeArgument))] string scalarValuesContainerAttributeArgument)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [{{dummyAttributeUsage}}Params({{string.Format(scalarValuesContainerAttributeArgument, string.Join(\", \", ScalarValues.Take(scalarValuesListLength)))}})]\r\n                    public string {{fieldOrPropertyDeclaration}}\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceDummyAttribute();\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Providing_only_a_single_value_should_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(FieldOrPropertyDeclarations))] string fieldOrPropertyDeclaration,\r\n            [CombinatorialMemberData(nameof(DummyAttributeUsage))] string dummyAttributeUsage,\r\n            [CombinatorialMemberData(nameof(ScalarValuesContainerAttributeArgumentWithLocationMarker))] string scalarValuesContainerAttributeArgument)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [{{dummyAttributeUsage}}Params({{string.Format(scalarValuesContainerAttributeArgument, 42)}})]\r\n                    public string {{fieldOrPropertyDeclaration}}\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceDummyAttribute();\r\n\r\n            AddDefaultExpectedDiagnostic();\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        public static IEnumerable<string> FieldOrPropertyDeclarations\r\n#pragma warning disable IDE0028 // Simplify collection initialization\r\n            => new FieldOrPropertyDeclarationsTheoryData();\r\n#pragma warning restore IDE0028 // Simplify collection initialization\r\n\r\n        public static IEnumerable<string> DummyAttributeUsage\r\n            => DummyAttributeUsageTheoryData;\r\n\r\n        public static IEnumerable<int> ScalarValuesListLength\r\n            => Enumerable.Range(2, ScalarValues.Count);\r\n\r\n        private static ReadOnlyCollection<string> ScalarValues\r\n            => Enumerable.Range(1, 2)\r\n            .Select(i => $\"\\\"test{i}\\\"\")\r\n            .ToList()\r\n            .AsReadOnly();\r\n        public static IEnumerable<string> ScalarValuesContainerAttributeArgument\r\n            => ScalarValuesContainerAttributeArgumentTheoryData();\r\n\r\n        public static IEnumerable<string> ScalarValuesContainerAttributeArgumentWithLocationMarker()\r\n        {\r\n            return GenerateData().Distinct();\r\n\r\n            static IEnumerable<string> GenerateData()\r\n            {\r\n                string[] nameColonUsages =\r\n                [\r\n                    \"\",\r\n                    \"values: \"\r\n                ];\r\n\r\n                string[] priorityNamedParameterUsages =\r\n                [\r\n                    \"\",\r\n                    \", Priority = 1\"\r\n                ];\r\n\r\n                string[] attributeUsagesBase =\r\n                [\r\n                    \"{{{{|#0:{{0}}|}}}}{1}\",\r\n                    \"{0}new object[] {{{{ {{{{|#0:{{0}}|}}}} }}}}{1}\",\r\n                    \"{0}[ {{{{|#0:{{0}}|}}}} ]{1}\",\r\n                ];\r\n\r\n                foreach (var attributeUsageBase in attributeUsagesBase)\r\n                {\r\n                    foreach (var nameColonUsage in nameColonUsages)\r\n                    {\r\n                        foreach (var priorityNamedParameterUsage in priorityNamedParameterUsages)\r\n                        {\r\n                            yield return string.Format(attributeUsageBase, nameColonUsage, priorityNamedParameterUsage);\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    public static TheoryData<string> DummyAttributeUsageTheoryData => [\"\", \"Dummy, \"];\r\n\r\n    public static TheoryData<string> ScalarValuesContainerAttributeArgumentTheoryData()\r\n    {\r\n        return [.. GenerateData().Distinct()];\r\n\r\n        static IEnumerable<string> GenerateData()\r\n        {\r\n            string[] nameColonUsages =\r\n            [\r\n                \"\",\r\n                \"values: \"\r\n            ];\r\n\r\n            string[] priorityNamedParameterUsages =\r\n            [\r\n                \"\",\r\n                \", Priority = 1\"\r\n            ];\r\n\r\n            string[] attributeUsagesBase =\r\n            [\r\n                \"{{0}}{1}\",\r\n                \"{0}new object[] {{{{ {{0}} }}}}{1}\",\r\n                \"{0}[ {{0}} ]{1}\"\r\n            ];\r\n\r\n            foreach (var attributeUsageBase in attributeUsagesBase)\r\n            {\r\n                foreach (var nameColonUsage in nameColonUsages)\r\n                {\r\n                    foreach (var priorityNamedParameterUsage in priorityNamedParameterUsages)\r\n                    {\r\n                        yield return string.Format(attributeUsageBase, nameColonUsage, priorityNamedParameterUsage);\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    }\r\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Analyzers.Tests/AnalyzerTests/BenchmarkRunner/RunAnalyzerTests.cs",
    "content": "﻿using BenchmarkDotNet.Analyzers.BenchmarkRunner;\r\nusing BenchmarkDotNet.Analyzers.Tests.Fixtures;\r\nusing System.Collections.Generic;\r\nusing System.Collections.ObjectModel;\r\nusing System.Linq;\r\nusing System.Threading.Tasks;\r\nusing Xunit;\r\n\r\nnamespace BenchmarkDotNet.Analyzers.Tests.AnalyzerTests.BenchmarkRunner;\r\n\r\npublic class RunAnalyzerTests\r\n{\r\n    public class General : AnalyzerTestFixture<RunAnalyzer>\r\n    {\r\n        [Theory, CombinatorialData]\r\n        public async Task Invoking_with_a_public_nonabstract_unsealed_nongeneric_type_argument_class_having_only_one_and_public_method_annotated_with_the_benchmark_attribute_should_not_trigger_diagnostic(\r\n            bool isGenericInvocation)\r\n        {\r\n            const string classWithOneBenchmarkMethodName = \"ClassWithOneBenchmarkMethod\";\r\n\r\n            var invocationExpression = isGenericInvocation ? $\"<{classWithOneBenchmarkMethodName}>()\" : $\"(typeof({classWithOneBenchmarkMethodName}))\";\r\n\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Running;\r\n\r\n                public class Program\r\n                {\r\n                    public static void Main(string[] args) {\r\n                        BenchmarkRunner.Run{{invocationExpression}};\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            const string benchmarkClassDocument = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class {{classWithOneBenchmarkMethodName}}\r\n                {\r\n                    [Benchmark]\r\n                    public void BenchmarkMethod()\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            AddSource(benchmarkClassDocument);\r\n\r\n            await RunAsync();\r\n        }\r\n    }\r\n\r\n    public class TypeArgumentClassMissingBenchmarkMethods : AnalyzerTestFixture<RunAnalyzer>\r\n    {\r\n        public TypeArgumentClassMissingBenchmarkMethods() : base(RunAnalyzer.TypeArgumentClassMissingBenchmarkMethodsRule) { }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Invoking_with_type_argument_class_having_at_least_one_public_method_annotated_with_the_benchmark_attribute_should_not_trigger_diagnostic(bool isGenericInvocation)\r\n        {\r\n            const string classWithOneBenchmarkMethodName = \"ClassWithOneBenchmarkMethod\";\r\n\r\n            var invocationExpression = isGenericInvocation ? $\"<{classWithOneBenchmarkMethodName}>()\" : $\"(typeof({classWithOneBenchmarkMethodName}))\";\r\n\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Running;\r\n                                               \r\n                public class Program\r\n                {\r\n                    public static void Main(string[] args) {\r\n                        BenchmarkRunner.Run{{invocationExpression}};\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            const string benchmarkClassDocument = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class {{classWithOneBenchmarkMethodName}}\r\n                {\r\n                    [Benchmark]\r\n                    public void BenchmarkMethod()\r\n                    {\r\n\r\n                    }\r\n\r\n                    public void BenchmarkMethod2()\r\n                    {\r\n\r\n                    }\r\n\r\n                    private void BenchmarkMethod3()\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            AddSource(benchmarkClassDocument);\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Invoking_with_type_argument_class_having_at_least_one_public_method_annotated_with_the_benchmark_attribute_in_one_of_its_ancestor_classes_should_not_trigger_diagnostic(\r\n            bool isGenericInvocation,\r\n            [CombinatorialMemberData(nameof(ClassAbstractModifiersEnumerableLocal))] string abstractModifier)\r\n        {\r\n            const string classWithOneBenchmarkMethodName = \"TopLevelBenchmarkClass\";\r\n\r\n            var invocationExpression = isGenericInvocation ? $\"<{classWithOneBenchmarkMethodName}>()\" : $\"(typeof({classWithOneBenchmarkMethodName}))\";\r\n\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Running;\r\n\r\n                public class Program\r\n                {\r\n                    public static void Main(string[] args) {\r\n                        BenchmarkRunner.Run{{invocationExpression}};\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            const string benchmarkClassDocument = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class {{classWithOneBenchmarkMethodName}} : BenchmarkClassAncestor1\r\n                {\r\n                }\r\n                \"\"\";\r\n\r\n            var benchmarkClassAncestor1Document = /* lang=c#-test */ $$\"\"\"\r\n                public {{abstractModifier}}class BenchmarkClassAncestor1 : BenchmarkClassAncestor2\r\n                {\r\n                }\r\n                \"\"\";\r\n\r\n            var benchmarkClassAncestor2Document = /* lang=c#-test */ $$\"\"\"\r\n                public {{abstractModifier}}class BenchmarkClassAncestor2 : BenchmarkClassAncestor3\r\n                {\r\n                }\r\n                \"\"\";\r\n\r\n            var benchmarkClassAncestor3Document = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public {{abstractModifier}}class BenchmarkClassAncestor3\r\n                {\r\n                    [Benchmark]\r\n                    public void BenchmarkMethod()\r\n                    {\r\n\r\n                    }\r\n\r\n                    public void BenchmarkMethod2()\r\n                    {\r\n\r\n                    }\r\n\r\n                    private void BenchmarkMethod3()\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            AddSource(benchmarkClassDocument);\r\n            AddSource(benchmarkClassAncestor1Document);\r\n            AddSource(benchmarkClassAncestor2Document);\r\n            AddSource(benchmarkClassAncestor3Document);\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Invoking_with_a_generic_type_argument_class_having_at_least_one_public_method_annotated_with_the_benchmark_attribute_in_one_of_its_ancestor_classes_should_not_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(TypeParametersListLengthEnumerableLocal))] int typeParametersListLength,\r\n            [CombinatorialMemberData(nameof(ClassAbstractModifiersEnumerableLocal))] string abstractModifier)\r\n        {\r\n            var typeParameters = string.Join(\", \", TypeParameters.Take(typeParametersListLength));\r\n\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Running;\r\n\r\n                public class Program\r\n                {\r\n                    public static void Main(string[] args) {\r\n                        BenchmarkRunner.Run(typeof(BenchmarkClass<{{new string(',', typeParametersListLength - 1)}}>));\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            var benchmarkClassDocument = /* lang=c#-test */ $$\"\"\"\r\n                public class BenchmarkClass<{{typeParameters}}> : BenchmarkClassAncestor1<{{typeParameters}}>\r\n                {\r\n                }\r\n                \"\"\";\r\n\r\n            var benchmarkClassAncestor1Document = /* lang=c#-test */ $$\"\"\"\r\n                public {{abstractModifier}}class BenchmarkClassAncestor1<{{typeParameters}}> : BenchmarkClassAncestor2<{{typeParameters}}>\r\n                {\r\n                }\r\n                \"\"\";\r\n\r\n            var benchmarkClassAncestor2Document = /* lang=c#-test */ $$\"\"\"\r\n                public {{abstractModifier}}class BenchmarkClassAncestor2<{{typeParameters}}> : BenchmarkClassAncestor3\r\n                {\r\n                }\r\n                \"\"\";\r\n\r\n            var benchmarkClassAncestor3Document = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public {{abstractModifier}}class BenchmarkClassAncestor3\r\n                {\r\n                    [Benchmark]\r\n                    public void BenchmarkMethod()\r\n                    {\r\n\r\n                    }\r\n\r\n                    public void BenchmarkMethod2()\r\n                    {\r\n\r\n                    }\r\n\r\n                    private void BenchmarkMethod3()\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            AddSource(benchmarkClassDocument);\r\n            AddSource(benchmarkClassAncestor1Document);\r\n            AddSource(benchmarkClassAncestor2Document);\r\n            AddSource(benchmarkClassAncestor3Document);\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Invoking_with_type_argument_class_having_no_public_method_annotated_with_the_benchmark_attribute_in_one_of_its_ancestor_classes_should_trigger_diagnostic(\r\n            bool isGenericInvocation,\r\n            [CombinatorialMemberData(nameof(ClassAbstractModifiersEnumerableLocal))] string abstractModifier)\r\n        {\r\n            const string classWithOneBenchmarkMethodName = \"TopLevelBenchmarkClass\";\r\n\r\n            var invocationExpression = isGenericInvocation ? $\"<{{|#0:{classWithOneBenchmarkMethodName}|}}>()\" : $\"(typeof({{|#0:{classWithOneBenchmarkMethodName}|}}))\";\r\n\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Running;\r\n\r\n                public class Program\r\n                {\r\n                    public static void Main(string[] args) {\r\n                        BenchmarkRunner.Run{{invocationExpression}};\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            const string benchmarkClassDocument = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class {{classWithOneBenchmarkMethodName}} : BenchmarkClassAncestor1\r\n                {\r\n                }\r\n                \"\"\";\r\n\r\n            var benchmarkClassAncestor1Document = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public {{abstractModifier}}class BenchmarkClassAncestor1 : BenchmarkClassAncestor2\r\n                {\r\n                }\r\n                \"\"\";\r\n\r\n            var benchmarkClassAncestor2Document = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public {{abstractModifier}}class BenchmarkClassAncestor2 : BenchmarkClassAncestor3\r\n                {\r\n                }\r\n                \"\"\";\r\n\r\n            var benchmarkClassAncestor3Document = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public {{abstractModifier}}class BenchmarkClassAncestor3\r\n                {\r\n                    public void BenchmarkMethod()\r\n                    {\r\n\r\n                    }\r\n\r\n                    public void BenchmarkMethod2()\r\n                    {\r\n\r\n                    }\r\n\r\n                    private void BenchmarkMethod3()\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            AddSource(benchmarkClassDocument);\r\n            AddSource(benchmarkClassAncestor1Document);\r\n            AddSource(benchmarkClassAncestor2Document);\r\n            AddSource(benchmarkClassAncestor3Document);\r\n\r\n            AddDefaultExpectedDiagnostic(classWithOneBenchmarkMethodName);\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Invoking_with_a_generic_type_argument_class_having_no_public_method_annotated_with_the_benchmark_attribute_in_one_of_its_ancestor_classes_should_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(TypeParametersListLengthEnumerableLocal))] int typeParametersListLength,\r\n            [CombinatorialMemberData(nameof(ClassAbstractModifiersEnumerableLocal))] string abstractModifier)\r\n        {\r\n            const string classWithOneBenchmarkMethodName = \"BenchmarkClass\";\r\n\r\n            var unboundGenericTypeParameterList = new string(',', typeParametersListLength - 1);\r\n            var typeParameters = string.Join(\", \", TypeParameters.Take(typeParametersListLength));\r\n\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Running;\r\n\r\n                public class Program\r\n                {\r\n                    public static void Main(string[] args) {\r\n                        BenchmarkRunner.Run(typeof({|#0:{{classWithOneBenchmarkMethodName}}<{{unboundGenericTypeParameterList}}>|}));\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            var benchmarkClassDocument = /* lang=c#-test */ $$\"\"\"\r\n                public class {{classWithOneBenchmarkMethodName}}<{{typeParameters}}> : BenchmarkClassAncestor1<{{typeParameters}}>\r\n                {\r\n                }\r\n                \"\"\";\r\n\r\n            var benchmarkClassAncestor1Document = /* lang=c#-test */ $$\"\"\"\r\n                public {{abstractModifier}}class BenchmarkClassAncestor1<{{typeParameters}}> : BenchmarkClassAncestor2<{{typeParameters}}>\r\n                {\r\n                }\r\n                \"\"\";\r\n\r\n            var benchmarkClassAncestor2Document = /* lang=c#-test */ $$\"\"\"\r\n                public {{abstractModifier}}class BenchmarkClassAncestor2<{{typeParameters}}> : BenchmarkClassAncestor3\r\n                {\r\n                }\r\n                \"\"\";\r\n\r\n            var benchmarkClassAncestor3Document = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public {{abstractModifier}}class BenchmarkClassAncestor3\r\n                {\r\n                    public void BenchmarkMethod()\r\n                    {\r\n\r\n                    }\r\n\r\n                    private void BenchmarkMethod2()\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            AddSource(benchmarkClassDocument);\r\n            AddSource(benchmarkClassAncestor1Document);\r\n            AddSource(benchmarkClassAncestor2Document);\r\n            AddSource(benchmarkClassAncestor3Document);\r\n\r\n            AddDefaultExpectedDiagnostic($\"{classWithOneBenchmarkMethodName}<{unboundGenericTypeParameterList}>\");\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Invoking_with_type_argument_class_having_no_public_method_annotated_with_the_benchmark_attribute_should_trigger_diagnostic(bool isGenericInvocation)\r\n        {\r\n            const string classWithOneBenchmarkMethodName = \"ClassWithOneBenchmarkMethod\";\r\n\r\n            var invocationExpression = isGenericInvocation ? $\"<{{|#0:{classWithOneBenchmarkMethodName}|}}>()\" : $\"(typeof({{|#0:{classWithOneBenchmarkMethodName}|}}))\";\r\n\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Running;\r\n\r\n                public class Program\r\n                {\r\n                    public static void Main(string[] args) {\r\n                        BenchmarkRunner.Run{{invocationExpression}};\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            const string benchmarkClassDocument = /* lang=c#-test */ $$\"\"\"\r\n                public class {{classWithOneBenchmarkMethodName}}\r\n                {\r\n                    public void BenchmarkMethod()\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n            TestCode = testCode;\r\n            AddSource(benchmarkClassDocument);\r\n\r\n            AddDefaultExpectedDiagnostic(classWithOneBenchmarkMethodName);\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        public static IEnumerable<string> ClassAbstractModifiersEnumerableLocal => ClassAbstractModifiersEnumerable;\r\n\r\n        public static IEnumerable<int> TypeParametersListLengthEnumerableLocal => TypeParametersListLengthEnumerable;\r\n    }\r\n\r\n    public class TypeArgumentClassMustBePublic : AnalyzerTestFixture<RunAnalyzer>\r\n    {\r\n        public TypeArgumentClassMustBePublic() : base(RunAnalyzer.TypeArgumentClassMustBePublicRule) { }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Invoking_with_a_nonpublic_class_with_multiple_inheritance_containing_at_least_one_method_annotated_with_benchmark_attribute_should_trigger_diagnostic(bool isGenericInvocation)\r\n        {\r\n            const string benchmarkClassName = \"BenchmarkClass\";\r\n\r\n            var invocationExpression = isGenericInvocation ? $\"<{{|#0:{benchmarkClassName}|}}>()\" : $\"(typeof({{|#0:{benchmarkClassName}|}}))\";\r\n\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n                using BenchmarkDotNet.Running;\r\n\r\n                public class Program\r\n                {\r\n                    public static void Main(string[] args) {\r\n                        BenchmarkRunner.Run{{invocationExpression}};\r\n                    }\r\n\r\n                    private class {{benchmarkClassName}} : BenchmarkClassAncestor1\r\n                    {\r\n                    }\r\n\r\n                    private class BenchmarkClassAncestor1 : BenchmarkClassAncestor2\r\n                    {\r\n                        [Benchmark]\r\n                        public void BenchmarkMethod()\r\n                        {\r\n\r\n                        }\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            const string benchmarkClassAncestor2Document = /* lang=c#-test */ \"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClassAncestor2\r\n                {\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            AddSource(benchmarkClassAncestor2Document);\r\n\r\n            AddDefaultExpectedDiagnostic(benchmarkClassName);\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Invoking_with_a_nonpublic_class_containing_at_least_one_method_annotated_with_benchmark_attribute_should_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(NonPublicClassAccessModifiersExceptFile))] string nonPublicClassAccessModifier,\r\n            bool isGenericInvocation)\r\n        {\r\n            const string benchmarkClassName = \"BenchmarkClass\";\r\n\r\n            var invocationExpression = isGenericInvocation ? $\"<{{|#0:{benchmarkClassName}|}}>()\" : $\"(typeof({{|#0:{benchmarkClassName}|}}))\";\r\n\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n                using BenchmarkDotNet.Running;\r\n\r\n                public class Program\r\n                {\r\n                    public static void Main(string[] args) {\r\n                        BenchmarkRunner.Run{{invocationExpression}};\r\n                    }\r\n\r\n                    {{nonPublicClassAccessModifier}}class {{benchmarkClassName}}\r\n                    {\r\n                        [Benchmark]\r\n                        public void BenchmarkMethod()\r\n                        {\r\n\r\n                        }\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n\r\n            AddDefaultExpectedDiagnostic(benchmarkClassName);\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Invoking_with_a_file_class_containing_at_least_one_method_annotated_with_benchmark_attribute_should_trigger_diagnostic(bool isGenericInvocation)\r\n        {\r\n            const string benchmarkClassName = \"BenchmarkClass\";\r\n\r\n            var invocationExpression = isGenericInvocation ? $\"<{{|#0:{benchmarkClassName}|}}>()\" : $\"(typeof({{|#0:{benchmarkClassName}|}}))\";\r\n\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n                using BenchmarkDotNet.Running;\r\n\r\n                public class Program\r\n                {\r\n                    public static void Main(string[] args) {\r\n                        BenchmarkRunner.Run{{invocationExpression}};\r\n                    }\r\n                }\r\n\r\n                file class {{benchmarkClassName}}\r\n                {\r\n                    [Benchmark]\r\n                    public void BenchmarkMethod()\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n\r\n            AddDefaultExpectedDiagnostic(benchmarkClassName);\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        public static IEnumerable<string> NonPublicClassAccessModifiersExceptFile\r\n            => new NonPublicClassAccessModifiersTheoryData().Where<string>(m => m != \"file \");\r\n    }\r\n\r\n    public class TypeArgumentClassMustBeUnsealed : AnalyzerTestFixture<RunAnalyzer>\r\n    {\r\n        public TypeArgumentClassMustBeUnsealed() : base(RunAnalyzer.TypeArgumentClassMustBeUnsealedRule) { }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Invoking_with_a_sealed_benchmark_class_should_trigger_diagnostic(bool isGenericInvocation)\r\n        {\r\n            const string benchmarkClassName = \"BenchmarkClass\";\r\n\r\n            var invocationExpression = isGenericInvocation ? $\"<{{|#0:{benchmarkClassName}|}}>()\" : $\"(typeof({{|#0:{benchmarkClassName}|}}))\";\r\n\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Running;\r\n\r\n                public class Program\r\n                {\r\n                    public static void Main(string[] args) {\r\n                        BenchmarkRunner.Run{{invocationExpression}};\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            const string benchmarkClassDocument = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public sealed class {{benchmarkClassName}}\r\n                {\r\n                    [Benchmark]\r\n                    public void BenchmarkMethod()\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n            TestCode = testCode;\r\n            AddSource(benchmarkClassDocument);\r\n            AddDefaultExpectedDiagnostic(benchmarkClassName);\r\n\r\n            await RunAsync();\r\n        }\r\n    }\r\n\r\n    public class TypeArgumentClassMustBeNonAbstract : AnalyzerTestFixture<RunAnalyzer>\r\n    {\r\n        public TypeArgumentClassMustBeNonAbstract() : base(RunAnalyzer.TypeArgumentClassMustBeNonAbstractRule) { }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Invoking_with_an_abstract_benchmark_class_should_trigger_diagnostic(bool isGenericInvocation)\r\n        {\r\n            const string benchmarkClassName = \"BenchmarkClass\";\r\n\r\n            var invocationExpression = isGenericInvocation ? $\"<{{|#0:{benchmarkClassName}|}}>()\" : $\"(typeof({{|#0:{benchmarkClassName}|}}))\";\r\n\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Running;\r\n\r\n                public class Program\r\n                {\r\n                    public static void Main(string[] args) {\r\n                        BenchmarkRunner.Run{{invocationExpression}};\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            const string benchmarkClassDocument = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public abstract class {{benchmarkClassName}}\r\n                {\r\n                    [Benchmark]\r\n                    public void BenchmarkMethod()\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            AddSource(benchmarkClassDocument);\r\n            AddDefaultExpectedDiagnostic(benchmarkClassName);\r\n\r\n            await RunAsync();\r\n        }\r\n    }\r\n\r\n    public class GenericTypeArgumentClassMustBeAnnotatedWithAGenericTypeArgumentsAttribute : AnalyzerTestFixture<RunAnalyzer>\r\n    {\r\n        public GenericTypeArgumentClassMustBeAnnotatedWithAGenericTypeArgumentsAttribute() : base(RunAnalyzer.GenericTypeArgumentClassMustBeAnnotatedWithAGenericTypeArgumentsAttributeRule) { }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Invoking_with_a_generic_class_annotated_with_at_least_one_generictypearguments_attribute_should_not_trigger_diagnostic(\r\n            [CombinatorialRange(1, 2)] int genericTypeArgumentsAttributeUsageCount,\r\n            [CombinatorialMemberData(nameof(TypeParametersListLengthEnumerableLocal))] int typeParametersListLength,\r\n            [CombinatorialMemberData(nameof(ClassAbstractModifiersEnumerableLocal))] string abstractModifier,\r\n            [CombinatorialMemberData(nameof(BenchmarkAttributeUsagesEnumerableLocal))] string benchmarkAttributeUsage)\r\n        {\r\n            const string benchmarkClassName = \"BenchmarkClass\";\r\n\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Running;\r\n\r\n                public class Program\r\n                {\r\n                    public static void Main(string[] args) {\r\n                        BenchmarkRunner.Run(typeof({{benchmarkClassName}}<{{new string(',', typeParametersListLength - 1)}}>));\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            var genericTypeArguments = string.Join(\", \", GenericTypeArguments.Select(ta => $\"typeof({ta})\").Take(typeParametersListLength));\r\n            var genericTypeArgumentsAttributeUsages = string.Join(\"\\n\", Enumerable.Repeat($\"[GenericTypeArguments({genericTypeArguments})]\", genericTypeArgumentsAttributeUsageCount));\r\n            var typeParameters = string.Join(\", \", TypeParameters.Take(typeParametersListLength));\r\n\r\n            var benchmarkClassDocument = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                {{genericTypeArgumentsAttributeUsages}}\r\n                public class BenchmarkClass<{{typeParameters}}> : BenchmarkClassAncestor1<{{typeParameters}}>\r\n                {\r\n                    {{benchmarkAttributeUsage}}\r\n                    public void BenchmarkMethod()\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            var benchmarkClassAncestor1Document = /* lang=c#-test */ $$\"\"\"\r\n                public {{abstractModifier}}class BenchmarkClassAncestor1<{{typeParameters}}> : BenchmarkClassAncestor2<{{typeParameters}}>\r\n                {\r\n\r\n                }\r\n                \"\"\";\r\n            var benchmarkClassAncestor2Document = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public {{abstractModifier}}class BenchmarkClassAncestor2<{{typeParameters}}>\r\n                {\r\n\r\n                    {{benchmarkAttributeUsage}}\r\n                    public void BenchmarkMethod()\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            AddSource(benchmarkClassDocument);\r\n            AddSource(benchmarkClassAncestor1Document);\r\n            AddSource(benchmarkClassAncestor2Document);\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Invoking_with_a_nongeneric_class_that_inherits_from_a_generic_class_not_annotated_with_a_generictypearguments_attribute_should_not_trigger_diagnostic(\r\n            bool isGenericInvocation,\r\n            [CombinatorialMemberData(nameof(TypeParametersListLengthEnumerableLocal))] int typeParametersListLength,\r\n            [CombinatorialMemberData(nameof(ClassAbstractModifiersEnumerableLocal))] string abstractModifier,\r\n            [CombinatorialMemberData(nameof(BenchmarkAttributeUsagesEnumerableLocal))] string benchmarkAttributeUsage)\r\n        {\r\n            const string benchmarkClassName = \"BenchmarkClass\";\r\n\r\n            var invocationExpression = isGenericInvocation ? $\"<{benchmarkClassName}>()\" : $\"(typeof({benchmarkClassName}))\";\r\n\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Running;\r\n\r\n                public class Program\r\n                {\r\n                    public static void Main(string[] args) {\r\n                        BenchmarkRunner.Run{{invocationExpression}};\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            var benchmarkClassDocument = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class {{benchmarkClassName}} : BenchmarkClassAncestor<{{string.Join(\", \", GenericTypeArguments.Take(typeParametersListLength))}}>\r\n                {\r\n\r\n                }\r\n                \"\"\";\r\n            var benchmarkClassAncestorDocument = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public {{abstractModifier}}class BenchmarkClassAncestor<{{string.Join(\", \", TypeParameters.Take(typeParametersListLength))}}>\r\n                {\r\n\r\n                    {{benchmarkAttributeUsage}}\r\n                    public void BenchmarkMethod()\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            AddSource(benchmarkClassDocument);\r\n            AddSource(benchmarkClassAncestorDocument);\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task A_generic_class_not_referenced_in_run_method_should_not_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(ClassAbstractModifiersEnumerableLocal))] string abstractModifier,\r\n            [CombinatorialMemberData(nameof(TypeParametersListLengthEnumerableLocal))] int typeParametersListLength,\r\n            [CombinatorialMemberData(nameof(BenchmarkAttributeUsagesEnumerableLocal))] string benchmarkAttributeUsage)\r\n        {\r\n            var typeParameters = string.Join(\", \", TypeParameters.Take(typeParametersListLength));\r\n\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass<{{string.Join(\", \", TypeParameters.Take(typeParametersListLength))}}> : BenchmarkClassAncestor1<{{typeParameters}}>\r\n                {\r\n                }\r\n                \"\"\";\r\n\r\n            var benchmarkClassAncestor1Document = /* lang=c#-test */ $$\"\"\"\r\n                public {{abstractModifier}}class BenchmarkClassAncestor1<{{typeParameters}}> : BenchmarkClassAncestor2<{{typeParameters}}>\r\n                {\r\n                }\r\n                \"\"\";\r\n\r\n            var benchmarkClassAncestor2Document = /* lang=c#-test */ $$\"\"\"\r\n                public {{abstractModifier}}class BenchmarkClassAncestor2<{{typeParameters}}> : BenchmarkClassAncestor3\r\n                {\r\n                }\r\n                \"\"\";\r\n\r\n            var benchmarkClassAncestor3Document = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public {{abstractModifier}}class BenchmarkClassAncestor3\r\n                {\r\n                    {{benchmarkAttributeUsage}}\r\n                    public void BenchmarkMethod()\r\n                    {\r\n\r\n                    }\r\n\r\n                    public void BenchmarkMethod2()\r\n                    {\r\n\r\n                    }\r\n\r\n                    private void BenchmarkMethod3()\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            AddSource(benchmarkClassAncestor1Document);\r\n            AddSource(benchmarkClassAncestor2Document);\r\n            AddSource(benchmarkClassAncestor3Document);\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Invoking_with_a_generic_class_not_annotated_with_a_generictypearguments_attribute_should_trigger_diagnostic(\r\n            [CombinatorialRange(0, 3)] int genericTypeArgumentsAttributeUsageCount,\r\n            [CombinatorialMemberData(nameof(TypeParametersListLengthEnumerableLocal))] int typeParametersListLength,\r\n            [CombinatorialMemberData(nameof(ClassAbstractModifiersEnumerableLocal))] string abstractModifier,\r\n            [CombinatorialMemberData(nameof(BenchmarkAttributeUsagesEnumerableLocal))] string benchmarkAttributeUsage)\r\n        {\r\n            const string benchmarkClassName = \"BenchmarkClass\";\r\n\r\n            var unboundGenericTypeParameterList = new string(',', typeParametersListLength - 1);\r\n            var typeParameters = string.Join(\", \", TypeParameters.Take(typeParametersListLength));\r\n            var genericTypeArguments = string.Join(\", \", GenericTypeArguments.Select(ta => $\"typeof({ta})\").Take(typeParametersListLength));\r\n            var genericTypeArgumentsAttributeUsages = string.Join(\"\\n\", Enumerable.Repeat($\"[GenericTypeArguments({genericTypeArguments})]\", genericTypeArgumentsAttributeUsageCount));\r\n\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Running;\r\n\r\n                public class Program\r\n                {\r\n                    public static void Main(string[] args) {\r\n                        BenchmarkRunner.Run(typeof({|#0:{{benchmarkClassName}}<{{unboundGenericTypeParameterList}}>|}));\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            var benchmarkClassDocument = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class {{benchmarkClassName}}<{{typeParameters}}> : BenchmarkClassAncestor1<{{typeParameters}}>\r\n                {\r\n                    {{benchmarkAttributeUsage}}\r\n                    public void BenchmarkMethod()\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            var benchmarkClassAncestor1Document = /* lang=c#-test */ $$\"\"\"\r\n                public {{abstractModifier}}class BenchmarkClassAncestor1<{{typeParameters}}> : BenchmarkClassAncestor2<{{typeParameters}}>\r\n                {\r\n\r\n                }\r\n                \"\"\";\r\n\r\n            var benchmarkClassAncestor2Document = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                {{genericTypeArgumentsAttributeUsages}}\r\n                public {{abstractModifier}}class BenchmarkClassAncestor2<{{typeParameters}}>\r\n                {\r\n\r\n                    {{benchmarkAttributeUsage}}\r\n                    public void BenchmarkMethod()\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            AddSource(benchmarkClassDocument);\r\n            AddSource(benchmarkClassAncestor1Document);\r\n            AddSource(benchmarkClassAncestor2Document);\r\n\r\n            AddDefaultExpectedDiagnostic($\"{benchmarkClassName}<{unboundGenericTypeParameterList}>\");\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        public static IEnumerable<string> ClassAbstractModifiersEnumerableLocal\r\n            => ClassAbstractModifiersEnumerable;\r\n\r\n        public static IEnumerable<string> BenchmarkAttributeUsagesEnumerableLocal\r\n            => BenchmarkAttributeUsagesEnumerable;\r\n\r\n        public static IEnumerable<int> TypeParametersListLengthEnumerableLocal\r\n            => TypeParametersListLengthEnumerable;\r\n    }\r\n\r\n    public static IEnumerable<string> ClassAbstractModifiersEnumerable\r\n        => [\"\", \"abstract \"];\r\n\r\n    public static IEnumerable<string> BenchmarkAttributeUsagesEnumerable\r\n        => [\"\", \"[Benchmark]\"];\r\n\r\n    public static IEnumerable<int> TypeParametersListLengthEnumerable\r\n        => Enumerable.Range(1, TypeParameters.Count);\r\n\r\n    private static ReadOnlyCollection<string> TypeParameters\r\n        => Enumerable.Range(1, 3)\r\n        .Select(i => $\"TParameter{i}\")\r\n        .ToList()\r\n        .AsReadOnly();\r\n\r\n    private static IReadOnlyCollection<string> GenericTypeArguments\r\n        => [\"int\", \"string\", \"bool\"];\r\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Analyzers.Tests/AnalyzerTests/General/BenchmarkClassAnalyzerTests.cs",
    "content": "﻿using BenchmarkDotNet.Analyzers.General;\r\nusing BenchmarkDotNet.Analyzers.Tests.Fixtures;\r\nusing System.Collections.Generic;\r\nusing System.Collections.ObjectModel;\r\nusing System.Linq;\r\nusing System.Threading.Tasks;\r\nusing Xunit;\r\n\r\nnamespace BenchmarkDotNet.Analyzers.Tests.AnalyzerTests.General;\r\n\r\npublic class BenchmarkClassAnalyzerTests\r\n{\r\n    public class General : AnalyzerTestFixture<BenchmarkClassAnalyzer>\r\n    {\r\n        [Theory]\r\n        [InlineData(\"\")]\r\n        [InlineData(\" abstract\")]\r\n        public async Task Class_not_annotated_with_any_generictypearguments_attributes_and_with_no_methods_annotated_with_benchmark_attribute_should_not_trigger_diagnostic(string abstractModifier)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public{{abstractModifier}} class BenchmarkClass\r\n                {\r\n                    public void BenchmarkMethod()\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n\r\n            await RunAsync();\r\n        }\r\n    }\r\n\r\n    public class ClassWithGenericTypeArgumentsAttributeMustBeGeneric : AnalyzerTestFixture<BenchmarkClassAnalyzer>\r\n    {\r\n        public ClassWithGenericTypeArgumentsAttributeMustBeGeneric() : base(BenchmarkClassAnalyzer.ClassWithGenericTypeArgumentsAttributeMustBeGenericRule) { }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Generic_class_annotated_with_a_generictypearguments_attribute_should_not_trigger_diagnostic(\r\n            [CombinatorialRange(1, 2)] int genericTypeArgumentsAttributeUsageCount,\r\n            [CombinatorialMemberData(nameof(BenchmarkAttributeUsagesEnumerableLocal))] string benchmarkAttributeUsage)\r\n        {\r\n            var genericTypeArgumentsAttributeUsages = Enumerable.Repeat(\"[GenericTypeArguments(typeof(int))]\", genericTypeArgumentsAttributeUsageCount);\r\n\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                {{string.Join(\"\\n\", genericTypeArgumentsAttributeUsages)}}\r\n                public class BenchmarkClass<TParameter>\r\n                {\r\n                    {{benchmarkAttributeUsage}}\r\n                    public void BenchmarkMethod()\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Nongeneric_class_annotated_with_a_generictypearguments_attribute_should_trigger_diagnostic(\r\n            [CombinatorialRange(1, 2)] int genericTypeArgumentsAttributeUsageCount,\r\n            [CombinatorialMemberData(nameof(BenchmarkAttributeUsagesEnumerableLocal))] string benchmarkAttributeUsage)\r\n        {\r\n            var genericTypeArgumentsAttributeUsages = Enumerable.Repeat(\"[{{|#{0}:GenericTypeArguments(typeof(int))|}}]\", genericTypeArgumentsAttributeUsageCount)\r\n                .Select((a, i) => string.Format(a, i));\r\n\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n                                               \r\n                {{string.Join(\"\\n\", genericTypeArgumentsAttributeUsages)}}\r\n                public class BenchmarkClass\r\n                {\r\n                    {{benchmarkAttributeUsage}}\r\n                    public void BenchmarkMethod()\r\n                    {\r\n                                               \r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n\r\n            for (var i = 0; i < genericTypeArgumentsAttributeUsageCount; i++)\r\n            {\r\n                AddExpectedDiagnostic(i);\r\n            }\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Nongeneric_class_annotated_with_a_generictypearguments_attribute_inheriting_from_an_abstract_generic_class_should_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(TypeParametersListLengthEnumerableLocal))] int typeParametersListLength,\r\n            [CombinatorialRange(1, 2)] int genericTypeArgumentsAttributeUsageCount,\r\n            [CombinatorialMemberData(nameof(BenchmarkAttributeUsagesEnumerableLocal))] string benchmarkAttributeUsage)\r\n        {\r\n            var genericTypeArguments = string.Join(\", \", GenericTypeArguments.Select(ta => $\"typeof({ta})\").Take(typeParametersListLength));\r\n            var genericTypeArgumentsAttributeUsages = Enumerable.Repeat($\"[{{{{|#{{0}}:GenericTypeArguments({genericTypeArguments})|}}}}]\", genericTypeArgumentsAttributeUsageCount)\r\n                .Select((a, i) => string.Format(a, i));\r\n\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                {{string.Join(\"\\n\", genericTypeArgumentsAttributeUsages)}}\r\n                public class BenchmarkClass : BenchmarkClassBase<{{string.Join(\", \", GenericTypeArguments.Take(typeParametersListLength))}}>\r\n                {\r\n                }\r\n                \"\"\";\r\n\r\n            var benchmarkBaseClassDocument = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public abstract class BenchmarkClassBase<{{string.Join(\", \", TypeParameters.Take(typeParametersListLength))}}>\r\n                {\r\n                    {{benchmarkAttributeUsage}}\r\n                    public void BenchmarkMethod()\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            AddSource(benchmarkBaseClassDocument);\r\n\r\n            for (var i = 0; i < genericTypeArgumentsAttributeUsageCount; i++)\r\n            {\r\n                AddExpectedDiagnostic(i);\r\n            }\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        public static IEnumerable<int> TypeParametersListLengthEnumerableLocal\r\n            => TypeParametersListLengthEnumerable;\r\n\r\n        private static ReadOnlyCollection<string> TypeParameters\r\n            => TypeParametersTheoryData;\r\n\r\n        private static IReadOnlyCollection<string> GenericTypeArguments\r\n            => GenericTypeArgumentsTheoryData;\r\n\r\n        public static IEnumerable<string> BenchmarkAttributeUsagesEnumerableLocal\r\n            => BenchmarkAttributeUsagesEnumerable;\r\n    }\r\n\r\n    public class GenericTypeArgumentsAttributeMustHaveMatchingTypeParameterCount : AnalyzerTestFixture<BenchmarkClassAnalyzer>\r\n    {\r\n        public GenericTypeArgumentsAttributeMustHaveMatchingTypeParameterCount() : base(BenchmarkClassAnalyzer.GenericTypeArgumentsAttributeMustHaveMatchingTypeParameterCountRule) { }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Generic_class_annotated_with_a_generictypearguments_attribute_having_matching_type_argument_count_should_not_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(TypeParametersListLengthEnumerableLocal))] int typeParametersListLength,\r\n            [CombinatorialRange(1, 2)] int genericTypeArgumentsAttributeUsageCount,\r\n            [CombinatorialMemberData(nameof(BenchmarkAttributeUsagesEnumerableLocal))] string benchmarkAttributeUsage)\r\n        {\r\n            var genericTypeArguments = string.Join(\", \", GenericTypeArguments.Select(ta => $\"typeof({ta})\").Take(typeParametersListLength));\r\n            var genericTypeArgumentsAttributeUsages = Enumerable.Repeat($\"[GenericTypeArguments({genericTypeArguments})]\", genericTypeArgumentsAttributeUsageCount);\r\n\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                {{string.Join(\"\\n\", genericTypeArgumentsAttributeUsages)}}\r\n                public class BenchmarkClass<{{string.Join(\", \", TypeParameters.Take(typeParametersListLength))}}>\r\n                {\r\n                    {{benchmarkAttributeUsage}}\r\n                    public void BenchmarkMethod()\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Generic_class_annotated_with_a_generictypearguments_attribute_having_mismatching_type_argument_count_should_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(TypeArgumentsData))] ValueTupleDouble<string, int> typeArgumentsData,\r\n            [CombinatorialMemberData(nameof(BenchmarkAttributeUsagesEnumerableLocal))] string benchmarkAttributeUsage)\r\n        {\r\n            const string benchmarkClassName = \"BenchmarkClass\";\r\n\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                [GenericTypeArguments({|#0:{{typeArgumentsData.Value1}}|})]\r\n                [GenericTypeArguments(typeof(int))]\r\n                public class {{benchmarkClassName}}<T1>\r\n                {\r\n                    {{benchmarkAttributeUsage}}\r\n                    public void BenchmarkMethod()\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            AddDefaultExpectedDiagnostic(1, \"\", benchmarkClassName, typeArgumentsData.Value2);\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        public static IEnumerable<ValueTupleDouble<string, int>> TypeArgumentsData =>\r\n        [\r\n            (\"typeof(int), typeof(string)\", 2),\r\n            (\"typeof(int), typeof(string), typeof(bool)\", 3)\r\n        ];\r\n\r\n        public static IEnumerable<int> TypeParametersListLengthEnumerableLocal\r\n            => TypeParametersListLengthEnumerable;\r\n\r\n        private static ReadOnlyCollection<string> TypeParameters\r\n            => TypeParametersTheoryData;\r\n\r\n        private static IReadOnlyCollection<string> GenericTypeArguments\r\n            => GenericTypeArgumentsTheoryData;\r\n\r\n        public static IEnumerable<string> BenchmarkAttributeUsagesEnumerableLocal\r\n            => BenchmarkAttributeUsagesEnumerable;\r\n    }\r\n\r\n    public class MethodMustBePublic : AnalyzerTestFixture<BenchmarkClassAnalyzer>\r\n    {\r\n        public MethodMustBePublic() : base(BenchmarkClassAnalyzer.MethodMustBePublicRule) { }\r\n\r\n        [Fact]\r\n        public async Task Public_method_annotated_with_benchmark_attribute_should_not_trigger_diagnostic()\r\n        {\r\n            const string testCode = /* lang=c#-test */ \"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [Benchmark]\r\n                    public void BenchmarkMethod()\r\n                    {\r\n\r\n                    }\r\n\r\n                    public void NonBenchmarkMethod()\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory]\r\n        [ClassData(typeof(NonPublicClassMemberAccessModifiersTheoryData))]\r\n        public async Task Nonpublic_method_annotated_with_benchmark_attribute_should_trigger_diagnostic(string nonPublicClassAccessModifier)\r\n        {\r\n            const string benchmarkMethodName = \"BenchmarkMethod\";\r\n\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [Benchmark]\r\n                    {{nonPublicClassAccessModifier}}void {|#0:{{benchmarkMethodName}}|}()\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            AddDefaultExpectedDiagnostic(benchmarkMethodName);\r\n\r\n            await RunAsync();\r\n        }\r\n    }\r\n\r\n    public class MethodMustBeNonGeneric : AnalyzerTestFixture<BenchmarkClassAnalyzer>\r\n    {\r\n        public MethodMustBeNonGeneric() : base(BenchmarkClassAnalyzer.MethodMustBeNonGenericRule) { }\r\n\r\n        [Fact]\r\n        public async Task Nongeneric_method_annotated_with_benchmark_attribute_should_not_trigger_diagnostic()\r\n        {\r\n            const string testCode = /* lang=c#-test */ \"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [Benchmark]\r\n                    public void NonGenericBenchmarkMethod()\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Fact]\r\n        public async Task Generic_method_not_annotated_with_benchmark_attribute_should_not_trigger_diagnostic()\r\n        {\r\n            const string testCode = /* lang=c#-test */ \"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    public void GenericMethod<T>()\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory]\r\n        [MemberData(nameof(TypeParametersListLength))]\r\n        public async Task Nongeneric_method_annotated_with_benchmark_attribute_should_trigger_diagnostic(int typeParametersListLength)\r\n        {\r\n            const string benchmarkMethodName = \"GenericBenchmarkMethod\";\r\n\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [Benchmark]\r\n                    public void {{benchmarkMethodName}}{|#0:<{{string.Join(\", \", TypeParameters.Take(typeParametersListLength))}}>|}()\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            AddDefaultExpectedDiagnostic(benchmarkMethodName);\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        public static TheoryData<int> TypeParametersListLength\r\n            => TypeParametersListLengthTheoryData;\r\n\r\n        private static ReadOnlyCollection<string> TypeParameters\r\n            => TypeParametersTheoryData;\r\n    }\r\n\r\n    public class ClassMustBeNonStatic : AnalyzerTestFixture<BenchmarkClassAnalyzer>\r\n    {\r\n        public ClassMustBeNonStatic() : base(BenchmarkClassAnalyzer.ClassMustBeNonStaticRule) { }\r\n\r\n        [Fact]\r\n        public async Task Instance_class_containing_at_least_one_method_annotated_with_benchmark_attribute_should_not_trigger_diagnostic()\r\n        {\r\n            const string testCode = /* lang=c#-test */ \"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass\r\n                {\r\n                    [Benchmark]\r\n                    public void BenchmarkMethod()\r\n                    {\r\n\r\n                    }\r\n\r\n                    public void NonBenchmarkMethod()\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Fact]\r\n        public async Task Static_class_containing_at_least_one_method_annotated_with_benchmark_attribute_should_trigger_diagnostic()\r\n        {\r\n            const string benchmarkClassName = \"BenchmarkClass\";\r\n\r\n            const string testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public {|#0:static|} class {{benchmarkClassName}}\r\n                {\r\n                    [Benchmark]\r\n                    public static void BenchmarkMethod()\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            AddDefaultExpectedDiagnostic(benchmarkClassName);\r\n\r\n            await RunAsync();\r\n        }\r\n    }\r\n\r\n    public class SingleNullArgumentToBenchmarkCategoryAttributeNotAllowed : AnalyzerTestFixture<BenchmarkClassAnalyzer>\r\n    {\r\n        public SingleNullArgumentToBenchmarkCategoryAttributeNotAllowed() : base(BenchmarkClassAnalyzer.SingleNullArgumentToBenchmarkCategoryAttributeNotAllowedRule)\r\n        {\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Providing_a_non_null_single_argument_should_not_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(ClassAbstractModifiersEnumerableLocal))] string abstractModifier,\r\n            bool useConstantFromOtherClass,\r\n            bool useLocalConstant,\r\n            [CombinatorialMemberData(nameof(BenchmarkAttributeUsagesEnumerableLocal))] string benchmarkAttributeUsage)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                [assembly: BenchmarkDotNet.Attributes.BenchmarkCategory({{(useConstantFromOtherClass ? \"Constants.Value\" : \"\\\"test\\\"\")}})]\r\n\r\n                public class BenchmarkClass : BenchmarkClassAncestor1\r\n                {\r\n                }\r\n                \"\"\";\r\n\r\n            var benchmarkCategoryAttributeUsage = $\"[BenchmarkCategory({(useLocalConstant ? \"_x\" : useConstantFromOtherClass ? \"Constants.Value\" : \"\\\"test\\\"\")})]\";\r\n\r\n            var benchmarkClassAncestor1Document = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                {{benchmarkCategoryAttributeUsage}}\r\n                public {{abstractModifier}}class BenchmarkClassAncestor1\r\n                {\r\n                    {{(useLocalConstant ? $\"private const string _x = {(useConstantFromOtherClass ? \"Constants.Value\" : \"\\\"test\\\"\")};\" : \"\")}}\r\n\r\n                    {{benchmarkCategoryAttributeUsage}}\r\n                    {{benchmarkAttributeUsage}}\r\n                    public void BenchmarkMethod()\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            AddSource(benchmarkClassAncestor1Document);\r\n            ReferenceConstants(\"string\", \"\\\"test\\\"\");\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Providing_an_empty_array_argument_should_not_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(ClassAbstractModifiersEnumerableLocal))] string abstractModifier,\r\n            [CombinatorialMemberData(nameof(EmptyBenchmarkCategoryAttributeArgumentEnumerableLocal))] string emptyBenchmarkCategoryAttributeArgument,\r\n            [CombinatorialMemberData(nameof(BenchmarkAttributeUsagesEnumerableLocal))] string benchmarkAttributeUsage)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                [assembly: BenchmarkDotNet.Attributes.BenchmarkCategory{{emptyBenchmarkCategoryAttributeArgument}}]\r\n\r\n                public class BenchmarkClass : BenchmarkClassAncestor1\r\n                {\r\n                }\r\n                \"\"\";\r\n\r\n            var benchmarkClassAncestor1Document = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                [BenchmarkCategory{{emptyBenchmarkCategoryAttributeArgument}}]\r\n                public {{abstractModifier}}class BenchmarkClassAncestor1\r\n                {\r\n                    [BenchmarkCategory{{emptyBenchmarkCategoryAttributeArgument}}]\r\n                    {{benchmarkAttributeUsage}}\r\n                    public void BenchmarkMethod()\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            AddSource(benchmarkClassAncestor1Document);\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Providing_an_array_argument_containing_one_or_more_null_values_should_not_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(ClassAbstractModifiersEnumerableLocal))] string abstractModifier,\r\n            bool useConstantsFromOtherClass,\r\n            bool useLocalConstants,\r\n            [CombinatorialValues(\"{0}\", \"{0}, {1}\", \"{1}, {0}\", \"{0}, {1}, {0}\", \"{1}, {0}, {1}\")] string valuesTemplate,\r\n            [CombinatorialMemberData(nameof(BenchmarkCategoryAttributeValuesContainerEnumerableLocal), false)] string valuesContainer,\r\n            [CombinatorialMemberData(nameof(BenchmarkAttributeUsagesEnumerableLocal))] string benchmarkAttributeUsage)\r\n        {\r\n            var assemblyLevelAttributeValues = string.Format(valuesContainer,\r\n                string.Format(valuesTemplate,\r\n                    useConstantsFromOtherClass ? \"Constants.Value1\" : \"null\",\r\n                    useConstantsFromOtherClass ? \"Constants.Value2\" : \"\\\"test\\\"\"\r\n                )\r\n            );\r\n\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                [assembly: BenchmarkDotNet.Attributes.BenchmarkCategory({{assemblyLevelAttributeValues}})]\r\n\r\n                public class BenchmarkClass : BenchmarkClassAncestor1\r\n                {\r\n                }\r\n                \"\"\";\r\n\r\n            var classAndMethodAttributeLevelValues = string.Format(valuesContainer,\r\n                string.Format(valuesTemplate,\r\n                    useLocalConstants ? \"_xNull\" : useConstantsFromOtherClass ? \"Constants.Value1\" : \"null\",\r\n                    useLocalConstants ? \"_xValue\" : useConstantsFromOtherClass ? \"Constants.Value2\" : \"\\\"test\\\"\"\r\n                )\r\n            );\r\n\r\n            var benchmarkClassAncestor1Document = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                [BenchmarkCategory({{classAndMethodAttributeLevelValues}})]\r\n                public {{abstractModifier}}class BenchmarkClassAncestor1\r\n                {\r\n                    {{(useLocalConstants ? $\"\"\"\r\n                                            private const string _xNull = {(useConstantsFromOtherClass ? \"Constants.Value1\" : \"null\")};\r\n                                            private const string _xValue = {(useConstantsFromOtherClass ? \"Constants.Value2\" : \"\\\"test\\\"\")};\r\n                                            \"\"\" : \"\")}}\r\n\r\n                    [BenchmarkCategory({{classAndMethodAttributeLevelValues}})]\r\n                    {{benchmarkAttributeUsage}}\r\n                    public void BenchmarkMethod()\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            AddSource(benchmarkClassAncestor1Document);\r\n            ReferenceConstants((\"string\", \"null\"), (\"string\", \"\\\"test\\\"\"));\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Providing_a_null_single_argument_should_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(ClassAbstractModifiersEnumerableLocal))] string abstractModifier,\r\n            bool useConstantFromOtherClass,\r\n            bool useLocalConstant,\r\n            [CombinatorialMemberData(nameof(BenchmarkAttributeUsagesEnumerableLocal))] string benchmarkAttributeUsage)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                [assembly: BenchmarkDotNet.Attributes.BenchmarkCategory({|#0:{{(useConstantFromOtherClass ? \"Constants.Value\" : \"null\")}}|})]\r\n\r\n                public class BenchmarkClass : BenchmarkClassAncestor1\r\n                {\r\n                }\r\n                \"\"\";\r\n\r\n            var benchmarkClassAncestor1Document = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                [BenchmarkCategory({|#1:{{(useLocalConstant ? \"_x\" : useConstantFromOtherClass ? \"Constants.Value\" : \"null\")}}|})]\r\n                public {{abstractModifier}}class BenchmarkClassAncestor1\r\n                {\r\n                    {{(useLocalConstant ? $\"private const string _x = {(useConstantFromOtherClass ? \"Constants.Value\" : \"null\")};\" : \"\")}}\r\n\r\n                    [BenchmarkCategory({|#2:{{(useLocalConstant ? \"_x\" : useConstantFromOtherClass ? \"Constants.Value\" : \"null\")}}|})]\r\n                    {{benchmarkAttributeUsage}}\r\n                    public void BenchmarkMethod()\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            AddSource(benchmarkClassAncestor1Document);\r\n            ReferenceConstants(\"string\", \"null\");\r\n\r\n            AddExpectedDiagnostic(0);\r\n            AddExpectedDiagnostic(1);\r\n            AddExpectedDiagnostic(2);\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        public static IEnumerable<string> ClassAbstractModifiersEnumerableLocal\r\n            => ClassAbstractModifiersEnumerable;\r\n\r\n        public static IEnumerable<string> BenchmarkAttributeUsagesEnumerableLocal\r\n            => BenchmarkAttributeUsagesEnumerable;\r\n\r\n        public static IEnumerable<string> EmptyBenchmarkCategoryAttributeArgumentEnumerableLocal\r\n            => EmptyBenchmarkCategoryAttributeArgumentEnumerable();\r\n\r\n        public static IEnumerable<string> BenchmarkCategoryAttributeValuesContainerEnumerableLocal(bool useParamsValues)\r\n            => BenchmarkCategoryAttributeValuesContainerEnumerable(useParamsValues);\r\n    }\r\n\r\n    public class OnlyOneMethodCanBeBaseline : AnalyzerTestFixture<BenchmarkClassAnalyzer>\r\n    {\r\n        public OnlyOneMethodCanBeBaseline() : base(BenchmarkClassAnalyzer.OnlyOneMethodCanBeBaselineRule) { }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Class_with_only_one_benchmark_method_marked_as_baseline_should_not_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(ClassAbstractModifiersEnumerableLocal))] string abstractModifier,\r\n            bool useConstantsFromOtherClass,\r\n            bool useLocalConstants,\r\n            bool useInvalidFalseValue)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass : BenchmarkClassAncestor1\r\n                {\r\n                    {{(useLocalConstants ? $\"\"\"\r\n                                            private const bool _xTrue = {(useConstantsFromOtherClass ? \"Constants.Value1\" : \"true\")};\r\n                                            private const bool _xFalse = {(useConstantsFromOtherClass ? \"Constants.Value2\" : useInvalidFalseValue ? \"dummy\" : \"false\")};\r\n                                            \"\"\" : \"\")}}\r\n\r\n                    [Benchmark(Baseline = {{(useLocalConstants ? \"_xTrue\" : useConstantsFromOtherClass ? \"Constants.Value1\" : \"true\")}})]\r\n                    public void BaselineBenchmarkMethod()\r\n                    {\r\n\r\n                    }\r\n\r\n                    [Benchmark]\r\n                    public void NonBaselineBenchmarkMethod1()\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            var benchmarkClassAncestor1Document = /* lang=c#-test */ $$\"\"\"\r\n                public {{abstractModifier}}class BenchmarkClassAncestor1 : BenchmarkClassAncestor2, System.IEquatable<BenchmarkClassAncestor1>\r\n                {\r\n                }\r\n                \"\"\";\r\n\r\n            var benchmarkClassAncestor2Document = /* lang=c#-test */ $$\"\"\"\r\n                public {{abstractModifier}}class BenchmarkClassAncestor2 : BenchmarkClassAncestor3\r\n                {\r\n                }\r\n                \"\"\";\r\n\r\n            var benchmarkClassAncestor3Document = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public {{abstractModifier}}class BenchmarkClassAncestor3\r\n                {\r\n                    {{(useLocalConstants ? $\"private const bool _xFalse = {(useConstantsFromOtherClass ? \"Constants.Value2\" : useInvalidFalseValue ? \"dummy\" : \"false\")};\" : \"\")}}\r\n\r\n                    [Benchmark(Baseline = {{(useLocalConstants ? \"_xFalse\" : useConstantsFromOtherClass ? \"Constants.Value2\" : useInvalidFalseValue ? \"dummy\" : \"false\")}})]\r\n                    public void NonBaselineBenchmarkMethod2()\r\n                    {\r\n\r\n                    }\r\n\r\n                    public void BenchmarkMethod2()\r\n                    {\r\n\r\n                    }\r\n\r\n                    private void BenchmarkMethod3()\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            AddSource(benchmarkClassAncestor1Document);\r\n            AddSource(benchmarkClassAncestor2Document);\r\n            AddSource(benchmarkClassAncestor3Document);\r\n            ReferenceConstants((\"bool\", \"true\"), (\"bool\", useInvalidFalseValue ? \"dummy\" : \"false\"));\r\n\r\n            DisableCompilerDiagnostics();\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Class_with_duplicated_benchmark_attribute_usages_per_method_should_not_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(ClassAbstractModifiersEnumerableLocal))] string abstractModifier,\r\n            bool useConstantsFromOtherClass,\r\n            bool useLocalConstants,\r\n            [CombinatorialValues(2, 3)] int baselineBenchmarkAttributeUsageCount)\r\n        {\r\n            var baselineBenchmarkAttributeUsages = string.Join(\r\n                \"\\n\", Enumerable.Repeat($\"[Benchmark(Baseline = {(useLocalConstants ? \"_xTrue\" : useConstantsFromOtherClass ? \"Constants.Value1\" : \"true\")})]\",\r\n                baselineBenchmarkAttributeUsageCount)\r\n            );\r\n\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass : BenchmarkClassAncestor1\r\n                {\r\n                    {{(useLocalConstants ? $\"\"\"\r\n                                            private const bool _xTrue = {(useConstantsFromOtherClass ? \"Constants.Value1\" : \"true\")};\r\n                                            private const bool _xFalse = {(useConstantsFromOtherClass ? \"Constants.Value2\" : \"false\")};\r\n                                            \"\"\" : \"\")}}\r\n\r\n                    {{baselineBenchmarkAttributeUsages}}\r\n                    public void BaselineBenchmarkMethod()\r\n                    {\r\n\r\n                    }\r\n\r\n                    [Benchmark]\r\n                    public void NonBaselineBenchmarkMethod1()\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            var benchmarkClassAncestor1Document = /* lang=c#-test */ $$\"\"\"\r\n                public {{abstractModifier}}class BenchmarkClassAncestor1 : BenchmarkClassAncestor2, System.IEquatable<BenchmarkClassAncestor1>\r\n                {\r\n                }\r\n                \"\"\";\r\n\r\n            var benchmarkClassAncestor2Document = /* lang=c#-test */ $$\"\"\"\r\n                public {{abstractModifier}}class BenchmarkClassAncestor2 : BenchmarkClassAncestor3\r\n                {\r\n                }\r\n                \"\"\";\r\n\r\n            var benchmarkClassAncestor3Document = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public {{abstractModifier}}class BenchmarkClassAncestor3\r\n                {\r\n                    {{(useLocalConstants ? $\"private const bool _xFalse = {(useConstantsFromOtherClass ? \"Constants.Value2\" : \"false\")};\" : \"\")}}\r\n\r\n                    {{baselineBenchmarkAttributeUsages}}\r\n                    public void NonBaselineBenchmarkMethod2()\r\n                    {\r\n\r\n                    }\r\n\r\n                    public void BenchmarkMethod2()\r\n                    {\r\n\r\n                    }\r\n\r\n                    private void BenchmarkMethod3()\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            AddSource(benchmarkClassAncestor1Document);\r\n            AddSource(benchmarkClassAncestor2Document);\r\n            AddSource(benchmarkClassAncestor3Document);\r\n            ReferenceConstants((\"bool\", \"true\"), (\"bool\", \"false\"));\r\n\r\n            DisableCompilerDiagnostics();\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Class_with_no_benchmark_methods_marked_as_baseline_should_not_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(ClassAbstractModifiersEnumerableLocal))] string abstractModifier,\r\n            bool useConstantFromOtherClass,\r\n            bool useLocalConstant,\r\n            bool useInvalidFalseValue)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass : BenchmarkClassAncestor1\r\n                {\r\n                    {{(useLocalConstant ? $\"private const bool _xFalse = {(useConstantFromOtherClass ? \"Constants.Value\" : useInvalidFalseValue ? \"dummy\" : \"false\")};\" : \"\")}}\r\n\r\n                    [Benchmark]\r\n                    public void NonBaselineBenchmarkMethod1()\r\n                    {\r\n\r\n                    }\r\n\r\n                    [Benchmark]\r\n                    public void NonBaselineBenchmarkMethod2()\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            var benchmarkClassAncestor1Document = /* lang=c#-test */ $$\"\"\"\r\n                public {{abstractModifier}}class BenchmarkClassAncestor1 : BenchmarkClassAncestor2\r\n                {\r\n                }\r\n                \"\"\";\r\n\r\n            var benchmarkClassAncestor2Document = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public {{abstractModifier}}class BenchmarkClassAncestor2\r\n                {\r\n                    [Benchmark(Baseline = {{(useLocalConstant ? \"_xFalse\" : useConstantFromOtherClass ? \"Constants.Value\" : useInvalidFalseValue ? \"dummy\" : \"false\")}})]\r\n                    public void NonBaselineBenchmarkMethod3()\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceConstants(\"bool\", useInvalidFalseValue ? \"dummy\" : \"false\");\r\n            AddSource(benchmarkClassAncestor1Document);\r\n            AddSource(benchmarkClassAncestor2Document);\r\n\r\n            DisableCompilerDiagnostics();\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Class_with_more_than_one_benchmark_method_marked_as_baseline_per_unique_category_should_not_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(ClassAbstractModifiersEnumerableLocal))] string abstractModifier,\r\n            bool useConstantsFromOtherClass,\r\n            bool useLocalConstants,\r\n            [CombinatorialMemberData(nameof(BenchmarkCategoryAttributeValuesContainerEnumerableLocal), true)] string valuesContainer)\r\n        {\r\n            var baselineBenchmarkAttributeUsage = $\"[Benchmark(Baseline = {(useLocalConstants ? \"_xTrue\" : useConstantsFromOtherClass ? \"Constants.Value1\" : \"true\")})]\";\r\n            var nonBaselineBenchmarkAttributeUsage = $\"[Benchmark(Baseline = {(useLocalConstants ? \"_xFalse\" : useConstantsFromOtherClass ? \"Constants.Value2\" : \"false\")})]\";\r\n\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass : BenchmarkClassAncestor1\r\n                {\r\n                    {{(useLocalConstants ? $\"\"\"\r\n                                            private const bool _xTrue = {(useConstantsFromOtherClass ? \"Constants.Value1\" : \"true\")};\r\n                                            private const bool _xFalse = {(useConstantsFromOtherClass ? \"Constants.Value2\" : \"false\")};\r\n                                            \"\"\" : \"\")}}\r\n\r\n                    [BenchmarkCategory({{string.Format(valuesContainer, \"\"\"\r\n                                                                        null, \"test\", null, \"TEST\", \"test2\"\r\n                                                                        \"\"\")}})]\r\n                    {{baselineBenchmarkAttributeUsage}}\r\n                    public void BaselineBenchmarkMethod1()\r\n                    {\r\n\r\n                    }\r\n\r\n\r\n                    [BenchmarkCategory({{string.Format(valuesContainer, \"null, null\")}})]\r\n                    [BenchmarkCategory({{string.Format(valuesContainer, \"\"\"\r\n                                                                        \"test\", null\r\n                                                                        \"\"\")}})]\r\n                    [BenchmarkCategory({{string.Format(valuesContainer, \"\"\"\r\n                                                                        \"test2\"\r\n                                                                        \"\"\")}})]\r\n                    {{baselineBenchmarkAttributeUsage}}\r\n                    public void BaselineBenchmarkMethod2()\r\n                    {\r\n\r\n                    }\r\n\r\n                    [BenchmarkCategory(\"Category1\")]\r\n                    {{nonBaselineBenchmarkAttributeUsage}}\r\n                    public void NonBaselineBenchmarkMethod1()\r\n                    {\r\n\r\n                    }\r\n\r\n                    [BenchmarkCategory(\"Category1\")]\r\n                    public void DummyMethod()\r\n                    {\r\n\r\n                    }\r\n\r\n                    [Benchmark]\r\n                    public void NonBaselineBenchmarkMethod2()\r\n                    {\r\n\r\n                    }\r\n\r\n                    {{nonBaselineBenchmarkAttributeUsage}}\r\n                    public void NonBaselineBenchmarkMethod3()\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            var benchmarkClassAncestor1Document = /* lang=c#-test */ $$\"\"\"\r\n                public {{abstractModifier}}class BenchmarkClassAncestor1 : BenchmarkClassAncestor2\r\n                {\r\n                }\r\n                \"\"\";\r\n\r\n            var benchmarkClassAncestor2Document = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public {{abstractModifier}}class BenchmarkClassAncestor2\r\n                {\r\n                    {{(useLocalConstants ? $\"private const bool _xTrue = {(useConstantsFromOtherClass ? \"Constants.Value1\" : \"true\")};\" : \"\")}}\r\n\r\n                    [BenchmarkCategory({{string.Format(valuesContainer, \"null, null\")}})]\r\n                    [BenchmarkCategory({{string.Format(valuesContainer, \"\"\"\r\n                                                                        \"test\", null\r\n                                                                        \"\"\")}})]\r\n                    [BenchmarkCategory({{string.Format(valuesContainer, \"\"\"\r\n                                                                        \"test2\"\r\n                                                                        \"\"\")}})]\r\n                    {{baselineBenchmarkAttributeUsage}}\r\n                    public void BaselineBenchmarkMethod3()\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceConstants((\"bool\", \"true\"), (\"bool\", \"false\"));\r\n            AddSource(benchmarkClassAncestor1Document);\r\n            AddSource(benchmarkClassAncestor2Document);\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Class_with_more_than_one_benchmark_method_marked_as_baseline_should_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(ClassAbstractModifiersEnumerableLocal))] string abstractModifier,\r\n            bool useConstantsFromOtherClass,\r\n            bool useLocalConstants,\r\n            bool useDuplicateInSameClass)\r\n        {\r\n            var baselineBenchmarkAttributeUsage = $\"[Benchmark(Baseline = {(useLocalConstants ? \"_xTrue\" : useConstantsFromOtherClass ? \"Constants.Value1\" : \"true\")})]\";\r\n            var baselineBenchmarkAttributeUsageWithLocationMarker = $\"[Benchmark({{{{|#{{0}}:Baseline = {(useLocalConstants ? \"_xTrue\" : useConstantsFromOtherClass ? \"Constants.Value1\" : \"true\")}|}}}})]\";\r\n            var nonBaselineBenchmarkAttributeUsage = $\"[Benchmark(Baseline = {(useLocalConstants ? \"_xFalse\" : useConstantsFromOtherClass ? \"Constants.Value2\" : \"false\")})]\";\r\n\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass : BenchmarkClassAncestor1\r\n                {\r\n                    {{(useLocalConstants ? $\"\"\"\r\n                                            private const bool _xTrue = {(useConstantsFromOtherClass ? \"Constants.Value1\" : \"true\")};\r\n                                            private const bool _xFalse = {(useConstantsFromOtherClass ? \"Constants.Value2\" : \"false\")};\r\n                                            \"\"\" : \"\")}}\r\n\r\n                    {{string.Format(baselineBenchmarkAttributeUsageWithLocationMarker, 0)}}\r\n                    public void BaselineBenchmarkMethod1()\r\n                    {\r\n\r\n                    }\r\n\r\n                    {{(useDuplicateInSameClass ? string.Format(baselineBenchmarkAttributeUsageWithLocationMarker, 1) : \"\")}}\r\n                    public void BaselineBenchmarkMethod2()\r\n                    {\r\n\r\n                    }\r\n\r\n                    [BenchmarkCategory(\"Category1\")]\r\n                    {{nonBaselineBenchmarkAttributeUsage}}\r\n                    public void NonBaselineBenchmarkMethod1()\r\n                    {\r\n\r\n                    }\r\n\r\n                    [BenchmarkCategory(\"Category1\")]\r\n                    public void DummyMethod()\r\n                    {\r\n\r\n                    }\r\n\r\n                    [Benchmark]\r\n                    public void NonBaselineBenchmarkMethod2()\r\n                    {\r\n\r\n                    }\r\n\r\n                    {{nonBaselineBenchmarkAttributeUsage}}\r\n                    public void NonBaselineBenchmarkMethod3()\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            var benchmarkClassAncestor1Document = /* lang=c#-test */ $$\"\"\"\r\n                public {{abstractModifier}}class BenchmarkClassAncestor1 : BenchmarkClassAncestor2\r\n                {\r\n                }\r\n                \"\"\";\r\n\r\n            var benchmarkClassAncestor2Document = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public {{abstractModifier}}class BenchmarkClassAncestor2\r\n                {\r\n                    {{(useLocalConstants ? $\"private const bool _xTrue = {(useConstantsFromOtherClass ? \"Constants.Value1\" : \"true\")};\" : \"\")}}\r\n\r\n                    {{baselineBenchmarkAttributeUsage}}\r\n                    public void BaselineBenchmarkMethod3()\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceConstants((\"bool\", \"true\"), (\"bool\", \"false\"));\r\n            AddSource(benchmarkClassAncestor1Document);\r\n            AddSource(benchmarkClassAncestor2Document);\r\n\r\n            AddExpectedDiagnostic(0);\r\n\r\n            if (useDuplicateInSameClass)\r\n            {\r\n                AddExpectedDiagnostic(1);\r\n            }\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Class_with_more_than_one_benchmark_method_marked_as_baseline_with_empty_category_should_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(ClassAbstractModifiersEnumerableLocal))] string abstractModifier,\r\n            bool useConstantsFromOtherClass,\r\n            bool useLocalConstants,\r\n            [CombinatorialMemberData(nameof(EmptyBenchmarkCategoryAttributeEnumerableLocal))] string emptyBenchmarkCategoryAttribute,\r\n            bool useDuplicateInSameClass)\r\n        {\r\n            var emptyBenchmarkCategoryAttributeUsages = string.Join(\"\\n\", Enumerable.Repeat(emptyBenchmarkCategoryAttribute, 3));\r\n            var baselineBenchmarkAttributeUsage = $\"[Benchmark(Baseline = {(useLocalConstants ? \"_xTrue\" : useConstantsFromOtherClass ? \"Constants.Value1\" : \"true\")})]\";\r\n            var baselineBenchmarkAttributeUsageWithLocationMarker = $\"[Benchmark({{{{|#{{0}}:Baseline = {(useLocalConstants ? \"_xTrue\" : useConstantsFromOtherClass ? \"Constants.Value1\" : \"true\")}|}}}})]\";\r\n            var nonBaselineBenchmarkAttributeUsage = $\"[Benchmark(Baseline = {(useLocalConstants ? \"_xFalse\" : useConstantsFromOtherClass ? \"Constants.Value2\" : \"false\")})]\";\r\n\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass : BenchmarkClassAncestor1\r\n                {\r\n                    {{(useLocalConstants ? $\"\"\"\r\n                                            private const bool _xTrue = {(useConstantsFromOtherClass ? \"Constants.Value1\" : \"true\")};\r\n                                            private const bool _xFalse = {(useConstantsFromOtherClass ? \"Constants.Value2\" : \"false\")};\r\n                                            \"\"\" : \"\")}}\r\n\r\n                    {{emptyBenchmarkCategoryAttributeUsages}}\r\n                    {{string.Format(baselineBenchmarkAttributeUsageWithLocationMarker, 0)}}\r\n                    public void BaselineBenchmarkMethod1()\r\n                    {\r\n\r\n                    }\r\n\r\n                    {{emptyBenchmarkCategoryAttributeUsages}}\r\n                    {{(useDuplicateInSameClass ? string.Format(baselineBenchmarkAttributeUsageWithLocationMarker, 1) : \"\")}}\r\n                    public void BaselineBenchmarkMethod2()\r\n                    {\r\n\r\n                    }\r\n\r\n                    [BenchmarkCategory(\"Category1\")]\r\n                    {{nonBaselineBenchmarkAttributeUsage}}\r\n                    public void NonBaselineBenchmarkMethod1()\r\n                    {\r\n\r\n                    }\r\n\r\n                    [BenchmarkCategory(\"Category1\")]\r\n                    public void DummyMethod()\r\n                    {\r\n\r\n                    }\r\n\r\n                    [Benchmark]\r\n                    public void NonBaselineBenchmarkMethod2()\r\n                    {\r\n\r\n                    }\r\n\r\n                    {{nonBaselineBenchmarkAttributeUsage}}\r\n                    public void NonBaselineBenchmarkMethod3()\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            var benchmarkClassAncestor1Document = /* lang=c#-test */ $$\"\"\"\r\n                public {{abstractModifier}}class BenchmarkClassAncestor1 : BenchmarkClassAncestor2\r\n                {\r\n                }\r\n                \"\"\";\r\n\r\n            var benchmarkClassAncestor2Document = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public {{abstractModifier}}class BenchmarkClassAncestor2\r\n                {\r\n                    {{(useLocalConstants ? $\"private const bool _xTrue = {(useConstantsFromOtherClass ? \"Constants.Value1\" : \"true\")};\" : \"\")}}\r\n\r\n                    {{emptyBenchmarkCategoryAttributeUsages}}\r\n                    {{baselineBenchmarkAttributeUsage}}\r\n                    public void BaselineBenchmarkMethod3()\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceConstants((\"bool\", \"true\"), (\"bool\", \"false\"));\r\n            AddSource(benchmarkClassAncestor1Document);\r\n            AddSource(benchmarkClassAncestor2Document);\r\n\r\n            AddExpectedDiagnostic(0);\r\n\r\n            if (useDuplicateInSameClass)\r\n            {\r\n                AddExpectedDiagnostic(1);\r\n            }\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        public static IEnumerable<string> ClassAbstractModifiersEnumerableLocal\r\n            => ClassAbstractModifiersEnumerable;\r\n\r\n        public static IEnumerable<string> BenchmarkCategoryAttributeValuesContainerEnumerableLocal(bool useParamsValues)\r\n            => BenchmarkCategoryAttributeValuesContainerEnumerable(useParamsValues);\r\n\r\n        public static IEnumerable<string> EmptyBenchmarkCategoryAttributeEnumerableLocal\r\n            => EmptyBenchmarkCategoryAttributeEnumerable();\r\n    }\r\n\r\n    public class OnlyOneMethodCanBeBaselinePerCategory : AnalyzerTestFixture<BenchmarkClassAnalyzer>\r\n    {\r\n        public OnlyOneMethodCanBeBaselinePerCategory() : base(BenchmarkClassAnalyzer.OnlyOneMethodCanBeBaselinePerCategoryRule) { }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Class_with_only_one_benchmark_method_marked_as_baseline_should_not_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(ClassAbstractModifiersEnumerableLocal))] string abstractModifier,\r\n            bool useConstantsFromOtherClass,\r\n            bool useLocalConstants,\r\n            bool useInvalidFalseValue)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass : BenchmarkClassAncestor1\r\n                {\r\n                    {{(useLocalConstants ? $\"\"\"\r\n                                            private const bool _xTrue = {(useConstantsFromOtherClass ? \"Constants.Value1\" : \"true\")};\r\n                                            private const bool _xFalse = {(useConstantsFromOtherClass ? \"Constants.Value2\" : useInvalidFalseValue ? \"dummy\" : \"false\")};\r\n                                            \"\"\" : \"\")}}\r\n\r\n                    [Benchmark(Baseline = {{(useLocalConstants ? \"_xTrue\" : useConstantsFromOtherClass ? \"Constants.Value1\" : \"true\")}})]\r\n                    public void BaselineBenchmarkMethod()\r\n                    {\r\n\r\n                    }\r\n\r\n                    [Benchmark]\r\n                    public void NonBaselineBenchmarkMethod1()\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            var benchmarkClassAncestor1Document = /* lang=c#-test */ $$\"\"\"\r\n                public {{abstractModifier}}class BenchmarkClassAncestor1 : BenchmarkClassAncestor2, System.IEquatable<BenchmarkClassAncestor1>\r\n                {\r\n                }\r\n                \"\"\";\r\n\r\n            var benchmarkClassAncestor2Document = /* lang=c#-test */ $$\"\"\"\r\n                public {{abstractModifier}}class BenchmarkClassAncestor2 : BenchmarkClassAncestor3\r\n                {\r\n                }\r\n                \"\"\";\r\n\r\n            var benchmarkClassAncestor3Document = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public {{abstractModifier}}class BenchmarkClassAncestor3\r\n                {\r\n                    {{(useLocalConstants ? $\"private const bool _xFalse = {(useConstantsFromOtherClass ? \"Constants.Value2\" : useInvalidFalseValue ? \"dummy\" : \"false\")};\" : \"\")}}\r\n\r\n                    [Benchmark(Baseline = {{(useLocalConstants ? \"_xFalse\" : useConstantsFromOtherClass ? \"Constants.Value2\" : useInvalidFalseValue ? \"dummy\" : \"false\")}})]\r\n                    public void NonBaselineBenchmarkMethod2()\r\n                    {\r\n\r\n                    }\r\n\r\n                    public void BenchmarkMethod2()\r\n                    {\r\n\r\n                    }\r\n\r\n                    private void BenchmarkMethod3()\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            AddSource(benchmarkClassAncestor1Document);\r\n            AddSource(benchmarkClassAncestor2Document);\r\n            AddSource(benchmarkClassAncestor3Document);\r\n            ReferenceConstants((\"bool\", \"true\"), (\"bool\", useInvalidFalseValue ? \"dummy\" : \"false\"));\r\n\r\n            DisableCompilerDiagnostics();\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Class_with_only_one_benchmark_method_marked_as_baseline_per_unique_category_should_not_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(ClassAbstractModifiersEnumerableLocal))] string abstractModifier,\r\n            bool useConstantsFromOtherClass,\r\n            bool useLocalConstants,\r\n            bool useInvalidFalseValue)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass : BenchmarkClassAncestor1\r\n                {\r\n                    {{(useLocalConstants ? $\"\"\"\r\n                                            private const bool _xTrue = {(useConstantsFromOtherClass ? \"Constants.Value1\" : \"true\")};\r\n                                            private const bool _xFalse = {(useConstantsFromOtherClass ? \"Constants.Value2\" : useInvalidFalseValue ? \"dummy\" : \"false\")};\r\n                                            \"\"\" : \"\")}}\r\n\r\n                    [Benchmark(Baseline = {{(useLocalConstants ? \"_xTrue\" : useConstantsFromOtherClass ? \"Constants.Value1\" : \"true\")}})]\r\n                    public void BaselineBenchmarkMethod()\r\n                    {\r\n\r\n                    }\r\n\r\n                    [BenchmarkCategory(\"Category1\")]\r\n                    [Benchmark(Baseline = {{(useLocalConstants ? \"_xTrue\" : useConstantsFromOtherClass ? \"Constants.Value1\" : \"true\")}})]\r\n                    public void BaselineBenchmarkMethod()\r\n                    {\r\n\r\n                    }\r\n\r\n                    [BenchmarkCategory(\"Category2\")]\r\n                    [Benchmark(Baseline = {{(useLocalConstants ? \"_xTrue\" : useConstantsFromOtherClass ? \"Constants.Value1\" : \"true\")}})]\r\n                    public void BaselineBenchmarkMethod()\r\n                    {\r\n\r\n                    }\r\n\r\n                    [BenchmarkCategory(\"Category1\")]\r\n                    [Benchmark(Baseline = {{(useLocalConstants ? \"_xFalse\" : useConstantsFromOtherClass ? \"Constants.Value2\" : useInvalidFalseValue ? \"dummy\" : \"false\")}})]\r\n                    public void BaselineBenchmarkMethod()\r\n                    {\r\n\r\n                    }\r\n\r\n                    [BenchmarkCategory(\"Category2\")]\r\n                    [Benchmark]\r\n                    public void BaselineBenchmarkMethod()\r\n                    {\r\n\r\n                    }\r\n\r\n                    [Benchmark]\r\n                    public void NonBaselineBenchmarkMethod1()\r\n                    {\r\n\r\n                    }\r\n\r\n                    [Benchmark(Baseline = {{(useLocalConstants ? \"_xFalse\" : useConstantsFromOtherClass ? \"Constants.Value2\" : useInvalidFalseValue ? \"dummy\" : \"false\")}})]\r\n                    public void NonBaselineBenchmarkMethod2()\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            var benchmarkClassAncestor1Document = /* lang=c#-test */ $$\"\"\"\r\n                public {{abstractModifier}}class BenchmarkClassAncestor1 : BenchmarkClassAncestor2\r\n                {\r\n                }\r\n                \"\"\";\r\n\r\n            var benchmarkClassAncestor2Document = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public {{abstractModifier}}class BenchmarkClassAncestor2\r\n                {\r\n                    [Benchmark(Baseline = {{(useLocalConstants ? \"_xTrue\" : useConstantsFromOtherClass ? \"Constants.Value1\" : \"true\")}})]\r\n                    public void NonBaselineBenchmarkMethod2()\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceConstants((\"bool\", \"true\"), (\"bool\", useInvalidFalseValue ? \"dummy\" : \"false\"));\r\n            AddSource(benchmarkClassAncestor1Document);\r\n            AddSource(benchmarkClassAncestor2Document);\r\n\r\n            DisableCompilerDiagnostics();\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Class_with_no_benchmark_methods_marked_as_baseline_should_not_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(ClassAbstractModifiersEnumerableLocal))] string abstractModifier,\r\n            bool useConstantFromOtherClass,\r\n            bool useLocalConstant,\r\n            bool useInvalidFalseValue)\r\n        {\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass : BenchmarkClassAncestor1\r\n                {\r\n                    {{(useLocalConstant ? $\"private const bool _xFalse = {(useConstantFromOtherClass ? \"Constants.Value\" : useInvalidFalseValue ? \"dummy\" : \"false\")};\" : \"\")}}\r\n\r\n                    [Benchmark]\r\n                    public void NonBaselineBenchmarkMethod1()\r\n                    {\r\n\r\n                    }\r\n\r\n                    [Benchmark]\r\n                    public void NonBaselineBenchmarkMethod2()\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            var benchmarkClassAncestor1Document = /* lang=c#-test */ $$\"\"\"\r\n                public {{abstractModifier}}class BenchmarkClassAncestor1 : BenchmarkClassAncestor2\r\n                {\r\n                }\r\n                \"\"\";\r\n\r\n            var benchmarkClassAncestor2Document = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public {{abstractModifier}}class BenchmarkClassAncestor2\r\n                {\r\n                    [Benchmark(Baseline = {{(useLocalConstant ? \"_xFalse\" : useConstantFromOtherClass ? \"Constants.Value\" : useInvalidFalseValue ? \"dummy\" : \"false\")}})]\r\n                    public void NonBaselineBenchmarkMethod3()\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceConstants(\"bool\", useInvalidFalseValue ? \"dummy\" : \"false\");\r\n            AddSource(benchmarkClassAncestor1Document);\r\n            AddSource(benchmarkClassAncestor2Document);\r\n\r\n            DisableCompilerDiagnostics();\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Class_with_more_than_one_benchmark_method_marked_as_baseline_should_trigger_not_diagnostic(\r\n            [CombinatorialMemberData(nameof(ClassAbstractModifiersEnumerableLocal))] string abstractModifier,\r\n            bool useConstantsFromOtherClass,\r\n            bool useLocalConstants,\r\n            bool useDuplicateInSameClass)\r\n        {\r\n            var baselineBenchmarkAttributeUsage = $\"[Benchmark(Baseline = {(useLocalConstants ? \"_xTrue\" : useConstantsFromOtherClass ? \"Constants.Value1\" : \"true\")})]\";\r\n            var nonBaselineBenchmarkAttributeUsage = $\"[Benchmark(Baseline = {(useLocalConstants ? \"_xFalse\" : useConstantsFromOtherClass ? \"Constants.Value2\" : \"false\")})]\";\r\n\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass : BenchmarkClassAncestor1\r\n                {\r\n                    {{(useLocalConstants ? $\"\"\"\r\n                                            private const bool _xTrue = {(useConstantsFromOtherClass ? \"Constants.Value1\" : \"true\")};\r\n                                            private const bool _xFalse = {(useConstantsFromOtherClass ? \"Constants.Value2\" : \"false\")};\r\n                                            \"\"\" : \"\")}}\r\n\r\n                    {{baselineBenchmarkAttributeUsage}}\r\n                    public void BaselineBenchmarkMethod1()\r\n                    {\r\n\r\n                    }\r\n\r\n                    {{(useDuplicateInSameClass ? baselineBenchmarkAttributeUsage : \"\")}}\r\n                    public void BaselineBenchmarkMethod2()\r\n                    {\r\n\r\n                    }\r\n\r\n                    [BenchmarkCategory(\"Category1\")]\r\n                    {{nonBaselineBenchmarkAttributeUsage}}\r\n                    public void NonBaselineBenchmarkMethod1()\r\n                    {\r\n\r\n                    }\r\n\r\n                    [BenchmarkCategory(\"Category1\")]\r\n                    public void DummyMethod()\r\n                    {\r\n\r\n                    }\r\n\r\n                    [Benchmark]\r\n                    public void NonBaselineBenchmarkMethod2()\r\n                    {\r\n\r\n                    }\r\n\r\n                    {{nonBaselineBenchmarkAttributeUsage}}\r\n                    public void NonBaselineBenchmarkMethod3()\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            var benchmarkClassAncestor1Document = /* lang=c#-test */ $$\"\"\"\r\n                public {{abstractModifier}}class BenchmarkClassAncestor1 : BenchmarkClassAncestor2\r\n                {\r\n                }\r\n                \"\"\";\r\n\r\n            var benchmarkClassAncestor2Document = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public {{abstractModifier}}class BenchmarkClassAncestor2\r\n                {\r\n                    {{(useLocalConstants ? $\"private const bool _xTrue = {(useConstantsFromOtherClass ? \"Constants.Value1\" : \"true\")};\" : \"\")}}\r\n\r\n                    {{baselineBenchmarkAttributeUsage}}\r\n                    public void BaselineBenchmarkMethod3()\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceConstants((\"bool\", \"true\"), (\"bool\", \"false\"));\r\n            AddSource(benchmarkClassAncestor1Document);\r\n            AddSource(benchmarkClassAncestor2Document);\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Class_with_more_than_one_benchmark_method_marked_as_baseline_with_empty_category_should_not_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(ClassAbstractModifiersEnumerableLocal))] string abstractModifier,\r\n            bool useConstantsFromOtherClass,\r\n            bool useLocalConstants,\r\n            [CombinatorialMemberData(nameof(EmptyBenchmarkCategoryAttributeEnumerableLocal))] string emptyBenchmarkCategoryAttribute,\r\n            bool useDuplicateInSameClass)\r\n        {\r\n            var emptyBenchmarkCategoryAttributeUsages = string.Join(\"\\n\", Enumerable.Repeat(emptyBenchmarkCategoryAttribute, 3));\r\n            var baselineBenchmarkAttributeUsage = $\"[Benchmark(Baseline = {(useLocalConstants ? \"_xTrue\" : useConstantsFromOtherClass ? \"Constants.Value1\" : \"true\")})]\";\r\n            var nonBaselineBenchmarkAttributeUsage = $\"[Benchmark(Baseline = {(useLocalConstants ? \"_xFalse\" : useConstantsFromOtherClass ? \"Constants.Value2\" : \"false\")})]\";\r\n\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass : BenchmarkClassAncestor1\r\n                {\r\n                    {{(useLocalConstants ? $\"\"\"\r\n                                            private const bool _xTrue = {(useConstantsFromOtherClass ? \"Constants.Value1\" : \"true\")};\r\n                                            private const bool _xFalse = {(useConstantsFromOtherClass ? \"Constants.Value2\" : \"false\")};\r\n                                            \"\"\" : \"\")}}\r\n\r\n                    {{emptyBenchmarkCategoryAttributeUsages}}\r\n                    {{baselineBenchmarkAttributeUsage}}\r\n                    public void BaselineBenchmarkMethod1()\r\n                    {\r\n\r\n                    }\r\n\r\n                    {{emptyBenchmarkCategoryAttributeUsages}}\r\n                    {{(useDuplicateInSameClass ? baselineBenchmarkAttributeUsage : \"\")}}\r\n                    public void BaselineBenchmarkMethod2()\r\n                    {\r\n\r\n                    }\r\n\r\n                    [BenchmarkCategory(\"Category1\")]\r\n                    {{nonBaselineBenchmarkAttributeUsage}}\r\n                    public void NonBaselineBenchmarkMethod1()\r\n                    {\r\n\r\n                    }\r\n\r\n                    [BenchmarkCategory(\"Category1\")]\r\n                    public void DummyMethod()\r\n                    {\r\n\r\n                    }\r\n\r\n                    [Benchmark]\r\n                    public void NonBaselineBenchmarkMethod2()\r\n                    {\r\n\r\n                    }\r\n\r\n                    {{nonBaselineBenchmarkAttributeUsage}}\r\n                    public void NonBaselineBenchmarkMethod3()\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            var benchmarkClassAncestor1Document = /* lang=c#-test */ $$\"\"\"\r\n                public {{abstractModifier}}class BenchmarkClassAncestor1 : BenchmarkClassAncestor2\r\n                {\r\n                }\r\n                \"\"\";\r\n\r\n            var benchmarkClassAncestor2Document = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public {{abstractModifier}}class BenchmarkClassAncestor2\r\n                {\r\n                    {{(useLocalConstants ? $\"private const bool _xTrue = {(useConstantsFromOtherClass ? \"Constants.Value1\" : \"true\")};\" : \"\")}}\r\n\r\n                    {{emptyBenchmarkCategoryAttributeUsages}}\r\n                    {{baselineBenchmarkAttributeUsage}}\r\n                    public void BaselineBenchmarkMethod3()\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceConstants((\"bool\", \"true\"), (\"bool\", \"false\"));\r\n            AddSource(benchmarkClassAncestor1Document);\r\n            AddSource(benchmarkClassAncestor2Document);\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Class_with_more_than_one_benchmark_method_marked_as_baseline_per_unique_category_with_unknown_values_should_not_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(ClassAbstractModifiersEnumerableLocal))] string abstractModifier,\r\n            bool useConstantsFromOtherClass,\r\n            bool useLocalConstants,\r\n            [CombinatorialMemberData(nameof(BenchmarkCategoryAttributeValuesContainerEnumerableLocal), true)] string valuesContainer,\r\n            [CombinatorialValues(\"dummy_literal\", \"1\", \"true\")] string invalidCategoryStringValue,\r\n            bool useDuplicateInSameClass)\r\n        {\r\n            var baselineBenchmarkAttributeUsage = $\"[Benchmark(Baseline = {(useLocalConstants ? \"_xTrue\" : useConstantsFromOtherClass ? \"Constants.Value1\" : \"true\")})]\";\r\n            var nonBaselineBenchmarkAttributeUsage = $\"[Benchmark(Baseline = {(useLocalConstants ? \"_xFalse\" : useConstantsFromOtherClass ? \"Constants.Value2\" : \"false\")})]\";\r\n\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass : BenchmarkClassAncestor1\r\n                {\r\n                    {{(useLocalConstants ? $\"\"\"\r\n                                            private const bool _xTrue = {(useConstantsFromOtherClass ? \"Constants.Value1\" : \"true\")};\r\n                                            private const bool _xFalse = {(useConstantsFromOtherClass ? \"Constants.Value2\" : \"false\")};\r\n                                            \"\"\" : \"\")}}\r\n\r\n                    [BenchmarkCategory({{string.Format(valuesContainer, $\"\"\"\r\n                                                                            null, {invalidCategoryStringValue}, null, \"TEST\", \"test2\"\r\n                                                                            \"\"\")}})]\r\n                    {{baselineBenchmarkAttributeUsage}}\r\n                    public void BaselineBenchmarkMethod1()\r\n                    {\r\n\r\n                    }\r\n\r\n                    [BenchmarkCategory({{string.Format(valuesContainer, \"null, null\")}})]\r\n                    [BenchmarkCategory({{string.Format(valuesContainer, \"\"\"\r\n                                                                        \"test\", null\r\n                                                                        \"\"\")}})]\r\n                    [BenchmarkCategory({{string.Format(valuesContainer, \"\"\"\r\n                                                                        \"test2\"\r\n                                                                        \"\"\")}})]\r\n                    {{(useDuplicateInSameClass ? baselineBenchmarkAttributeUsage : \"\")}}\r\n                    public void BaselineBenchmarkMethod2()\r\n                    {\r\n\r\n                    }\r\n\r\n                    [BenchmarkCategory(\"Category1\")]\r\n                    {{nonBaselineBenchmarkAttributeUsage}}\r\n                    public void NonBaselineBenchmarkMethod1()\r\n                    {\r\n\r\n                    }\r\n\r\n                    [BenchmarkCategory(\"Category1\")]\r\n                    public void DummyMethod()\r\n                    {\r\n\r\n                    }\r\n\r\n                    [Benchmark]\r\n                    public void NonBaselineBenchmarkMethod2()\r\n                    {\r\n\r\n                    }\r\n\r\n                    {{nonBaselineBenchmarkAttributeUsage}}\r\n                    public void NonBaselineBenchmarkMethod3()\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            var benchmarkClassAncestor1Document = /* lang=c#-test */ $$\"\"\"\r\n                public {{abstractModifier}}class BenchmarkClassAncestor1 : BenchmarkClassAncestor2\r\n                {\r\n                }\r\n                \"\"\";\r\n\r\n            var benchmarkClassAncestor2Document = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public {{abstractModifier}}class BenchmarkClassAncestor2\r\n                {\r\n                    {{(useLocalConstants ? $\"private const bool _xTrue = {(useConstantsFromOtherClass ? \"Constants.Value1\" : \"true\")};\" : \"\")}}\r\n\r\n                    [BenchmarkCategory({{string.Format(valuesContainer, \"null, null\")}})]\r\n                    [BenchmarkCategory({{string.Format(valuesContainer, $\"{invalidCategoryStringValue}, null\")}})]\r\n                    [BenchmarkCategory({{string.Format(valuesContainer, \"\"\"\r\n                                                                        \"test2\"\r\n                                                                        \"\"\")}})]\r\n                    {{baselineBenchmarkAttributeUsage}}\r\n                    public void BaselineBenchmarkMethod3()\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceConstants((\"bool\", \"true\"), (\"bool\", \"false\"));\r\n            AddSource(benchmarkClassAncestor1Document);\r\n            AddSource(benchmarkClassAncestor2Document);\r\n            DisableCompilerDiagnostics();\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        [Theory, CombinatorialData]\r\n        public async Task Class_with_more_than_one_benchmark_method_marked_as_baseline_per_unique_category_should_trigger_diagnostic(\r\n            [CombinatorialMemberData(nameof(ClassAbstractModifiersEnumerableLocal))] string abstractModifier,\r\n            bool useConstantsFromOtherClass,\r\n            bool useLocalConstants,\r\n            [CombinatorialMemberData(nameof(BenchmarkCategoryAttributeValuesContainerEnumerableLocal), true)] string valuesContainer,\r\n            bool useDuplicateInSameClass)\r\n        {\r\n            var baselineBenchmarkAttributeUsage = $\"[Benchmark(Baseline = {(useLocalConstants ? \"_xTrue\" : useConstantsFromOtherClass ? \"Constants.Value1\" : \"true\")})]\";\r\n            var baselineBenchmarkAttributeUsageWithLocationMarker = $\"[Benchmark({{{{|#{{0}}:Baseline = {(useLocalConstants ? \"_xTrue\" : useConstantsFromOtherClass ? \"Constants.Value1\" : \"true\")}|}}}})]\";\r\n            var nonBaselineBenchmarkAttributeUsage = $\"[Benchmark(Baseline = {(useLocalConstants ? \"_xFalse\" : useConstantsFromOtherClass ? \"Constants.Value2\" : \"false\")})]\";\r\n\r\n            var testCode = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public class BenchmarkClass : BenchmarkClassAncestor1\r\n                {\r\n                    {{(useLocalConstants ? $\"\"\"\r\n                                            private const bool _xTrue = {(useConstantsFromOtherClass ? \"Constants.Value1\" : \"true\")};\r\n                                            private const bool _xFalse = {(useConstantsFromOtherClass ? \"Constants.Value2\" : \"false\")};\r\n                                            \"\"\" : \"\")}}\r\n\r\n                    [BenchmarkCategory({{string.Format(valuesContainer, \"\"\"\r\n                                                                        null, \"test\", null, \"TEST\", \"test2\"\r\n                                                                        \"\"\")}})]\r\n                    {{string.Format(baselineBenchmarkAttributeUsageWithLocationMarker, 0)}}\r\n                    public void BaselineBenchmarkMethod1()\r\n                    {\r\n\r\n                    }\r\n\r\n                    [BenchmarkCategory({{string.Format(valuesContainer, \"null, null\")}})]\r\n                    [BenchmarkCategory({{string.Format(valuesContainer, \"\"\"\r\n                                                                        \"test\", null\r\n                                                                        \"\"\")}})]\r\n                    [BenchmarkCategory({{string.Format(valuesContainer, \"\"\"\r\n                                                                        \"test2\"\r\n                                                                        \"\"\")}})]\r\n                    {{(useDuplicateInSameClass ? string.Format(baselineBenchmarkAttributeUsageWithLocationMarker, 1) : \"\")}}\r\n                    public void BaselineBenchmarkMethod2()\r\n                    {\r\n\r\n                    }\r\n\r\n                    [BenchmarkCategory(\"Category1\")]\r\n                    {{nonBaselineBenchmarkAttributeUsage}}\r\n                    public void NonBaselineBenchmarkMethod1()\r\n                    {\r\n\r\n                    }\r\n\r\n                    [BenchmarkCategory(\"Category1\")]\r\n                    public void DummyMethod()\r\n                    {\r\n\r\n                    }\r\n\r\n                    [Benchmark]\r\n                    public void NonBaselineBenchmarkMethod2()\r\n                    {\r\n\r\n                    }\r\n\r\n                    {{nonBaselineBenchmarkAttributeUsage}}\r\n                    public void NonBaselineBenchmarkMethod3()\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            var benchmarkClassAncestor1Document = /* lang=c#-test */ $$\"\"\"\r\n                public {{abstractModifier}}class BenchmarkClassAncestor1 : BenchmarkClassAncestor2\r\n                {\r\n                }\r\n                \"\"\";\r\n\r\n            var benchmarkClassAncestor2Document = /* lang=c#-test */ $$\"\"\"\r\n                using BenchmarkDotNet.Attributes;\r\n\r\n                public {{abstractModifier}}class BenchmarkClassAncestor2\r\n                {\r\n                    {{(useLocalConstants ? $\"private const bool _xTrue = {(useConstantsFromOtherClass ? \"Constants.Value1\" : \"true\")};\" : \"\")}}\r\n\r\n                    [BenchmarkCategory({{string.Format(valuesContainer, \"null, null\")}})]\r\n                    [BenchmarkCategory({{string.Format(valuesContainer, \"\"\"\r\n                                                                        \"test\", null\r\n                                                                        \"\"\")}})]\r\n                    [BenchmarkCategory({{string.Format(valuesContainer, \"\"\"\r\n                                                                        \"test2\"\r\n                                                                        \"\"\")}})]\r\n                    {{baselineBenchmarkAttributeUsage}}\r\n                    public void BaselineBenchmarkMethod3()\r\n                    {\r\n\r\n                    }\r\n                }\r\n                \"\"\";\r\n\r\n            TestCode = testCode;\r\n            ReferenceConstants((\"bool\", \"true\"), (\"bool\", \"false\"));\r\n            AddSource(benchmarkClassAncestor1Document);\r\n            AddSource(benchmarkClassAncestor2Document);\r\n\r\n            AddExpectedDiagnostic(0);\r\n\r\n            if (useDuplicateInSameClass)\r\n            {\r\n                AddExpectedDiagnostic(1);\r\n            }\r\n\r\n            await RunAsync();\r\n        }\r\n\r\n        public static IEnumerable<string> ClassAbstractModifiersEnumerableLocal\r\n            => ClassAbstractModifiersEnumerable;\r\n\r\n        public static IEnumerable<string> EmptyBenchmarkCategoryAttributeEnumerableLocal\r\n            => EmptyBenchmarkCategoryAttributeEnumerable();\r\n\r\n        public static IEnumerable<string> BenchmarkCategoryAttributeValuesContainerEnumerableLocal(bool useParamsValues)\r\n            => BenchmarkCategoryAttributeValuesContainerEnumerable(useParamsValues);\r\n    }\r\n\r\n    public static TheoryData<int> TypeParametersListLengthTheoryData\r\n        => [.. TypeParametersListLengthEnumerable];\r\n\r\n    public static IEnumerable<int> TypeParametersListLengthEnumerable\r\n        => Enumerable.Range(1, TypeParametersTheoryData.Count);\r\n\r\n    private static ReadOnlyCollection<string> TypeParametersTheoryData\r\n        => Enumerable.Range(1, 3)\r\n        .Select(i => $\"TParameter{i}\")\r\n        .ToList()\r\n        .AsReadOnly();\r\n\r\n    private static IReadOnlyCollection<string> GenericTypeArgumentsTheoryData\r\n        => [\"int\", \"string\", \"bool\"];\r\n\r\n    public static IEnumerable<string> ClassAbstractModifiersEnumerable\r\n        => [\"\", \"abstract \"];\r\n\r\n    public static IEnumerable<string> BenchmarkAttributeUsagesEnumerable\r\n        => [\"\", \"[Benchmark] \"];\r\n\r\n    public static IEnumerable<string> EmptyBenchmarkCategoryAttributeArgumentEnumerable()\r\n    {\r\n        yield return \"\";\r\n        yield return \"()\";\r\n\r\n        string[] nameColonUsages =\r\n        [\r\n            \"\",\r\n            \"categories: \"\r\n        ];\r\n\r\n        string[] attributeUsagesBase =\r\n        [\r\n            \"({0}new string[] {{ }})\",\r\n            \"({0}new string[0])\",\r\n            \"({0}[ ])\"\r\n        ];\r\n\r\n        foreach (var attributeUsageBase in attributeUsagesBase)\r\n        {\r\n            foreach (var nameColonUsage in nameColonUsages)\r\n            {\r\n                yield return string.Format(attributeUsageBase, nameColonUsage);\r\n            }\r\n        }\r\n    }\r\n\r\n    public static IEnumerable<string> EmptyBenchmarkCategoryAttributeEnumerable()\r\n    {\r\n        yield return \"[BenchmarkCategory]\";\r\n        yield return \"[BenchmarkCategory()]\";\r\n\r\n        string[] nameColonUsages =\r\n        [\r\n            \"\",\r\n            \"categories: \"\r\n        ];\r\n\r\n        string[] attributeUsagesBase =\r\n        [\r\n            \"({0}new string[] {{ }})\",\r\n            \"({0}new string[0])\",\r\n            \"({0}[ ])\"\r\n        ];\r\n\r\n        foreach (var attributeUsageBase in attributeUsagesBase)\r\n        {\r\n            foreach (var nameColonUsage in nameColonUsages)\r\n            {\r\n                yield return $\"[BenchmarkCategory{string.Format(attributeUsageBase, nameColonUsage)}]\";\r\n            }\r\n        }\r\n    }\r\n\r\n    public static IEnumerable<string> BenchmarkCategoryAttributeValuesContainerEnumerable(bool useParamsValues)\r\n    {\r\n        return GenerateData(useParamsValues).Distinct();\r\n\r\n        static IEnumerable<string> GenerateData(bool useParamsValues)\r\n        {\r\n            string[] nameColonUsages =\r\n            [\r\n                \"\",\r\n                \"categories: \"\r\n            ];\r\n\r\n            List<string> attributeUsagesBase = useParamsValues ? [\"{{0}}\"] : [];\r\n\r\n            attributeUsagesBase.AddRange([\r\n                                            \"{0}new string[] {{{{ {{0}} }}}}\",\r\n                                            \"{0}[ {{0}} ]\"\r\n                                         ]);\r\n\r\n            foreach (var attributeUsageBase in attributeUsagesBase)\r\n            {\r\n                foreach (var nameColonUsage in nameColonUsages)\r\n                {\r\n                    yield return string.Format(attributeUsageBase, nameColonUsage);\r\n                }\r\n            }\r\n        }\r\n    }\r\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Analyzers.Tests/BenchmarkDotNet.Analyzers.Tests.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\r\n  <Import Project=\"..\\..\\build\\common.props\" />\r\n  <PropertyGroup>\r\n    <AssemblyName>BenchmarkDotNet.Analyzers.Tests</AssemblyName>\r\n    <TargetFrameworks>net462;net8.0;net10.0</TargetFrameworks>\r\n    <PreserveCompilationContext>true</PreserveCompilationContext>\r\n    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>\r\n    <GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>\r\n    <SuppressTfmSupportBuildErrors>true</SuppressTfmSupportBuildErrors>\r\n    <NoWarn>$(NoWarn);CS1591</NoWarn>\r\n  </PropertyGroup>\r\n  <ItemGroup>\r\n    <None Remove=\"BenchmarkDotNet.Analyzers.Tests.csproj.DotSettings\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <PackageReference Include=\"Microsoft.CodeAnalysis.CSharp.Analyzer.Testing\" Version=\"1.1.3\" />\r\n    <PackageReference Include=\"Microsoft.CodeAnalysis.CSharp.Workspaces\" Version=\"5.0.0\" />\r\n    <PackageReference Include=\"Microsoft.NET.Test.Sdk\" Version=\"18.0.1\" />\r\n    <PackageReference Include=\"Newtonsoft.Json\" Version=\"13.0.4\" />\r\n    <PackageReference Include=\"xunit\" Version=\"2.9.3\" />\r\n    <PackageReference Include=\"Xunit.Combinatorial\" Version=\"[1.6.24]\" />\r\n    <PackageReference Include=\"xunit.runner.visualstudio\" Version=\"[2.8.2]\">\r\n      <PrivateAssets>all</PrivateAssets>\r\n      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\r\n    </PackageReference>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ProjectReference Include=\"..\\..\\src\\BenchmarkDotNet.Analyzers\\BenchmarkDotNet.Analyzers.csproj\" />\r\n    <ProjectReference Include=\"..\\..\\src\\BenchmarkDotNet\\BenchmarkDotNet.csproj\" />\r\n  </ItemGroup>\r\n  <Import Project=\"..\\..\\build\\common.targets\" />\r\n</Project>"
  },
  {
    "path": "tests/BenchmarkDotNet.Analyzers.Tests/BenchmarkDotNet.Analyzers.Tests.csproj.DotSettings",
    "content": "﻿<wpf:ResourceDictionary xml:space=\"preserve\" xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\" xmlns:s=\"clr-namespace:System;assembly=mscorlib\" xmlns:ss=\"urn:shemas-jetbrains-com:settings-storage-xaml\" xmlns:wpf=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">\n\t<s:Boolean x:Key=\"/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=fixtures_005Cextensions/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=fixtures_005Cgenerators/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=fixtures_005Cserializable/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=fixtures_005Ctestframework/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=fixtures_005Ctheorydata/@EntryIndexedValue\">True</s:Boolean></wpf:ResourceDictionary>"
  },
  {
    "path": "tests/BenchmarkDotNet.Analyzers.Tests/Fixtures/AnalyzerTestFixture.cs",
    "content": "﻿using Microsoft.CodeAnalysis;\r\nusing Microsoft.CodeAnalysis.CSharp;\r\nusing Microsoft.CodeAnalysis.CSharp.Testing;\r\nusing Microsoft.CodeAnalysis.Diagnostics;\r\nusing Microsoft.CodeAnalysis.Testing;\r\nusing System;\r\nusing System.Collections.Generic;\r\nusing System.Linq;\r\nusing System.Threading;\r\nusing System.Threading.Tasks;\r\nusing Xunit;\r\n\r\nnamespace BenchmarkDotNet.Analyzers.Tests.Fixtures;\r\n\r\npublic abstract class AnalyzerTestFixture<TAnalyzer>\r\n    where TAnalyzer : DiagnosticAnalyzer, new()\r\n{\r\n    private readonly CSharpAnalyzerTest<TAnalyzer, DefaultVerifier> _analyzerTest;\r\n    private readonly DiagnosticDescriptor? _ruleUnderTest;\r\n\r\n    private AnalyzerTestFixture(bool assertUniqueSupportedDiagnostics)\r\n    {\r\n        _analyzerTest = new InternalAnalyzerTest\r\n        {\r\n#if NET10_0_OR_GREATER\r\n            ReferenceAssemblies = ReferenceAssemblies.Net.Net100,\r\n#elif NET8_0_OR_GREATER\r\n            ReferenceAssemblies = ReferenceAssemblies.Net.Net80,\r\n#elif NET6_0_OR_GREATER\r\n            ReferenceAssemblies = ReferenceAssemblies.Net.Net60,\r\n#else\r\n            ReferenceAssemblies = ReferenceAssemblies.NetStandard.NetStandard20,\r\n#endif\r\n            TestState =\r\n            {\r\n                AdditionalReferences =\r\n                {\r\n                    \"BenchmarkDotNet.dll\",\r\n                    \"BenchmarkDotNet.Annotations.dll\",\r\n#if !NET6_0_OR_GREATER\r\n                    \"System.Memory.dll\"\r\n#endif\r\n                }\r\n            }\r\n        };\r\n\r\n        if (assertUniqueSupportedDiagnostics)\r\n        {\r\n            AssertUniqueSupportedDiagnostics();\r\n        }\r\n    }\r\n\r\n    protected AnalyzerTestFixture() : this(true) { }\r\n\r\n    protected AnalyzerTestFixture(DiagnosticDescriptor diagnosticDescriptor) : this(false)\r\n    {\r\n        var analyzer = AssertUniqueSupportedDiagnostics();\r\n\r\n        // ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract\r\n        if (diagnosticDescriptor == null)\r\n        {\r\n            Assert.Fail(\"Diagnostic under test cannot be null when using this constructor\");\r\n        }\r\n\r\n        AssertDiagnosticUnderTestIsSupportedByAnalyzer();\r\n        DisableAllSupportedDiagnosticsExceptDiagnosticUnderTest();\r\n\r\n        _ruleUnderTest = diagnosticDescriptor;\r\n\r\n        void AssertDiagnosticUnderTestIsSupportedByAnalyzer()\r\n        {\r\n            if (!analyzer.SupportedDiagnostics.Any(dd => dd.Id == diagnosticDescriptor.Id))\r\n            {\r\n                Assert.Fail($\"Diagnostic descriptor with ID {diagnosticDescriptor.Id} is not supported by the analyzer {typeof(TAnalyzer).Name}\");\r\n            }\r\n        }\r\n\r\n        void DisableAllSupportedDiagnosticsExceptDiagnosticUnderTest()\r\n        {\r\n            _analyzerTest.DisabledDiagnostics.Clear();\r\n            _analyzerTest.DisabledDiagnostics.AddRange(\r\n                analyzer.SupportedDiagnostics\r\n                    .Select(dd => dd.Id)\r\n                    .Except([diagnosticDescriptor.Id])\r\n            );\r\n        }\r\n    }\r\n\r\n    private static TAnalyzer AssertUniqueSupportedDiagnostics()\r\n    {\r\n        var allSupportedDiagnostics = new Dictionary<string, int>();\r\n\r\n        var analyzer = new TAnalyzer();\r\n        foreach (var supportedDiagnostic in analyzer.SupportedDiagnostics)\r\n        {\r\n            if (allSupportedDiagnostics.TryGetValue(supportedDiagnostic.Id, out int value))\r\n            {\r\n                allSupportedDiagnostics[supportedDiagnostic.Id] = ++value;\r\n            }\r\n            else\r\n            {\r\n                allSupportedDiagnostics[supportedDiagnostic.Id] = 1;\r\n            }\r\n        }\r\n\r\n        var duplicateSupportedDiagnostics = allSupportedDiagnostics\r\n            .Where(kvp => kvp.Value > 1)\r\n            .OrderBy(kvp => kvp.Key)\r\n            .ToArray();\r\n\r\n        if (duplicateSupportedDiagnostics.Length > 0)\r\n        {\r\n            Assert.Fail($\"The analyzer {typeof(TAnalyzer).FullName} contains duplicate supported diagnostics:{Environment.NewLine}{Environment.NewLine}{string.Join(\", \", duplicateSupportedDiagnostics.Select(kvp => $\"❌ {kvp.Key} (x{kvp.Value})\"))}{Environment.NewLine}\");\r\n        }\r\n\r\n        return analyzer;\r\n    }\r\n\r\n    protected string TestCode\r\n    {\r\n        set => _analyzerTest.TestCode = value;\r\n    }\r\n\r\n    protected void AddSource(string filename, string content)\r\n        => _analyzerTest.TestState.Sources.Add((filename, content));\r\n\r\n    protected void AddSource(string content)\r\n        => _analyzerTest.TestState.Sources.Add(content);\r\n\r\n    protected void AddDefaultExpectedDiagnostic()\r\n        => AddExpectedDiagnostic();\r\n\r\n    protected void AddDefaultExpectedDiagnostic(params object[] arguments)\r\n        => AddExpectedDiagnostic(arguments);\r\n\r\n    protected void AddDefaultExpectedDiagnostic(DiagnosticSeverity effectiveDiagnosticSeverity)\r\n        => AddExpectedDiagnostic(effectiveDiagnosticSeverity: effectiveDiagnosticSeverity);\r\n\r\n    protected void AddDefaultExpectedDiagnostic(DiagnosticSeverity effectiveDiagnosticSeverity, params object[] arguments)\r\n        => AddExpectedDiagnostic(arguments, effectiveDiagnosticSeverity: effectiveDiagnosticSeverity);\r\n\r\n    protected void AddExpectedDiagnostic(int markupKey)\r\n        => AddExpectedDiagnostic(null, markupKey);\r\n\r\n    protected void AddExpectedDiagnostic(int markupKey, DiagnosticSeverity effectiveDiagnosticSeverity)\r\n        => AddExpectedDiagnostic(null, markupKey, effectiveDiagnosticSeverity);\r\n\r\n    protected void AddExpectedDiagnostic(int markupKey, params object[] arguments)\r\n        => AddExpectedDiagnostic(arguments, markupKey);\r\n\r\n    protected void AddExpectedDiagnostic(int markupKey, DiagnosticSeverity effectiveDiagnosticSeverity, params object[] arguments)\r\n        => AddExpectedDiagnostic(arguments, markupKey, effectiveDiagnosticSeverity);\r\n\r\n    private void AddExpectedDiagnostic(object[]? arguments = null, int markupKey = 0, DiagnosticSeverity? effectiveDiagnosticSeverity = null)\r\n    {\r\n        if (_ruleUnderTest == null)\r\n        {\r\n            throw new InvalidOperationException(\"Failed to add expected diagnostic: no diagnostic rule specified for this fixture\");\r\n        }\r\n\r\n        var diagnosticResult = new DiagnosticResult(_ruleUnderTest)\r\n            .WithLocation(markupKey)\r\n            .WithMessageFormat(_ruleUnderTest.MessageFormat);\r\n\r\n        if (arguments != null)\r\n        {\r\n            diagnosticResult = diagnosticResult.WithArguments(arguments);\r\n        }\r\n\r\n        if (effectiveDiagnosticSeverity.HasValue)\r\n        {\r\n            diagnosticResult = diagnosticResult.WithSeverity(effectiveDiagnosticSeverity.Value);\r\n        }\r\n\r\n        _analyzerTest.ExpectedDiagnostics.Add(diagnosticResult);\r\n    }\r\n\r\n    protected void DisableCompilerDiagnostics()\r\n        => _analyzerTest.CompilerDiagnostics = CompilerDiagnostics.None;\r\n\r\n    protected Task RunAsync()\r\n        => _analyzerTest.RunAsync(CancellationToken.None);\r\n\r\n    protected void ReferenceDummyAttribute()\r\n        => _analyzerTest.TestState.Sources.Add(\"\"\"\r\n            using System;\r\n\r\n            public class DummyAttribute : Attribute\r\n            {\r\n\r\n            }\r\n            \"\"\"\r\n        );\r\n\r\n    protected void ReferenceDummyEnum()\r\n        => _analyzerTest.TestState.Sources.Add(\"\"\"\r\n            public enum DummyEnum\r\n            {\r\n                Value1,\r\n                Value2,\r\n                Value3\r\n            }\r\n            \"\"\"\r\n        );\r\n\r\n    protected void ReferenceDummyEnumInDifferentNamespace()\r\n        => _analyzerTest.TestState.Sources.Add(\"\"\"\r\n            namespace DifferentNamespace;\r\n            \r\n            public enum DummyEnumInDifferentNamespace\r\n            {\r\n                Value1,\r\n                Value2,\r\n                Value3\r\n            }\r\n            \"\"\"\r\n        );\r\n\r\n    protected void ReferenceDummyEnumWithFlagsAttribute()\r\n        => _analyzerTest.TestState.Sources.Add(\"\"\"\r\n            using System;\r\n\r\n            [Flags]\r\n            public enum DummyEnumWithFlagsAttribute\r\n            {\r\n                Value1,\r\n                Value2,\r\n                Value3\r\n            }\r\n            \"\"\"\r\n        );\r\n\r\n    protected void ReferenceConstants(string type, string value)\r\n        => _analyzerTest.TestState.Sources.Add($$\"\"\"\r\n            using System;\r\n\r\n            public static class Constants\r\n            {\r\n                public const {{type}} Value = {{value}};\r\n            }\r\n            \"\"\"\r\n        );\r\n\r\n    protected void ReferenceConstants(params (string Type, string Value)[] constants)\r\n        => _analyzerTest.TestState.Sources.Add($$\"\"\"\r\n            using System;\r\n\r\n            public static class Constants\r\n            {\r\n                {{string.Join(\"\\n   \", constants.Select((c, i) => $\"public const {c.Type} Value{i + 1} = {c.Value};\"))}}\r\n            }\r\n            \"\"\"\r\n        );\r\n\r\n    protected void SetParseOptions(LanguageVersion languageVersion, bool interceptorsNamespaces = false)\r\n    {\r\n        var parseOptions = new CSharpParseOptions(languageVersion);\r\n\r\n        if (interceptorsNamespaces)\r\n        {\r\n            parseOptions = parseOptions.WithFeatures([ new KeyValuePair<string, string>(AnalyzerHelper.InterceptorsNamespaces, \"\") ]);\r\n        }\r\n\r\n        _analyzerTest.SolutionTransforms.Add((solution, projectId) => solution.WithProjectParseOptions(projectId, parseOptions));\r\n    }\r\n\r\n    private sealed class InternalAnalyzerTest : CSharpAnalyzerTest<TAnalyzer, DefaultVerifier>\r\n    {\r\n        protected override string DefaultTestProjectName => \"BenchmarksAssemblyUnderAnalysis\";\r\n    }\r\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Analyzers.Tests/Fixtures/Extensions/TheoryDataExtensions.cs",
    "content": "﻿using System.Collections.Generic;\r\nusing System.Collections.ObjectModel;\r\nusing System.Linq;\r\nusing Xunit;\r\n\r\nnamespace BenchmarkDotNet.Analyzers.Tests.Fixtures;\r\n\r\npublic static class TheoryDataExtensions\r\n{\r\n    public static ReadOnlyCollection<T> AsReadOnly<T>(this TheoryData<T> theoryData)\r\n        => (theoryData as IEnumerable<T>).ToList().AsReadOnly();\r\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Analyzers.Tests/Fixtures/Generators/CombinationsGenerator.cs",
    "content": "﻿using System;\r\nusing System.Collections;\r\nusing System.Collections.Generic;\r\nusing System.Linq;\r\n\r\nnamespace BenchmarkDotNet.Analyzers.Tests.Fixtures;\r\n\r\npublic static class CombinationsGenerator\r\n{\r\n    public static IEnumerable<int[]> GenerateCombinationsCounts(int length, int maxValue)\r\n    {\r\n        if (length <= 0)\r\n        {\r\n            yield break;\r\n        }\r\n\r\n        var baseN = maxValue + 1;\r\n        var total = 1;\r\n\r\n        for (var i = 0; i < length; i++)\r\n        {\r\n            total *= baseN;\r\n        }\r\n\r\n        for (var i = 0; i < total; i++)\r\n        {\r\n            // ReSharper disable once StackAllocInsideLoop\r\n            Span<int> currentCombination = stackalloc int[length];\r\n\r\n            var temp = i;\r\n            for (var j = length - 1; j >= 0; j--)\r\n            {\r\n                currentCombination[j] = temp % baseN;\r\n                temp /= baseN;\r\n            }\r\n\r\n            // Copy from Span (stack) to heap-allocated array\r\n            var result = new int[length];\r\n            currentCombination.CopyTo(result);\r\n\r\n            yield return result;\r\n        }\r\n    }\r\n\r\n    public static IEnumerable<object[]> CombineArguments(params IEnumerable[] argumentSets)\r\n    {\r\n        if (argumentSets.Length == 0)\r\n        {\r\n            yield break;\r\n        }\r\n\r\n        IEnumerable<object[]> combinations = [[]];\r\n\r\n        foreach (var argumentValues in argumentSets)\r\n        {\r\n            combinations = combinations\r\n                .SelectMany(_ => argumentValues.Cast<object>(), (c, v) => c.Concat([v])\r\n                .ToArray());\r\n        }\r\n\r\n        foreach (var combination in combinations)\r\n        {\r\n            yield return combination;\r\n        }\r\n    }\r\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Analyzers.Tests/Fixtures/Serializable/ValueTupleDouble.cs",
    "content": "﻿using Xunit.Abstractions;\r\n\r\nnamespace BenchmarkDotNet.Analyzers.Tests.Fixtures;\r\n\r\npublic class ValueTupleDouble<T1, T2> : IXunitSerializable\r\n{\r\n    public T1? Value1 { get; set; }\r\n\r\n    public T2? Value2 { get; set; }\r\n\r\n    public void Deserialize(IXunitSerializationInfo info)\r\n    {\r\n        Value1 = info.GetValue<T1>(nameof(Value1));\r\n        Value2 = info.GetValue<T2>(nameof(Value2));\r\n    }\r\n\r\n    public void Serialize(IXunitSerializationInfo info)\r\n    {\r\n        info.AddValue(nameof(Value1), Value1);\r\n        info.AddValue(nameof(Value2), Value2);\r\n    }\r\n\r\n    public static implicit operator ValueTupleDouble<T1, T2>((T1, T2) valueTupleDouble)\r\n        => new() { Value1 = valueTupleDouble.Item1, Value2 = valueTupleDouble.Item2 };\r\n\r\n    public override string ToString()\r\n        => Value1 == null || Value2 == null ? \"<empty>\" : $\"{Value1} · {Value2}\";\r\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Analyzers.Tests/Fixtures/Serializable/ValueTupleTriple.cs",
    "content": "﻿using Xunit.Abstractions;\r\n\r\nnamespace BenchmarkDotNet.Analyzers.Tests.Fixtures;\r\n\r\npublic class ValueTupleTriple<T1, T2, T3> : IXunitSerializable\r\n{\r\n    public T1? Value1 { get; set; }\r\n\r\n    public T2? Value2 { get; set; }\r\n\r\n    public T3? Value3 { get; set; }\r\n\r\n    public void Deserialize(IXunitSerializationInfo info)\r\n    {\r\n        Value1 = info.GetValue<T1>(nameof(Value1));\r\n        Value2 = info.GetValue<T2>(nameof(Value2));\r\n        Value3 = info.GetValue<T3>(nameof(Value3));\r\n    }\r\n\r\n    public void Serialize(IXunitSerializationInfo info)\r\n    {\r\n        info.AddValue(nameof(Value1), Value1);\r\n        info.AddValue(nameof(Value2), Value2);\r\n        info.AddValue(nameof(Value3), Value3);\r\n    }\r\n\r\n    public static implicit operator ValueTupleTriple<T1, T2, T3>((T1, T2, T3) valueTupleTriple)\r\n        => new() { Value1 = valueTupleTriple.Item1, Value2 = valueTupleTriple.Item2, Value3 = valueTupleTriple.Item3 };\r\n\r\n    public override string ToString()\r\n        => Value1 == null || Value2 == null || Value3 == null ? \"<empty>\" : $\"{Value1} · {Value2} · {Value3}\";\r\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Analyzers.Tests/Fixtures/TheoryData/FieldOrPropertyDeclarationsTheoryData.cs",
    "content": "﻿using Xunit;\r\n\r\nnamespace BenchmarkDotNet.Analyzers.Tests.Fixtures;\r\n\r\ninternal sealed class FieldOrPropertyDeclarationsTheoryData : TheoryData<string>\r\n{\r\n    public FieldOrPropertyDeclarationsTheoryData()\r\n    {\r\n        AddRange(\r\n#if NET5_0_OR_GREATER\r\n                 \"Property { get; init; }\",\r\n#else\r\n                 \"Property { get; set; }\",\r\n#endif\r\n                 \"_field;\"\r\n        );\r\n    }\r\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Analyzers.Tests/Fixtures/TheoryData/NonPublicClassAccessModifiersTheoryData.cs",
    "content": "﻿using Xunit;\r\n\r\nnamespace BenchmarkDotNet.Analyzers.Tests.Fixtures;\r\n\r\ninternal sealed class NonPublicClassAccessModifiersTheoryData : TheoryData<string>\r\n{\r\n    public NonPublicClassAccessModifiersTheoryData()\r\n    {\r\n        AddRange(\r\n            \"protected internal \",\r\n            \"protected \",\r\n            \"internal \",\r\n            \"private protected \",\r\n            \"private \",\r\n            \"file \",\r\n            \"\"\r\n        );\r\n    }\r\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Analyzers.Tests/Fixtures/TheoryData/NonPublicClassMemberAccessModifiersTheoryData.cs",
    "content": "﻿namespace BenchmarkDotNet.Analyzers.Tests.Fixtures;\r\n\r\nusing Xunit;\r\n\r\ninternal sealed class NonPublicClassMemberAccessModifiersTheoryData : TheoryData<string>\r\n{\r\n    public NonPublicClassMemberAccessModifiersTheoryData()\r\n    {\r\n        AddRange(\r\n            \"protected internal \",\r\n            \"protected \",\r\n            \"internal \",\r\n            \"private protected \",\r\n            \"private \",\r\n            \"\"\r\n        );\r\n    }\r\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Analyzers.Tests/Fixtures/TheoryData/NonPublicPropertySetterAccessModifiersTheoryData.cs",
    "content": "﻿using Xunit;\r\n\r\nnamespace BenchmarkDotNet.Analyzers.Tests.Fixtures;\r\n\r\ninternal sealed class NonPublicPropertySetterAccessModifiersTheoryData : TheoryData<string>\r\n{\r\n    public NonPublicPropertySetterAccessModifiersTheoryData()\r\n    {\r\n        AddRange(\r\n            \"protected internal\",\r\n            \"protected\",\r\n            \"internal\",\r\n            \"private protected\",\r\n            \"private\"\r\n        );\r\n    }\r\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Exporters.Plotting.Tests/BenchmarkDotNet.Exporters.Plotting.Tests.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\n  <Import Project=\"..\\..\\build\\common.props\" />\n  <PropertyGroup>\n    <TargetFrameworks>net8.0;net462</TargetFrameworks>\n    <GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>\n    <GenerateDocumentationFile>false</GenerateDocumentationFile>\n  </PropertyGroup>\n  <ItemGroup Condition=\" '$(TargetFrameworkIdentifier)' == '.NETFramework' \">\n    <PackageReference Include=\"Microsoft.NETCore.Platforms\" Version=\"7.0.4\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ProjectReference Include=\"..\\..\\src\\BenchmarkDotNet.Exporters.Plotting\\BenchmarkDotNet.Exporters.Plotting.csproj\" />\n    <ProjectReference Include=\"..\\..\\src\\BenchmarkDotNet\\BenchmarkDotNet.csproj\" />\n    <ProjectReference Include=\"..\\BenchmarkDotNet.Tests\\BenchmarkDotNet.Tests.csproj\" />\n  </ItemGroup>\n  <ItemGroup>\n    <PackageReference Include=\"Microsoft.NET.Test.Sdk\" Version=\"18.0.1\" />\n    <PackageReference Include=\"xunit\" Version=\"2.9.3\" />\n    <PackageReference Include=\"xunit.runner.visualstudio\" Version=\"[2.8.2]\">\n      <PrivateAssets>all</PrivateAssets>\n      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\n    </PackageReference>\n  </ItemGroup>\n  <Import Project=\"..\\..\\build\\common.targets\" />\n</Project>\n"
  },
  {
    "path": "tests/BenchmarkDotNet.Exporters.Plotting.Tests/ScottPlotExporterTests.cs",
    "content": "using BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Tests.Builders;\nusing BenchmarkDotNet.Tests.Mocks;\nusing System;\nusing System.Diagnostics.CodeAnalysis;\nusing System.IO;\nusing System.Linq;\nusing Xunit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.Exporters.Plotting.Tests\n{\n    public class ScottPlotExporterTests(ITestOutputHelper output)\n    {\n        public static TheoryData<Type> GetGroupBenchmarkTypes()\n        {\n            var data = new TheoryData<Type>();\n            foreach (var type in typeof(BaselinesBenchmarks).GetNestedTypes())\n                data.Add(type);\n            return data;\n        }\n\n        [Theory]\n        [MemberData(nameof(GetGroupBenchmarkTypes))]\n        public void BarPlots(Type benchmarkType)\n        {\n            var logger = new AccumulationLogger();\n            logger.WriteLine(\"=== \" + benchmarkType.Name + \" ===\");\n\n            var exporter = new ScottPlotExporter()\n            {\n                IncludeBarPlot = true,\n                IncludeBoxPlot = false,\n            };\n            var summary = MockFactory.CreateSummary(benchmarkType);\n            var filePaths = exporter.ExportToFiles(summary, logger).ToList();\n            Assert.NotEmpty(filePaths);\n            Assert.All(filePaths, f => File.Exists(f));\n\n            foreach (string filePath in filePaths)\n                logger.WriteLine($\"* {filePath}\");\n            output.WriteLine(logger.GetLog());\n        }\n\n        [Theory]\n        [MemberData(nameof(GetGroupBenchmarkTypes))]\n        public void BoxPlots(Type benchmarkType)\n        {\n            var logger = new AccumulationLogger();\n            logger.WriteLine(\"=== \" + benchmarkType.Name + \" ===\");\n\n            var exporter = new ScottPlotExporter()\n            {\n                IncludeBarPlot = false,\n                IncludeBoxPlot = true,\n            };\n            var summary = MockFactory.CreateSummaryWithBiasedDistribution(benchmarkType, 1, 4, 10, 9);\n            var filePaths = exporter.ExportToFiles(summary, logger).ToList();\n            Assert.NotEmpty(filePaths);\n            Assert.All(filePaths, f => File.Exists(f));\n\n            foreach (string filePath in filePaths)\n                logger.WriteLine($\"* {filePath}\");\n            output.WriteLine(logger.GetLog());\n        }\n\n        [Theory]\n        [MemberData(nameof(GetGroupBenchmarkTypes))]\n        public void BoxPlotsWithOneMeasurement(Type benchmarkType)\n        {\n            var logger = new AccumulationLogger();\n            logger.WriteLine(\"=== \" + benchmarkType.Name + \" ===\");\n\n            var exporter = new ScottPlotExporter()\n            {\n                IncludeBarPlot = false,\n                IncludeBoxPlot = true,\n            };\n            var summary = MockFactory.CreateSummaryWithBiasedDistribution(benchmarkType, 1, 4, 10, 1);\n            var filePaths = exporter.ExportToFiles(summary, logger).ToList();\n            Assert.NotEmpty(filePaths);\n            Assert.All(filePaths, f => File.Exists(f));\n\n            foreach (string filePath in filePaths)\n                logger.WriteLine($\"* {filePath}\");\n            output.WriteLine(logger.GetLog());\n        }\n\n        [SuppressMessage(\"ReSharper\", \"InconsistentNaming\")]\n        public static class BaselinesBenchmarks\n        {\n            /* NoBaseline */\n            [RankColumn, LogicalGroupColumn, BaselineColumn]\n            [SimpleJob(id: \"Job1\"), SimpleJob(id: \"Job2\")]\n            public class NoBaseline_MethodsParamsJobs\n            {\n                [Params(2, 10)] public int Param;\n\n                [Benchmark] public void Base() { }\n                [Benchmark] public void Foo() { }\n                [Benchmark] public void Bar() { }\n            }\n\n            [RankColumn, LogicalGroupColumn, BaselineColumn]\n            [SimpleJob(id: \"Job1\"), SimpleJob(id: \"Job2\")]\n            [GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByMethod)]\n            public class NoBaseline_MethodsParamsJobs_GroupByMethod\n            {\n                [Params(2, 10)] public int Param;\n\n                [Benchmark, BenchmarkCategory(\"CatA\")] public void Base() { }\n                [Benchmark, BenchmarkCategory(\"CatB\")] public void Foo() { }\n                [Benchmark, BenchmarkCategory(\"CatB\")] public void Bar() { }\n            }\n\n            [RankColumn, LogicalGroupColumn, BaselineColumn]\n            [SimpleJob(id: \"Job1\"), SimpleJob(id: \"Job2\")]\n            [GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByJob)]\n            public class NoBaseline_MethodsParamsJobs_GroupByJob\n            {\n                [Params(2, 10)] public int Param;\n\n                [Benchmark, BenchmarkCategory(\"CatA\")] public void Base() { }\n                [Benchmark, BenchmarkCategory(\"CatB\")] public void Foo() { }\n                [Benchmark, BenchmarkCategory(\"CatB\")] public void Bar() { }\n            }\n\n            [RankColumn, LogicalGroupColumn, BaselineColumn]\n            [SimpleJob(id: \"Job1\"), SimpleJob(id: \"Job2\")]\n            [GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByParams)]\n            public class NoBaseline_MethodsParamsJobs_GroupByParams\n            {\n                [Params(2, 10)] public int Param;\n\n                [Benchmark, BenchmarkCategory(\"CatA\")] public void Base() { }\n                [Benchmark, BenchmarkCategory(\"CatB\")] public void Foo() { }\n                [Benchmark, BenchmarkCategory(\"CatB\")] public void Bar() { }\n            }\n\n            [RankColumn, LogicalGroupColumn, BaselineColumn]\n            [SimpleJob(id: \"Job1\"), SimpleJob(id: \"Job2\")]\n            [GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByCategory)]\n            public class NoBaseline_MethodsParamsJobs_GroupByCategory\n            {\n                [Params(2, 10)] public int Param;\n\n                [Benchmark(Baseline = true), BenchmarkCategory(\"CatA\")]\n                public void A1() { }\n\n                [Benchmark, BenchmarkCategory(\"CatA\")] public void A2() { }\n\n                [Benchmark(Baseline = true), BenchmarkCategory(\"CatB\")]\n                public void B1() { }\n\n                [Benchmark, BenchmarkCategory(\"CatB\")] public void B2() { }\n            }\n\n            [RankColumn, LogicalGroupColumn, BaselineColumn]\n            [SimpleJob(id: \"Job1\"), SimpleJob(id: \"Job2\")]\n            [GroupBenchmarksBy(\n                BenchmarkLogicalGroupRule.ByMethod,\n                BenchmarkLogicalGroupRule.ByJob,\n                BenchmarkLogicalGroupRule.ByParams,\n                BenchmarkLogicalGroupRule.ByCategory)]\n            public class NoBaseline_MethodsParamsJobs_GroupByAll\n            {\n                [Params(2, 10)] public int Param;\n\n                [Benchmark(Baseline = true), BenchmarkCategory(\"CatA\")]\n                public void A1() { }\n\n                [Benchmark, BenchmarkCategory(\"CatA\")] public void A2() { }\n\n                [Benchmark(Baseline = true), BenchmarkCategory(\"CatB\")]\n                public void B1() { }\n\n                [Benchmark, BenchmarkCategory(\"CatB\")] public void B2() { }\n            }\n\n            /* MethodBaseline */\n\n            [RankColumn, LogicalGroupColumn, BaselineColumn]\n            public class MethodBaseline_Methods\n            {\n                [Benchmark(Baseline = true)] public void Base() { }\n                [Benchmark] public void Foo() { }\n                [Benchmark] public void Bar() { }\n            }\n\n            [RankColumn, LogicalGroupColumn, BaselineColumn]\n            public class MethodBaseline_MethodsParams\n            {\n                [Params(2, 10)] public int Param;\n\n                [Benchmark(Baseline = true)] public void Base() { }\n                [Benchmark] public void Foo() { }\n                [Benchmark] public void Bar() { }\n            }\n\n            [RankColumn, LogicalGroupColumn, BaselineColumn]\n            [SimpleJob(id: \"Job1\"), SimpleJob(id: \"Job2\")]\n            public class MethodBaseline_MethodsJobs\n            {\n                [Benchmark(Baseline = true)] public void Base() { }\n                [Benchmark] public void Foo() { }\n                [Benchmark] public void Bar() { }\n            }\n\n            [RankColumn, LogicalGroupColumn, BaselineColumn]\n            [SimpleJob(id: \"Job1\"), SimpleJob(id: \"Job2\")]\n            public class MethodBaseline_MethodsParamsJobs\n            {\n                [Params(2, 10)] public int Param;\n\n                [Benchmark(Baseline = true)] public void Base() { }\n                [Benchmark] public void Foo() { }\n                [Benchmark] public void Bar() { }\n            }\n\n            /* JobBaseline */\n\n            [RankColumn, LogicalGroupColumn, BaselineColumn]\n            [SimpleJob(id: \"Job1\", baseline: true), SimpleJob(id: \"Job2\")]\n            public class JobBaseline_MethodsJobs\n            {\n                [Benchmark] public void Base() { }\n                [Benchmark] public void Foo() { }\n                [Benchmark] public void Bar() { }\n            }\n\n            [RankColumn, LogicalGroupColumn, BaselineColumn]\n            [SimpleJob(id: \"Job1\", baseline: true), SimpleJob(id: \"Job2\")]\n            public class JobBaseline_MethodsParamsJobs\n            {\n                [Params(2, 10)] public int Param;\n\n                [Benchmark] public void Base() { }\n                [Benchmark] public void Foo() { }\n                [Benchmark] public void Bar() { }\n            }\n\n            /* MethodJobBaseline */\n\n            [RankColumn, LogicalGroupColumn, BaselineColumn]\n            [SimpleJob(id: \"Job1\", baseline: true), SimpleJob(id: \"Job2\")]\n            public class MethodJobBaseline_MethodsJobs\n            {\n                [Benchmark(Baseline = true)] public void Foo() { }\n                [Benchmark] public void Bar() { }\n            }\n\n            [RankColumn, LogicalGroupColumn, BaselineColumn]\n            [SimpleJob(id: \"Job1\", baseline: true), SimpleJob(id: \"Job2\")]\n            public class MethodJobBaseline_MethodsJobsParams\n            {\n                [Params(2, 10)] public int Param;\n\n                [Benchmark(Baseline = true)] public void Foo() { }\n                [Benchmark] public void Bar() { }\n            }\n\n            /* Invalid */\n\n#pragma warning disable BDN1107\n            [RankColumn, LogicalGroupColumn, BaselineColumn]\n            public class Invalid_TwoMethodBaselines\n            {\n                [Benchmark(Baseline = true)] public void Foo() { }\n                [Benchmark(Baseline = true)] public void Bar() { }\n            }\n#pragma warning restore BDN1107\n\n            [RankColumn, LogicalGroupColumn, BaselineColumn]\n            [SimpleJob(id: \"Job1\", baseline: true), SimpleJob(id: \"Job2\", baseline: true)]\n            public class Invalid_TwoJobBaselines\n            {\n                [Benchmark] public void Foo() { }\n                [Benchmark] public void Bar() { }\n            }\n\n            /* Escape Params */\n\n            public class Escape_ParamsAndArguments\n            {\n                [Params(\"\\t\", \"\\n\")] public required string StringParam;\n\n                [Arguments('\\t')]\n                [Arguments('\\n')]\n                [Benchmark] public void Foo(char charArg) { }\n\n                [Benchmark] public void Bar() { }\n            }\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/AllSetupAndCleanupTest.cs",
    "content": "using System;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Tests.XUnit;\nusing Xunit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.IntegrationTests\n{\n    public class AllSetupAndCleanupTest : BenchmarkTestExecutor\n    {\n        private const string Prefix = \"// ### Called: \";\n        private const string GlobalSetupCalled = Prefix + \"GlobalSetup\";\n        private const string GlobalCleanupCalled = Prefix + \"GlobalCleanup\";\n        private const string IterationSetupCalled = Prefix + \"IterationSetup\";\n        private const string IterationCleanupCalled = Prefix + \"IterationCleanup\";\n        private const string BenchmarkCalled = Prefix + \"Benchmark\";\n\n        private readonly string[] expectedLogLines = [\n            \"// ### Called: GlobalSetup\",\n\n            \"// ### Called: IterationSetup (1)\", // MainWarmup1\n            \"// ### Called: Benchmark\", // MainWarmup1\n            \"// ### Called: IterationCleanup (1)\", // MainWarmup1\n            \"// ### Called: IterationSetup (2)\", // MainWarmup2\n            \"// ### Called: Benchmark\", // MainWarmup2\n            \"// ### Called: IterationCleanup (2)\", // MainWarmup2\n\n            \"// ### Called: IterationSetup (3)\", // MainTarget1\n            \"// ### Called: Benchmark\", // MainTarget1\n            \"// ### Called: IterationCleanup (3)\", // MainTarget1\n            \"// ### Called: IterationSetup (4)\", // MainTarget2\n            \"// ### Called: Benchmark\", // MainTarget2\n            \"// ### Called: IterationCleanup (4)\", // MainTarget2\n            \"// ### Called: IterationSetup (5)\", // MainTarget3\n            \"// ### Called: Benchmark\", // MainTarget3\n            \"// ### Called: IterationCleanup (5)\", // MainTarget3\n\n            \"// ### Called: GlobalCleanup\"\n        ];\n\n        public AllSetupAndCleanupTest(ITestOutputHelper output) : base(output) { }\n\n        private static string[] GetActualLogLines(Summary summary)\n            => GetSingleStandardOutput(summary).Where(line => line.StartsWith(Prefix)).ToArray();\n\n        [Theory]\n        [InlineData(typeof(AllSetupAndCleanupAttributeBenchmarks))]\n        [InlineData(typeof(AllSetupAndCleanupAttributeBenchmarksTask))]\n        [InlineData(typeof(AllSetupAndCleanupAttributeBenchmarksGenericTask))]\n        [InlineData(typeof(AllSetupAndCleanupAttributeBenchmarksValueTask))]\n        [InlineData(typeof(AllSetupAndCleanupAttributeBenchmarksGenericValueTask))]\n        [InlineData(typeof(AllSetupAndCleanupAttributeBenchmarksValueTaskSource))]\n        [InlineData(typeof(AllSetupAndCleanupAttributeBenchmarksGenericValueTaskSource))]\n        public void AllSetupAndCleanupMethodRunsTest(Type benchmarkType)\n        {\n            var miniJob = Job.Default.WithStrategy(RunStrategy.Monitoring).WithWarmupCount(2).WithIterationCount(3).WithInvocationCount(1).WithUnrollFactor(1).WithId(\"MiniJob\");\n            var config = CreateSimpleConfig(job: miniJob);\n\n            var summary = CanExecute(benchmarkType, config);\n\n            var actualLogLines = GetActualLogLines(summary);\n            foreach (string line in actualLogLines)\n                Output.WriteLine(line);\n            SmartAssert.Equal(expectedLogLines, actualLogLines);\n        }\n\n        public class AllSetupAndCleanupAttributeBenchmarks\n        {\n            private int setupCounter;\n            private int cleanupCounter;\n\n            [IterationSetup]\n            public void IterationSetup() => Console.WriteLine(IterationSetupCalled + \" (\" + ++setupCounter + \")\");\n\n            [IterationCleanup]\n            public void IterationCleanup() => Console.WriteLine(IterationCleanupCalled + \" (\" + ++cleanupCounter + \")\");\n\n            [GlobalSetup]\n            public void GlobalSetup() => Console.WriteLine(GlobalSetupCalled);\n\n            [GlobalCleanup]\n            public void GlobalCleanup() => Console.WriteLine(GlobalCleanupCalled);\n\n            [Benchmark]\n            public void Benchmark() => Console.WriteLine(BenchmarkCalled);\n        }\n\n        public class AllSetupAndCleanupAttributeBenchmarksTask\n        {\n            private int setupCounter;\n            private int cleanupCounter;\n\n            [IterationSetup]\n            public void IterationSetup() => Console.WriteLine(IterationSetupCalled + \" (\" + ++setupCounter + \")\");\n\n            [IterationCleanup]\n            public void IterationCleanup() => Console.WriteLine(IterationCleanupCalled + \" (\" + ++cleanupCounter + \")\");\n\n            [GlobalSetup]\n            public Task GlobalSetup() => Console.Out.WriteLineAsync(GlobalSetupCalled);\n\n            [GlobalCleanup]\n            public Task GlobalCleanup() => Console.Out.WriteLineAsync(GlobalCleanupCalled);\n\n            [Benchmark]\n            public void Benchmark() => Console.WriteLine(BenchmarkCalled);\n        }\n\n        public class AllSetupAndCleanupAttributeBenchmarksGenericTask\n        {\n            private int setupCounter;\n            private int cleanupCounter;\n\n            [IterationSetup]\n            public void IterationSetup() => Console.WriteLine(IterationSetupCalled + \" (\" + ++setupCounter + \")\");\n\n            [IterationCleanup]\n            public void IterationCleanup() => Console.WriteLine(IterationCleanupCalled + \" (\" + ++cleanupCounter + \")\");\n\n            [GlobalSetup]\n            public async Task<int> GlobalSetup()\n            {\n                await Console.Out.WriteLineAsync(GlobalSetupCalled);\n\n                return 42;\n            }\n\n            [GlobalCleanup]\n            public async Task<int> GlobalCleanup()\n            {\n                await Console.Out.WriteLineAsync(GlobalCleanupCalled);\n\n                return 42;\n            }\n\n            [Benchmark]\n            public void Benchmark() => Console.WriteLine(BenchmarkCalled);\n        }\n\n        public class AllSetupAndCleanupAttributeBenchmarksValueTask\n        {\n            private int setupCounter;\n            private int cleanupCounter;\n\n            [IterationSetup]\n            public void IterationSetup() => Console.WriteLine(IterationSetupCalled + \" (\" + ++setupCounter + \")\");\n\n            [IterationCleanup]\n            public void IterationCleanup() => Console.WriteLine(IterationCleanupCalled + \" (\" + ++cleanupCounter + \")\");\n\n            [GlobalSetup]\n            public ValueTask GlobalSetup() => new ValueTask(Console.Out.WriteLineAsync(GlobalSetupCalled));\n\n            [GlobalCleanup]\n            public ValueTask GlobalCleanup() => new ValueTask(Console.Out.WriteLineAsync(GlobalCleanupCalled));\n\n            [Benchmark]\n            public void Benchmark() => Console.WriteLine(BenchmarkCalled);\n        }\n\n        public class AllSetupAndCleanupAttributeBenchmarksGenericValueTask\n        {\n            private int setupCounter;\n            private int cleanupCounter;\n\n            [IterationSetup]\n            public void IterationSetup() => Console.WriteLine(IterationSetupCalled + \" (\" + ++setupCounter + \")\");\n\n            [IterationCleanup]\n            public void IterationCleanup() => Console.WriteLine(IterationCleanupCalled + \" (\" + ++cleanupCounter + \")\");\n\n            [GlobalSetup]\n            public async ValueTask<int> GlobalSetup()\n            {\n                await Console.Out.WriteLineAsync(GlobalSetupCalled);\n\n                return 42;\n            }\n\n            [GlobalCleanup]\n            public async ValueTask<int> GlobalCleanup()\n            {\n                await Console.Out.WriteLineAsync(GlobalCleanupCalled);\n\n                return 42;\n            }\n\n            [Benchmark]\n            public void Benchmark() => Console.WriteLine(BenchmarkCalled);\n        }\n\n        public class AllSetupAndCleanupAttributeBenchmarksValueTaskSource\n        {\n            private readonly ValueTaskSource<int> valueTaskSource = new();\n            private int setupCounter;\n            private int cleanupCounter;\n\n            [IterationSetup]\n            public void IterationSetup() => Console.WriteLine(IterationSetupCalled + \" (\" + ++setupCounter + \")\");\n\n            [IterationCleanup]\n            public void IterationCleanup() => Console.WriteLine(IterationCleanupCalled + \" (\" + ++cleanupCounter + \")\");\n\n            [GlobalSetup]\n            public ValueTask GlobalSetup()\n            {\n                valueTaskSource.Reset();\n                Console.Out.WriteLineAsync(GlobalSetupCalled).ContinueWith(_ => valueTaskSource.SetResult(42));\n                return new ValueTask(valueTaskSource, valueTaskSource.Token);\n            }\n\n            [GlobalCleanup]\n            public ValueTask GlobalCleanup()\n            {\n                valueTaskSource.Reset();\n                Console.Out.WriteLineAsync(GlobalCleanupCalled).ContinueWith(_ => valueTaskSource.SetResult(42));\n                return new ValueTask(valueTaskSource, valueTaskSource.Token);\n            }\n\n            [Benchmark]\n            public void Benchmark() => Console.WriteLine(BenchmarkCalled);\n        }\n\n        public class AllSetupAndCleanupAttributeBenchmarksGenericValueTaskSource\n        {\n            private readonly ValueTaskSource<int> valueTaskSource = new();\n            private int setupCounter;\n            private int cleanupCounter;\n\n            [IterationSetup]\n            public void IterationSetup() => Console.WriteLine(IterationSetupCalled + \" (\" + ++setupCounter + \")\");\n\n            [IterationCleanup]\n            public void IterationCleanup() => Console.WriteLine(IterationCleanupCalled + \" (\" + ++cleanupCounter + \")\");\n\n            [GlobalSetup]\n            public ValueTask<int> GlobalSetup()\n            {\n                valueTaskSource.Reset();\n                Console.Out.WriteLineAsync(GlobalSetupCalled).ContinueWith(_ => valueTaskSource.SetResult(42));\n                return new ValueTask<int>(valueTaskSource, valueTaskSource.Token);\n            }\n\n            [GlobalCleanup]\n            public ValueTask<int> GlobalCleanup()\n            {\n                valueTaskSource.Reset();\n                Console.Out.WriteLineAsync(GlobalCleanupCalled).ContinueWith(_ => valueTaskSource.SetResult(42));\n                return new ValueTask<int>(valueTaskSource, valueTaskSource.Token);\n            }\n\n            [Benchmark]\n            public void Benchmark() => Console.WriteLine(BenchmarkCalled);\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/App.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<configuration>\n  <appSettings>\n    <add key=\"settings\" value=\"getsCopied\" />\n    <add key=\"xunit.methodDisplay\" value=\"method\" />\n  </appSettings>\n</configuration>"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/AppConfigTests.cs",
    "content": "﻿using System;\nusing System.Configuration;\nusing BenchmarkDotNet.Attributes;\nusing Xunit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.IntegrationTests\n{\n    public class AppConfigTests : BenchmarkTestExecutor\n    {\n        public AppConfigTests(ITestOutputHelper output) : base(output) { }\n\n        [Fact]\n        public void CustomSettingsGetRewritten()\n            => CanExecute<AppConfigConsumingBenchmark>();\n    }\n\n    public class AppConfigConsumingBenchmark\n    {\n        [Benchmark]\n        public void ReadFromAppConfig()\n        {\n            if (ConfigurationManager.AppSettings[\"settings\"] != \"getsCopied\")\n            {\n                throw new InvalidOperationException(\"The app config did not get copied\");\n            }\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/ArgumentsTests.cs",
    "content": "﻿using BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Tests.XUnit;\nusing BenchmarkDotNet.Toolchains;\nusing BenchmarkDotNet.Toolchains.InProcess.Emit;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Numerics;\nusing System.Threading.Tasks;\nusing Xunit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.IntegrationTests\n{\n    public class ArgumentsTests : BenchmarkTestExecutor\n    {\n        public static IEnumerable<object[]> GetToolchains()\n            =>\n                [\n                    [Job.Default.GetToolchain()],\n                    [InProcessEmitToolchain.Default],\n                ];\n\n        public ArgumentsTests(ITestOutputHelper output) : base(output) { }\n\n        [Theory, MemberData(nameof(GetToolchains), DisableDiscoveryEnumeration = true)]\n        public void ArgumentsArePassedToBenchmarks(IToolchain toolchain) => CanExecute<WithArguments>(toolchain);\n\n        public class WithArguments\n        {\n            [Benchmark]\n            [Arguments(true, 1)]\n            [Arguments(false, 2)]\n            public void Simple(bool boolean, int number)\n            {\n                if (boolean && number != 1 || !boolean && number != 2)\n                    throw new InvalidOperationException(\"Incorrect values were passed\");\n            }\n\n            [Benchmark]\n            [Arguments(true, 1)]\n            [Arguments(false, 2)]\n            public Task SimpleAsync(bool boolean, int number)\n            {\n                if (boolean && number != 1 || !boolean && number != 2)\n                    throw new InvalidOperationException(\"Incorrect values were passed\");\n\n                return Task.CompletedTask;\n            }\n\n            [Benchmark]\n            [Arguments(true, 1)]\n            [Arguments(false, 2)]\n            public ValueTask<int> SimpleValueTaskAsync(bool boolean, int number)\n            {\n                if (boolean && number != 1 || !boolean && number != 2)\n                    throw new InvalidOperationException(\"Incorrect values were passed\");\n\n                return new ValueTask<int>(0);\n            }\n        }\n\n        [Theory, MemberData(nameof(GetToolchains), DisableDiscoveryEnumeration = true)]\n        public void ArgumentsFromSourceArePassedToBenchmarks(IToolchain toolchain) => CanExecute<WithArgumentsSource>(toolchain);\n\n        public class WithArgumentsSource\n        {\n            [Benchmark]\n            [ArgumentsSource(nameof(ArgumentsProvider))]\n            public void Simple(bool boolean, int number)\n            {\n                if (boolean && number != 1 || !boolean && number != 2)\n                    throw new InvalidOperationException(\"Incorrect values were passed\");\n            }\n\n            public IEnumerable<object[]> ArgumentsProvider()\n            {\n                yield return new object[] { true, 1 };\n                yield return new object[] { false, 2 };\n            }\n        }\n\n        [Theory, MemberData(nameof(GetToolchains), DisableDiscoveryEnumeration = true)]\n        public void ArgumentsFromSourceInAnotherClassArePassedToBenchmarks(IToolchain toolchain) => CanExecute<WithArgumentsSourceInAnotherClass>(toolchain);\n\n        public class WithArgumentsSourceInAnotherClass\n        {\n            [Benchmark]\n            [ArgumentsSource(typeof(ExternalClassWithArgumentsSource), nameof(ExternalClassWithArgumentsSource.OnePrimitiveType))]\n            public void OnePrimitiveType(int number)\n            {\n                if (number % 2 != 1)\n                    throw new InvalidOperationException(\"Incorrect values were passed\");\n            }\n\n            [Benchmark]\n            [ArgumentsSource(typeof(ExternalClassWithArgumentsSource), nameof(ExternalClassWithArgumentsSource.TwoPrimitiveTypes))]\n            public void TwoPrimitiveTypes(bool boolean, int number)\n            {\n                if (boolean && number != 1 || !boolean && number != 2)\n                    throw new InvalidOperationException(\"Incorrect values were passed\");\n            }\n\n            [Benchmark]\n            [ArgumentsSource(typeof(ExternalClassWithArgumentsSource), nameof(ExternalClassWithArgumentsSource.OneNonPrimitiveType))]\n            public void OneNonPrimitiveType(Version version)\n            {\n                int[] versionNumbers = [version.Major, version.Minor, version.MinorRevision, version.Build];\n                if (versionNumbers.Distinct().Count() != 4)\n                    throw new InvalidOperationException(\"Incorrect values were passed\");\n            }\n\n            [Benchmark]\n            [ArgumentsSource(typeof(ExternalClassWithArgumentsSource), nameof(ExternalClassWithArgumentsSource.TwoNonPrimitiveTypes))]\n            public void TwoNonPrimitiveTypes(Version version, DateTime dateTime)\n            {\n                int[] versionNumbers = [version.Major, version.Minor, version.MinorRevision, version.Build];\n                if (versionNumbers.Distinct().Count() != 4)\n                    throw new InvalidOperationException(\"Incorrect values were passed\");\n\n                if (dateTime.Month != dateTime.Day)\n                    throw new InvalidOperationException(\"Incorrect values were passed\");\n            }\n\n            [Benchmark]\n            [ArgumentsSource(typeof(ExternalClassWithArgumentsSource), nameof(ExternalClassWithArgumentsSource.OnePrimitiveAndOneNonPrimitive))]\n            public void OnePrimitiveAndOneNonPrimitive(Version version, int number)\n            {\n                int[] versionNumbers = [version.Major, version.Minor, version.MinorRevision, version.Build];\n                if (versionNumbers.Distinct().Count() != 4)\n                    throw new InvalidOperationException(\"Incorrect values were passed\");\n\n                if (number != version.Major)\n                    throw new InvalidOperationException(\"Incorrect values were passed\");\n            }\n        }\n        public static class ExternalClassWithArgumentsSource\n        {\n            public static IEnumerable<int> OnePrimitiveType()\n            {\n                yield return 3;\n                yield return 5;\n            }\n\n            public static IEnumerable<object[]> TwoPrimitiveTypes()\n            {\n                yield return new object[] { true, 1 };\n                yield return new object[] { false, 2 };\n            }\n\n            public static IEnumerable<Version> OneNonPrimitiveType()\n            {\n                yield return new Version(1, 2, 3, 4);\n                yield return new Version(5, 6, 7, 8);\n            }\n\n            public static IEnumerable<object[]> TwoNonPrimitiveTypes()\n            {\n                yield return new object[] { new Version(1, 2, 3, 4), new DateTime(2011, 11, 11) };\n                yield return new object[] { new Version(5, 6, 7, 8), new DateTime(2002, 02, 02) };\n            }\n\n            public static IEnumerable<object[]> OnePrimitiveAndOneNonPrimitive()\n            {\n                yield return new object[] { new Version(1, 2, 3, 4), 1 };\n                yield return new object[] { new Version(5, 6, 7, 8), 5 };\n            }\n        }\n\n        [Theory, MemberData(nameof(GetToolchains), DisableDiscoveryEnumeration = true)]\n        public void ArgumentsCanBePassedByReferenceToBenchmark(IToolchain toolchain) => CanExecute<WithRefArguments>(toolchain);\n\n        public class WithRefArguments\n        {\n            [Benchmark]\n            [Arguments(true, 1)]\n            [Arguments(false, 2)]\n            public void Simple(ref bool boolean, ref int number)\n            {\n                if (boolean && number != 1 || !boolean && number != 2)\n                    throw new InvalidOperationException(\"Incorrect values were passed\");\n            }\n        }\n\n        [Theory, MemberData(nameof(GetToolchains), DisableDiscoveryEnumeration = true)]\n        public void ArgumentsCanBePassedByReadonlyReferenceToBenchmark(IToolchain toolchain) => CanExecute<WithInArguments>(toolchain);\n\n        public class WithInArguments\n        {\n            [Benchmark]\n            [Arguments(true, 1)]\n            [Arguments(false, 2)]\n            public void Simple(in bool boolean, in int number)\n            {\n                if (boolean && number != 1 || !boolean && number != 2)\n                    throw new InvalidOperationException(\"Incorrect values were passed\");\n            }\n        }\n\n        [Theory, MemberData(nameof(GetToolchains), DisableDiscoveryEnumeration = true)]\n        public void NonCompileTimeConstantsCanBeReturnedFromSource(IToolchain toolchain) => CanExecute<WithComplexTypesReturnedFromSources>(toolchain);\n\n        public class WithComplexTypesReturnedFromSources\n        {\n            [ParamsSource(nameof(DictionaryAsParam))]\n            public required Dictionary<int, string> DictionaryParamInstance;\n\n            [ParamsSource(nameof(SameButStatic))]\n            public required Dictionary<int, string> DictionaryParamStatic;\n\n            [Benchmark]\n            [ArgumentsSource(nameof(NonPrimitive))]\n            public void Simple(SomeClass someClass, SomeStruct someStruct)\n            {\n                if (DictionaryParamInstance[1234] != \"it's an instance getter\")\n                    throw new InvalidOperationException(\"Incorrect dictionary (instance\");\n\n                if (DictionaryParamStatic[1234] != \"it's a static getter\")\n                    throw new InvalidOperationException(\"Incorrect dictionary (static)\");\n\n                if (!(someStruct.RangeEnd == 100 || someStruct.RangeEnd == 1000))\n                    throw new InvalidOperationException(\"Incorrect struct values were passed\");\n\n                if (someStruct.RangeEnd != someClass.Values.Length)\n                    throw new InvalidOperationException(\"Incorrect length\");\n\n                for (int i = 0; i < someStruct.RangeEnd; i++)\n                    if (someClass.Values[i] != i * 2)\n                        throw new InvalidOperationException(\"Incorrect array values were passed\");\n            }\n\n            public IEnumerable<object[]> NonPrimitive()\n            {\n                yield return new object[] { new SomeClass(Enumerable.Range(0, 100).ToArray()), new SomeStruct(100) };\n                yield return new object[] { new SomeClass(Enumerable.Range(0, 1000).ToArray()), new SomeStruct(1000) };\n            }\n\n            public IEnumerable<object> DictionaryAsParam => [new Dictionary<int, string>() { { 1234, \"it's an instance getter\" } }];\n\n            public static IEnumerable<object> SameButStatic => [new Dictionary<int, string>() { { 1234, \"it's a static getter\" } }];\n\n            public class SomeClass\n            {\n                public SomeClass(int[] initialValues) => Values = initialValues.Select(val => val * 2).ToArray();\n\n                public int[] Values { get; }\n            }\n\n            public struct SomeStruct\n            {\n                public SomeStruct(int rangeEnd) => RangeEnd = rangeEnd;\n\n                public int RangeEnd { get; }\n            }\n        }\n\n        [Theory, MemberData(nameof(GetToolchains), DisableDiscoveryEnumeration = true)]\n        public void ArrayCanBeUsedAsArgument(IToolchain toolchain) => CanExecute<WithArray>(toolchain);\n\n        public class WithArray\n        {\n            [Benchmark]\n            [Arguments(new[] { 0, 1, 2 })]\n            public void AcceptingArray(int[] array)\n            {\n                if (array.Length != 3)\n                    throw new InvalidOperationException(\"Incorrect array length\");\n\n                for (int i = 0; i < 3; i++)\n                    if (array[i] != i)\n                        throw new InvalidOperationException($\"Incorrect array element at index {i}, was {array[i]} instead of {i}\");\n            }\n        }\n\n        [Theory, MemberData(nameof(GetToolchains), DisableDiscoveryEnumeration = true)]\n        public void IEnumerableCanBeUsedAsArgument(IToolchain toolchain) => CanExecute<WithIEnumerable>(toolchain);\n\n        public class WithIEnumerable\n        {\n            private static IEnumerable<int> Iterator() { yield return 1; }\n\n            public IEnumerable<object[]> Sources()\n            {\n                yield return new object[] { \"Empty\", Enumerable.Empty<int>() };\n                yield return new object[] { \"Range\", Enumerable.Range(0, 10) };\n                yield return new object[] { \"List\", new List<int>() { 1, 2, 3 } };\n                yield return new object[] { \"int[]\", new int[] { 1, 2, 3 } };\n                yield return new object[] { \"int[].Select\", new int[] { 1, 2, 3 }.Select(i => i) };\n                yield return new object[] { \"int[].Select.Where\", new int[] { 1, 2, 3 }.Select(i => i).Where(i => i % 2 == 0) };\n                yield return new object[] { \"Iterator\", Iterator() };\n                yield return new object[] { \"Iterator.Select\", Iterator().Select(i => i) };\n                yield return new object[] { \"Iterator.Select.Where\", Iterator().Select(i => i).Where(i => i % 2 == 0) };\n            }\n\n            [Benchmark]\n            [ArgumentsSource(nameof(Sources))]\n            public void Any(string name, IEnumerable<int> source) => source.Any();\n        }\n\n        [Theory, MemberData(nameof(GetToolchains), DisableDiscoveryEnumeration = true)]\n        public void IEnumerableArgumentsCanBeGrouped(IToolchain toolchain)\n        {\n            var summary = CanExecute<EnumerableOnDifferentMethods>(toolchain, (config) => config.AddLogicalGroupRules(BenchmarkLogicalGroupRule.ByParams)); // We must group by params to test array argument grouping\n\n            // There should be two logical groups, one for the first argument and one for the second argument\n            // Thus there should be two pairs per descriptor, and each pair should be distinct because it belongs to a different group\n\n            var descriptorGroupPairs = summary.BenchmarksCases.Select(benchmarkCase => (benchmarkCase.Descriptor, summary.GetLogicalGroupKey(benchmarkCase))).GroupBy(benchmarkCase => benchmarkCase.Descriptor);\n\n            Assert.True(\n                descriptorGroupPairs.All(group => group.Select(pair => pair.Item2).Distinct().Count() == 2)\n            );\n        }\n\n        public class EnumerableOnDifferentMethods\n        {\n            public IEnumerable<IEnumerable<int>> GetEnumerables()\n            {\n                yield return Enumerable.Range(1, 10);\n                yield return Enumerable.Range(2, 10);\n            }\n\n            [Benchmark(Baseline = true)]\n            [ArgumentsSource(nameof(GetEnumerables))]\n            public void AcceptsEnumerables(IEnumerable<int> arg)\n            {\n                if (arg.IsEmpty())\n                    throw new ArgumentException(\"Incorrect length\");\n            }\n\n            [Benchmark]\n            [ArgumentsSource(nameof(GetEnumerables))]\n            public void AcceptsEnumerables2(IEnumerable<int> arg)\n            {\n                if (arg.IsEmpty())\n                    throw new ArgumentException(\"Incorrect length\");\n            }\n        }\n\n        [Theory, MemberData(nameof(GetToolchains), DisableDiscoveryEnumeration = true)]\n        public void IEnumerableArgumentsOfDifferentLengthsCanBeGrouped(IToolchain toolchain)\n        {\n            var summary = CanExecute<EnumerableOfDiffLengthOnDifferentMethods>(toolchain, (config) => config.AddLogicalGroupRules(BenchmarkLogicalGroupRule.ByParams)); // We must group by params to test array argument grouping\n\n            // There should be two logical groups, one for the first argument and one for the second argument\n            // Thus there should be two pairs per descriptor, and each pair should be distinct because it belongs to a different group\n\n            var descriptorGroupPairs = summary.BenchmarksCases.Select(benchmarkCase => (benchmarkCase.Descriptor, summary.GetLogicalGroupKey(benchmarkCase))).GroupBy(benchmarkCase => benchmarkCase.Descriptor);\n\n            Assert.True(\n                descriptorGroupPairs.All(group => group.Select(pair => pair.Item2).Distinct().Count() == 2)\n            );\n        }\n\n        public class EnumerableOfDiffLengthOnDifferentMethods\n        {\n            public IEnumerable<IEnumerable<int>> GetEnumerables()\n            {\n                yield return Enumerable.Range(1, 10);\n                yield return Enumerable.Range(1, 11);\n            }\n\n            [Benchmark(Baseline = true)]\n            [ArgumentsSource(nameof(GetEnumerables))]\n            public void AcceptsEnumerables(IEnumerable<int> arg)\n            {\n                if (arg.IsEmpty())\n                    throw new ArgumentException(\"Incorrect length\");\n            }\n\n            [Benchmark]\n            [ArgumentsSource(nameof(GetEnumerables))]\n            public void AcceptsEnumerables2(IEnumerable<int> arg)\n            {\n                if (arg.IsEmpty())\n                    throw new ArgumentException(\"Incorrect length\");\n            }\n        }\n\n        [Theory, MemberData(nameof(GetToolchains), DisableDiscoveryEnumeration = true)]\n        public void JaggedArrayCanBeUsedAsArgument(IToolchain toolchain) => CanExecute<WithJaggedArray>(toolchain);\n\n        public class WithJaggedArray\n        {\n            [Benchmark]\n            [ArgumentsSource(nameof(CreateMatrix))]\n            public void Test(int[][] array)\n            {\n                for (int i = 0; i < 10; i++)\n                    for (int j = 0; j < i; j++)\n                        if (array[i][j] != i)\n                            throw new ArgumentException(\"Invalid value\");\n            }\n\n            public IEnumerable<object> CreateMatrix()\n            {\n                int[][] jagged = new int[10][];\n\n                for (int i = 0; i < jagged.Length; i++)\n                {\n                    int[] row = new int[i];\n\n                    for (int j = 0; j < i; j++)\n                        row[j] = i;\n\n                    jagged[i] = row;\n                }\n\n                yield return jagged;\n            }\n        }\n\n        [Theory, MemberData(nameof(GetToolchains), DisableDiscoveryEnumeration = true)]\n        public void GenericTypeCanBePassedByRefAsArgument(IToolchain toolchain) => CanExecute<WithGenericByRef>(toolchain);\n\n        public class WithGenericByRef\n        {\n            public class Generic<T1, T2>\n            {\n                public T1 Item1;\n                public T2 Item2;\n\n                public Generic(T1 item1, T2 item2)\n                {\n                    Item1 = item1;\n                    Item2 = item2;\n                }\n            }\n\n            [Benchmark]\n            [ArgumentsSource(nameof(GetInputData))]\n            public bool ValueTupleCompareNoOpt(ref Generic<int, string> byRef)\n            {\n                if (byRef.Item1 != 3 || byRef.Item2 != \"red\")\n                    throw new ArgumentException(\"Wrong values\");\n\n                return true;\n            }\n\n            public IEnumerable<object> GetInputData()\n            {\n                yield return new Generic<int, string>(3, \"red\");\n            }\n        }\n\n        [Theory, MemberData(nameof(GetToolchains), DisableDiscoveryEnumeration = true)]\n        public void AnArrayOfTypeWithNoParameterlessCtorCanBePassedAsArgument(IToolchain toolchain) => CanExecute<WithArrayOfStringAsArgument>(toolchain);\n\n        public class WithArrayOfStringAsArgument\n        {\n            [Benchmark]\n            [Arguments([new string[0]])]\n            // arguments accept \"params object[]\", when we pass just a string[] it's recognized as an array of params\n            public void TypeReflectionArrayGetType(object anArray)\n            {\n                string[] strings = (string[])anArray;\n\n                if (strings.Length != 0)\n                    throw new ArgumentException(\"The array should be empty\");\n            }\n        }\n\n        [Theory, MemberData(nameof(GetToolchains), DisableDiscoveryEnumeration = true)]\n        public void AnArrayCanBePassedToBenchmarkAsSpan(IToolchain toolchain) => CanExecute<WithArrayToSpan>(toolchain);\n\n        public class WithArrayToSpan\n        {\n            [Benchmark]\n            [Arguments(new[] { 0, 1, 2 })]\n            public void AcceptsSpan(Span<int> span)\n            {\n                if (span.Length != 3)\n                    throw new ArgumentException(\"Invalid length\");\n\n                for (int i = 0; i < 3; i++)\n                    if (span[i] != i)\n                        throw new ArgumentException(\"Invalid value\");\n            }\n        }\n\n        [Theory, MemberData(nameof(GetToolchains), DisableDiscoveryEnumeration = true)]\n        public void AnArrayFromArgumentsSourceCanBePassedToBenchmarkAsSpan(IToolchain toolchain) => CanExecute<WithArrayFromArgumentsSourceToSpan>(toolchain);\n\n        public class WithArrayFromArgumentsSourceToSpan\n        {\n            public IEnumerable<object[]> GetArray()\n            {\n                yield return new object[] { new[] { 0, 1, 2 } };\n            }\n\n            [Benchmark]\n            [ArgumentsSource(nameof(GetArray))]\n            public void AcceptsSpanFromArgumentsSource(Span<int> span)\n            {\n                if (span.Length != 3)\n                    throw new ArgumentException(\"Invalid length\");\n\n                for (int i = 0; i < 3; i++)\n                    if (span[i] != i)\n                        throw new ArgumentException(\"Invalid value\");\n            }\n        }\n\n        // The string -> ReadOnlySpan<char> implicit cast operator is available only in .NET Core 2.1+ (https://github.com/dotnet/corefx/issues/30121)\n#if NETCOREAPP2_1_OR_GREATER\n        [Theory]\n        [MemberData(nameof(GetToolchains), DisableDiscoveryEnumeration = true)]\n        public void StringCanBePassedToBenchmarkAsReadOnlySpan(IToolchain toolchain) => CanExecute<WithStringToReadOnlySpan>(toolchain);\n\n        public class WithStringToReadOnlySpan\n        {\n            private const string expectedString = \"very nice string\";\n\n            [Benchmark]\n            [Arguments(expectedString)]\n            public void AcceptsReadOnlySpan(ReadOnlySpan<char> notString)\n            {\n                string aString = notString.ToString();\n\n                if (aString != expectedString)\n                    throw new ArgumentException(\"Invalid value\");\n            }\n        }\n\n        [Theory]\n        [MemberData(nameof(GetToolchains), DisableDiscoveryEnumeration = true)]\n        public void StringFromArgumentsSourceCanBePassedToBenchmarkAsReadOnlySpan(IToolchain toolchain) => CanExecute<WithStringFromArgumentsSourceToReadOnlySpan>(toolchain);\n\n        public class WithStringFromArgumentsSourceToReadOnlySpan\n        {\n            private const string expectedString = \"very nice string\";\n\n            public IEnumerable<object[]> GetString()\n            {\n                yield return new object[] { expectedString };\n            }\n\n            [Benchmark]\n            [ArgumentsSource(nameof(GetString))]\n            public void AcceptsReadOnlySpanFromArgumentsSource(ReadOnlySpan<char> notString)\n            {\n                string aString = notString.ToString();\n\n                if (aString != expectedString)\n                    throw new ArgumentException(\"Invalid value\");\n            }\n        }\n#endif\n\n        [Theory, MemberData(nameof(GetToolchains), DisableDiscoveryEnumeration = true)]\n        public void AnArrayOfStringsCanBeUsedAsArgument(IToolchain toolchain) =>\n            CanExecute<WithArrayOfStringFromArgumentSource>(toolchain);\n\n        public class WithArrayOfStringFromArgumentSource\n        {\n            public IEnumerable<object> GetArrayOfString()\n            {\n                yield return new string[123];\n            }\n\n            [Benchmark]\n            [ArgumentsSource(nameof(GetArrayOfString))]\n            public void TypeReflectionArrayGetType(string[] array)\n            {\n                if (array.Length != 123)\n                    throw new ArgumentException(\"The array was empty\");\n            }\n        }\n\n        [Theory, MemberData(nameof(GetToolchains), DisableDiscoveryEnumeration = true)] // make sure BDN mimics xunit's MemberData behaviour\n        public void AnIEnumerableOfArrayOfObjectsCanBeUsedAsArgumentForBenchmarkAcceptingSingleArgument(IToolchain toolchain)\n            => CanExecute<WithIEnumerableOfArrayOfObjectsFromArgumentSource>(toolchain);\n\n        public class WithIEnumerableOfArrayOfObjectsFromArgumentSource\n        {\n            public IEnumerable<object[]> GetArguments()\n            {\n                yield return new object[] { true };\n            }\n\n            [Benchmark]\n            [ArgumentsSource(nameof(GetArguments))]\n            public void SingleArgument(bool boolean)\n            {\n                if (boolean != true)\n                    throw new ArgumentException(\"The value of boolean was incorrect\");\n            }\n        }\n\n        [Theory, MemberData(nameof(GetToolchains), DisableDiscoveryEnumeration = true)]\n        public void BenchmarkCanAcceptFewArrays(IToolchain toolchain) => CanExecute<FewArrays>(toolchain);\n\n        public class FewArrays\n        {\n            public IEnumerable<object[]> GetArrays()\n            {\n                yield return new object[2]\n                {\n                    new int[] { 0, 2, 4 },\n                    new int[] { 1, 3, 5 },\n                };\n            }\n\n            [Benchmark]\n            [ArgumentsSource(nameof(GetArrays))]\n            public void AcceptsArrays(int[] even, int[] notEven)\n            {\n                if (even.Length != 3 || notEven.Length != 3)\n                    throw new ArgumentException(\"Incorrect length\");\n\n                if (!even.All(n => n % 2 == 0))\n                    throw new ArgumentException(\"Not even\");\n\n                if (!notEven.All(n => n % 2 != 0))\n                    throw new ArgumentException(\"Even\");\n            }\n        }\n\n        [Theory, MemberData(nameof(GetToolchains), DisableDiscoveryEnumeration = true)]\n        public void ArrayArgumentsCanBeGrouped(IToolchain toolchain)\n        {\n            var summary = CanExecute<ArrayOnDifferentMethods>(toolchain, (config) => config.AddLogicalGroupRules(BenchmarkLogicalGroupRule.ByParams)); // We must group by params to test array argument grouping\n\n            // There should be two logical groups, one for the first argument and one for the second argument\n            // Thus there should be two pairs per descriptor, and each pair should be distinct because it belongs to a different group\n\n            var descriptorGroupPairs = summary.BenchmarksCases.Select(benchmarkCase => (benchmarkCase.Descriptor, summary.GetLogicalGroupKey(benchmarkCase))).GroupBy(benchmarkCase => benchmarkCase.Descriptor);\n\n            Assert.True(\n                descriptorGroupPairs.All(group => group.Select(pair => pair.Item2).Distinct().Count() == 2)\n            );\n        }\n\n        public class ArrayOnDifferentMethods\n        {\n            public IEnumerable<int[]> GetArrays()\n            {\n                yield return new int[] { 1, 2, 3 };\n                yield return new int[] { 2, 3, 4 };\n            }\n\n            [Benchmark(Baseline = true)]\n            [ArgumentsSource(nameof(GetArrays))]\n            public void AcceptsArrays(int[] arr)\n            {\n                if (arr.Length != 3)\n                    throw new ArgumentException(\"Incorrect length\");\n            }\n\n            [Benchmark]\n            [ArgumentsSource(nameof(GetArrays))]\n            public void AcceptsArrays2(int[] arr)\n            {\n                if (arr.Length != 3)\n                    throw new ArgumentException(\"Incorrect length\");\n            }\n        }\n\n        [Theory, MemberData(nameof(GetToolchains), DisableDiscoveryEnumeration = true)]\n        public void MultidimensionalArraysAreProperlyDisplayed(IToolchain toolchain)\n        {\n            var summary = CanExecute<WithMultidimensionalArrayArgument>(toolchain);\n\n            Assert.Equal(\n                \"Int32[2, 3]\",\n                summary.Table.Columns.Where(col => col.Header == \"arr\").First().Content[0]\n            );\n        }\n\n        public class WithMultidimensionalArrayArgument\n        {\n            public IEnumerable<int[,]> GetArrays()\n            {\n                yield return new int[,] { { 1, 2, 3 }, { 4, 5, 6 } };\n            }\n\n            [Benchmark]\n            [ArgumentsSource(nameof(GetArrays))]\n            public void AcceptsMultidimensionalArray(int[,] arr)\n            {\n                if (arr.Length == 0)\n                    throw new ArgumentException(\"Incorrect length\");\n            }\n        }\n\n        [Theory, MemberData(nameof(GetToolchains), DisableDiscoveryEnumeration = true)]\n        public void MultidimensionalAndJaggedArraysCanBeMixed(IToolchain toolchain)\n        {\n            var summary = CanExecute<WithMixedJaggedAndMultidimensionalArrays>(toolchain);\n\n            Assert.Equal(\n                \"Int32[0, 0][][,][]\",\n                summary.Table.Columns.Where(col => col.Header == \"arr\").First().Content[0]\n            );\n        }\n\n        public class WithMixedJaggedAndMultidimensionalArrays\n        {\n            public IEnumerable<int[,][][,][]> GetArrays()\n            {\n                yield return new int[,][][,][] { };\n            }\n\n            [Benchmark]\n            [ArgumentsSource(nameof(GetArrays))]\n            public void AcceptsMixedArray(int[,][][,][] arr)\n            {\n                if (arr.Length > 0)\n                    throw new ArgumentException(\"Incorrect length\");\n            }\n        }\n\n        [Theory, MemberData(nameof(GetToolchains), DisableDiscoveryEnumeration = true)]\n        public void VeryBigIntegersAreSupported(IToolchain toolchain) => CanExecute<WithVeryBigInteger>(toolchain);\n\n        public class WithVeryBigInteger\n        {\n            public IEnumerable<object> GetVeryBigInteger()\n            {\n                yield return BigInteger.Parse(new string(Enumerable.Repeat('1', 1000).ToArray()));\n            }\n\n            [Benchmark]\n            [ArgumentsSource(nameof(GetVeryBigInteger))]\n            public void Method(BigInteger passed)\n            {\n                BigInteger expected = GetVeryBigInteger().OfType<BigInteger>().Single();\n\n                if (expected != passed)\n                    throw new ArgumentException(\"The BigInteger has wrong value!\");\n            }\n        }\n\n        [Theory, MemberData(nameof(GetToolchains), DisableDiscoveryEnumeration = true)]\n        public void SpecialDoubleValuesAreSupported(IToolchain toolchain) => CanExecute<WithSpecialDoubleValues>(toolchain);\n\n        public class WithSpecialDoubleValues\n        {\n            public IEnumerable<object[]> GetSpecialDoubleValues()\n            {\n                yield return new object[] { double.Epsilon, nameof(double.Epsilon) };\n                yield return new object[] { double.MinValue, nameof(double.MinValue) };\n                yield return new object[] { double.MaxValue, nameof(double.MaxValue) };\n                yield return new object[] { double.NaN, nameof(double.NaN) };\n                yield return new object[] { double.NegativeInfinity, nameof(double.NegativeInfinity) };\n                yield return new object[] { double.PositiveInfinity, nameof(double.PositiveInfinity) };\n            }\n\n            [Benchmark]\n            [ArgumentsSource(nameof(GetSpecialDoubleValues))]\n            public void Method(double passed, string name)\n            {\n                switch (name)\n                {\n                    case nameof(double.Epsilon):\n                        if (passed != double.Epsilon) throw new InvalidOperationException($\"Unable to pass {nameof(double.Epsilon)}\");\n                        break;\n                    case nameof(double.MaxValue):\n                        if (passed != double.MaxValue) throw new InvalidOperationException($\"Unable to pass {nameof(double.MaxValue)}\");\n                        break;\n                    case nameof(double.MinValue):\n                        if (passed != double.MinValue) throw new InvalidOperationException($\"Unable to pass {nameof(double.MinValue)}\");\n                        break;\n                    case nameof(double.NaN):\n                        if (!double.IsNaN(passed)) throw new InvalidOperationException($\"Unable to pass {nameof(double.NaN)}\");\n                        break;\n                    case nameof(double.PositiveInfinity):\n                        if (!double.IsPositiveInfinity(passed)) throw new InvalidOperationException($\"Unable to pass {nameof(double.PositiveInfinity)}\");\n                        break;\n                    case nameof(double.NegativeInfinity):\n                        if (!double.IsNegativeInfinity(passed)) throw new InvalidOperationException($\"Unable to pass {nameof(double.NegativeInfinity)}\");\n                        break;\n                    default:\n                        throw new InvalidOperationException($\"Unknown case! {name}\");\n                }\n            }\n        }\n\n        [Theory, MemberData(nameof(GetToolchains), DisableDiscoveryEnumeration = true)]\n        public void SpecialFloatValuesAreSupported(IToolchain toolchain) => CanExecute<WithSpecialFloatValues>(toolchain);\n\n        public class WithSpecialFloatValues\n        {\n            public IEnumerable<object[]> GetSpecialFloatValues()\n            {\n                yield return new object[] { float.Epsilon, nameof(float.Epsilon) };\n                yield return new object[] { float.MinValue, nameof(float.MinValue) };\n                yield return new object[] { float.MaxValue, nameof(float.MaxValue) };\n                yield return new object[] { float.NaN, nameof(float.NaN) };\n                yield return new object[] { float.NegativeInfinity, nameof(float.NegativeInfinity) };\n                yield return new object[] { float.PositiveInfinity, nameof(float.PositiveInfinity) };\n            }\n\n            [Benchmark]\n            [ArgumentsSource(nameof(GetSpecialFloatValues))]\n            public void Method(float passed, string name)\n            {\n                switch (name)\n                {\n                    case nameof(float.Epsilon):\n                        if (passed != float.Epsilon) throw new InvalidOperationException($\"Unable to pass {nameof(float.Epsilon)}\");\n                        break;\n                    case nameof(float.MaxValue):\n                        if (passed != float.MaxValue) throw new InvalidOperationException($\"Unable to pass {nameof(float.MaxValue)}\");\n                        break;\n                    case nameof(float.MinValue):\n                        if (passed != float.MinValue) throw new InvalidOperationException($\"Unable to pass {nameof(float.MinValue)}\");\n                        break;\n                    case nameof(float.NaN):\n                        if (!float.IsNaN(passed)) throw new InvalidOperationException($\"Unable to pass {nameof(float.NaN)}\");\n                        break;\n                    case nameof(float.PositiveInfinity):\n                        if (!float.IsPositiveInfinity(passed)) throw new InvalidOperationException($\"Unable to pass {nameof(float.PositiveInfinity)}\");\n                        break;\n                    case nameof(float.NegativeInfinity):\n                        if (!float.IsNegativeInfinity(passed)) throw new InvalidOperationException($\"Unable to pass {nameof(float.NegativeInfinity)}\");\n                        break;\n                    default:\n                        throw new InvalidOperationException($\"Unknown case! {name}\");\n                }\n            }\n        }\n\n        [Theory, MemberData(nameof(GetToolchains), DisableDiscoveryEnumeration = true)]\n        public void SpecialDecimalValuesAreSupported(IToolchain toolchain) => CanExecute<WithSpecialDecimalValues>(toolchain);\n\n        public class WithSpecialDecimalValues\n        {\n            public IEnumerable<object[]> GetSpecialDecimalValues()\n            {\n                yield return new object[] { decimal.MaxValue, nameof(decimal.MaxValue) };\n                yield return new object[] { decimal.MinValue, nameof(decimal.MinValue) };\n            }\n\n            [Benchmark]\n            [ArgumentsSource(nameof(GetSpecialDecimalValues))]\n            public void Method(decimal passed, string name)\n            {\n                switch (name)\n                {\n                    case nameof(decimal.MaxValue):\n                        if (passed != decimal.MaxValue) throw new InvalidOperationException($\"Unable to pass {nameof(decimal.MaxValue)}\");\n                        break;\n                    case nameof(decimal.MinValue):\n                        if (passed != decimal.MinValue) throw new InvalidOperationException($\"Unable to pass {nameof(decimal.MinValue)}\");\n                        break;\n                    default:\n                        throw new InvalidOperationException($\"Unknown case! {name}\");\n                }\n            }\n        }\n\n        [Theory, MemberData(nameof(GetToolchains), DisableDiscoveryEnumeration = true)]\n        public void DateTimeCanBeUsedAsArgument(IToolchain toolchain) => CanExecute<WithDateTime>(toolchain);\n\n        public class WithDateTime\n        {\n            public IEnumerable<object> DateTimeValues()\n            {\n                yield return new DateTime(2018, 8, 15);\n            }\n\n            [Benchmark]\n            [ArgumentsSource(nameof(DateTimeValues))]\n            public void Test(DateTime passed)\n            {\n                DateTime expected = DateTimeValues().OfType<DateTime>().Single();\n\n                if (expected != passed)\n                    throw new ArgumentException(\"The DateTime has wrong value!\");\n            }\n        }\n\n        [Theory, MemberData(nameof(GetToolchains), DisableDiscoveryEnumeration = true)]\n        public void CustomTypeThatAlsoExistsInTheSystemNamespaceAsArgument(IToolchain toolchain) => CanExecute<CustomTypeThatAlsoExistsInTheSystemNamespace>(toolchain);\n\n        public class CustomTypeThatAlsoExistsInTheSystemNamespace\n        {\n            public enum Action\n            {\n                It, Is, A, Duplicate, Of, System, Dot, Action\n            }\n\n            [Benchmark]\n            [Arguments(Action.System)]\n            public void Test(Action passed)\n            {\n                Action expected = Action.System;\n\n                if (expected != passed)\n                    throw new ArgumentException(\"The passed enum has wrong value!\");\n            }\n        }\n\n        [Theory, MemberData(nameof(GetToolchains), DisableDiscoveryEnumeration = true)]\n        public void EnumFlagsAreSupported(IToolchain toolchain) => CanExecute<WithEnumFlags>(toolchain);\n\n        public class WithEnumFlags\n        {\n            [Flags]\n            public enum LongFlagEnum : long\n            {\n                None = 0,\n                First = 1 << 0,\n                Second = 1 << 1,\n                Third = 1 << 2,\n                Fourth = 1 << 3\n            }\n\n            [Flags]\n            public enum ByteFlagEnum : byte\n            {\n                None = 0,\n                First = 1 << 0,\n                Second = 1 << 1,\n                Third = 1 << 2,\n                Fourth = 1 << 3\n            }\n\n            [Benchmark]\n            [Arguments(LongFlagEnum.First | LongFlagEnum.Second, ByteFlagEnum.Third | ByteFlagEnum.Fourth)]\n            public void Test(LongFlagEnum passedLongFlagEnum, ByteFlagEnum passedByteFlagEnum)\n            {\n                if ((LongFlagEnum.First | LongFlagEnum.Second) != passedLongFlagEnum)\n                    throw new ArgumentException(\"The passed long flag enum has wrong value!\");\n\n                if ((ByteFlagEnum.Third | ByteFlagEnum.Fourth) != passedByteFlagEnum)\n                    throw new ArgumentException(\"The passed byte flag enum has wrong value!\");\n            }\n        }\n\n        [Theory, MemberData(nameof(GetToolchains), DisableDiscoveryEnumeration = true)]\n        public void UndefinedEnumValuesAreSupported(IToolchain toolchain) => CanExecute<WithUndefinedEnumValue>(toolchain);\n\n        public class WithUndefinedEnumValue\n        {\n            [Flags]\n            public enum SomeEnum : long\n            {\n                First = 0, Last = 1\n            }\n\n            [Benchmark]\n            [Arguments(SomeEnum.First, (SomeEnum)100, (SomeEnum)(-100))]\n            public void Test(SomeEnum defined, SomeEnum undefined, SomeEnum undefinedNegative)\n            {\n                if (SomeEnum.First != defined)\n                    throw new ArgumentException(\"The passed defined enum has wrong value!\");\n\n                if ((SomeEnum)100 != undefined)\n                    throw new ArgumentException(\"The passed undefined enum has wrong value!\");\n\n                if ((SomeEnum)(-100) != undefinedNegative)\n                    throw new ArgumentException(\"The passed undefined negative enum has wrong value!\");\n            }\n        }\n\n        [Theory, MemberData(nameof(GetToolchains), DisableDiscoveryEnumeration = true)]\n        public void StaticMethodsAndPropertiesCanBeUsedAsSources_EnumerableOfObjects(IToolchain toolchain)\n            => CanExecute<WithStaticSources_EnumerableOfObjects>(toolchain);\n\n        public class WithStaticSources_EnumerableOfObjects\n        {\n            public static IEnumerable<object> StaticMethod() { yield return 1; }\n\n            public static IEnumerable<object> StaticProperty\n            {\n                get\n                {\n                    yield return 2;\n                    yield return 3;\n                }\n            }\n\n            [ParamsSource(nameof(StaticMethod))]\n            public int ParamOne { get; set; }\n\n            [ParamsSource(nameof(StaticProperty))]\n            public int ParamTwo { get; set; }\n\n            [Benchmark]\n            [ArgumentsSource(nameof(StaticMethod))]\n            public void TestMethod(int argument)\n            {\n                if (argument != 1)\n                    throw new ArgumentException(\"The argument value is incorrect!\");\n                if (ParamOne != 1)\n                    throw new ArgumentException(\"The ParamOne value is incorrect!\");\n                if (ParamTwo != 2 && ParamTwo != 3)\n                    throw new ArgumentException(\"The ParamTwo value is incorrect!\");\n            }\n\n            [Benchmark]\n            [ArgumentsSource(nameof(StaticProperty))]\n            public void TestProperty(int argument)\n            {\n                if (argument != 2 && argument != 3)\n                    throw new ArgumentException(\"The argument value is incorrect!\");\n                if (ParamOne != 1)\n                    throw new ArgumentException(\"The ParamOne value is incorrect!\");\n                if (ParamTwo != 2 && ParamTwo != 3)\n                    throw new ArgumentException(\"The ParamTwo value is incorrect!\");\n            }\n        }\n\n        [Theory, MemberData(nameof(GetToolchains), DisableDiscoveryEnumeration = true)]\n        public void StaticMethodsAndPropertiesCanBeUsedAsSources_EnumerableOfArrayOfObjects(IToolchain toolchain)\n            => CanExecute<WithStaticSources_EnumerableOfArrayOfObjects>(toolchain);\n\n        public class WithStaticSources_EnumerableOfArrayOfObjects\n        {\n            public static IEnumerable<object[]> StaticMethod() { yield return new object[] { 1 }; }\n            public static IEnumerable<object[]> StaticProperty\n            {\n                get\n                {\n                    yield return new object[] { 2 };\n                    yield return new object[] { 3 };\n                }\n            }\n\n            [ParamsSource(nameof(StaticMethod))]\n            public int ParamOne { get; set; }\n\n            [ParamsSource(nameof(StaticProperty))]\n            public int ParamTwo { get; set; }\n\n            [Benchmark]\n            [ArgumentsSource(nameof(StaticMethod))]\n            public void TestMethod(int argument)\n            {\n                if (argument != 1)\n                    throw new ArgumentException(\"The argument value is incorrect!\");\n                if (ParamOne != 1)\n                    throw new ArgumentException(\"The ParamOne value is incorrect!\");\n                if (ParamTwo != 2 && ParamTwo != 3)\n                    throw new ArgumentException(\"The ParamTwo value is incorrect!\");\n            }\n\n            [Benchmark]\n            [ArgumentsSource(nameof(StaticProperty))]\n            public void TestProperty(int argument)\n            {\n                if (argument != 2 && argument != 3)\n                    throw new ArgumentException(\"The argument value is incorrect!\");\n                if (ParamOne != 1)\n                    throw new ArgumentException(\"The ParamOne value is incorrect!\");\n                if (ParamTwo != 2 && ParamTwo != 3)\n                    throw new ArgumentException(\"The ParamTwo value is incorrect!\");\n            }\n        }\n\n        [Theory, MemberData(nameof(GetToolchains), DisableDiscoveryEnumeration = true)]\n        public void MethodsAndPropertiesFromAnotherClassCanBeUsedAsSources(IToolchain toolchain)\n            => CanExecute<ParamsSourcePointingToAnotherClass>(toolchain);\n\n        public class ParamsSourcePointingToAnotherClass\n        {\n            [ParamsSource(typeof(ExternalClassWithParamsSource), nameof(ExternalClassWithParamsSource.PrimitiveTypeMethod))]\n            public int ParamOne { get; set; }\n\n            [ParamsSource(typeof(ExternalClassWithParamsSource), nameof(ExternalClassWithParamsSource.PrimitiveTypeProperty))]\n            public int ParamTwo { get; set; }\n\n            [ParamsSource(typeof(ExternalClassWithParamsSource), nameof(ExternalClassWithParamsSource.NonPrimitiveTypeMethod))]\n            public required Version ParamThree { get; set; }\n\n            [ParamsSource(typeof(ExternalClassWithParamsSource), nameof(ExternalClassWithParamsSource.NonPrimitiveTypeProperty))]\n            public required Version ParamFour { get; set; }\n\n            [Benchmark]\n            public void Test()\n            {\n                if (ParamOne != 123)\n                    throw new ArgumentException(\"The ParamOne value is incorrect!\");\n                if (ParamTwo != 456)\n                    throw new ArgumentException(\"The ParamTwo value is incorrect!\");\n                if (ParamThree != new Version(1, 2, 3, 4))\n                    throw new ArgumentException(\"The ParamThree value is incorrect!\");\n                if (ParamFour != new Version(5, 6, 7, 8))\n                    throw new ArgumentException(\"The ParamFour value is incorrect!\");\n            }\n        }\n        public static class ExternalClassWithParamsSource\n        {\n            public static IEnumerable<int> PrimitiveTypeMethod()\n            {\n                yield return 123;\n            }\n            public static IEnumerable<int> PrimitiveTypeProperty\n            {\n                get\n                {\n                    yield return 456;\n                }\n            }\n            public static IEnumerable<Version> NonPrimitiveTypeMethod()\n            {\n                yield return new Version(1, 2, 3, 4);\n            }\n            public static IEnumerable<Version> NonPrimitiveTypeProperty\n            {\n                get\n                {\n                    yield return new Version(5, 6, 7, 8);\n                }\n            }\n        }\n\n        [Theory, MemberData(nameof(GetToolchains), DisableDiscoveryEnumeration = true)]\n        public void VeryLongStringsAreSupported(IToolchain toolchain) => CanExecute<WithVeryLongString>(toolchain);\n\n        public class WithVeryLongString\n        {\n            private readonly string LongString = new string('a', 200_000);\n            private readonly string LongString2 = new string('a', 200_000 - 1) + \"b\";\n\n            public IEnumerable<object[]> Arguments()\n            {\n                yield return new object[] { LongString, LongString2 };\n            }\n\n            [Benchmark]\n            [ArgumentsSource(nameof(Arguments))]\n            public void Test(string first, string second)\n            {\n                if (first != LongString)\n                    throw new ArgumentException($\"{nameof(first)} passed string has wrong value!\");\n                if (second != LongString2)\n                    throw new ArgumentException($\"{nameof(second)} passed string has wrong value!\");\n            }\n        }\n\n        [Theory, MemberData(nameof(GetToolchains), DisableDiscoveryEnumeration = true)]\n        public void ComplexStringPattersAreSupported(IToolchain toolchain) => CanExecute<Perf_Regex_Industry_RustLang_Sherlock>(toolchain);\n\n        public class Perf_Regex_Industry_RustLang_Sherlock\n        {\n            [Params(@\"[\"\"'][^\"\"']{0,30}[?!.][\"\"']\")]\n            public required string Pattern { get; set; }\n\n            [Benchmark]\n            public int Consume() => Pattern.Length;\n        }\n\n        [Fact]\n        public void UnusedDisposableParamsAreDisposed() => CanExecute<WithDisposableArguments>(Job.Default.GetToolchain());\n\n        public class WithDisposableArguments\n        {\n            public IEnumerable<Disposable> GetDisposables()\n            {\n                yield return new Disposable(0);\n                yield return new Disposable(1);\n            }\n\n            [ParamsSource(nameof(GetDisposables))]\n            public required Disposable used;\n\n            [Benchmark]\n            public void CheckDisposed()\n            {\n                if (used.Id == 0)\n                {\n                    if (Disposable.Created != 1)\n                        throw new ArgumentException(\"Only one instance should be created so far!\");\n                    if (Disposable.Disposed != 0)\n                        throw new ArgumentException(\"None should be disposed as only one was created and is still in use\");\n                }\n                if (used.Id == 1)\n                {\n                    if (Disposable.Created != 2)\n                        throw new ArgumentException(\"Two instances should be created so far!\");\n                    if (Disposable.Disposed != 1)\n                        throw new ArgumentException(\"The first one should be disposed as it's not used\");\n                }\n            }\n\n            public class Disposable : IDisposable\n            {\n                public static int Created = 0;\n                public static int Disposed = 0;\n\n                public int Id { get; private set; }\n\n                public Disposable(int id)\n                {\n                    Id = id;\n                    ++Created;\n                }\n\n                public void Dispose() => ++Disposed;\n            }\n        }\n\n        private Reports.Summary CanExecute<T>(IToolchain toolchain, Func<IConfig, IConfig>? furtherConfigure = null)\n        {\n            var config = CreateSimpleConfig(job: Job.Dry.WithToolchain(toolchain));\n\n            if (furtherConfigure is not null)\n            {\n                config = furtherConfigure(config);\n            }\n\n            return CanExecute<T>(config);\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/AssemblyConfigTests.cs",
    "content": "﻿using BenchmarkDotNet.IntegrationTests.ConfigPerAssembly;\nusing Xunit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.IntegrationTests\n{\n    public class AssemblyConfigTests : BenchmarkTestExecutor\n    {\n        public AssemblyConfigTests(ITestOutputHelper output) : base(output) { }\n\n        [Fact]\n        public void ConfigCanBeSetPerAssembly()\n        {\n            CanExecute<AssemblyConfigBenchmarks>();\n\n            Assert.True(AssemblyConfigAttribute.IsActivated);\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/AsyncBenchmarksTests.cs",
    "content": "﻿using System;\nusing System.Threading.Tasks;\nusing System.Threading.Tasks.Sources;\nusing BenchmarkDotNet.Attributes;\nusing Xunit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.IntegrationTests\n{\n    internal class ValueTaskSource<T> : IValueTaskSource<T>, IValueTaskSource\n    {\n        private ManualResetValueTaskSourceCore<T> _core;\n\n        T IValueTaskSource<T>.GetResult(short token) => _core.GetResult(token);\n        void IValueTaskSource.GetResult(short token) => _core.GetResult(token);\n        ValueTaskSourceStatus IValueTaskSource<T>.GetStatus(short token) => _core.GetStatus(token);\n        ValueTaskSourceStatus IValueTaskSource.GetStatus(short token) => _core.GetStatus(token);\n        void IValueTaskSource<T>.OnCompleted(Action<object?> continuation, object? state, short token, ValueTaskSourceOnCompletedFlags flags) => _core.OnCompleted(continuation, state, token, flags);\n        void IValueTaskSource.OnCompleted(Action<object?> continuation, object? state, short token, ValueTaskSourceOnCompletedFlags flags) => _core.OnCompleted(continuation, state, token, flags);\n        public void Reset() => _core.Reset();\n        public short Token => _core.Version;\n        public void SetResult(T result) => _core.SetResult(result);\n    }\n\n    // This is used to test the case of ValueTaskAwaiter.IsCompleted returns false, then OnCompleted invokes the callback immediately because it happened to complete between the 2 calls.\n    internal class ValueTaskSourceCallbackOnly<T> : IValueTaskSource<T>, IValueTaskSource\n    {\n        private ManualResetValueTaskSourceCore<T> _core;\n\n        T IValueTaskSource<T>.GetResult(short token) => _core.GetResult(token);\n        void IValueTaskSource.GetResult(short token) => _core.GetResult(token);\n        // Always return pending state so OnCompleted will be called.\n        ValueTaskSourceStatus IValueTaskSource<T>.GetStatus(short token) => ValueTaskSourceStatus.Pending;\n        ValueTaskSourceStatus IValueTaskSource.GetStatus(short token) => ValueTaskSourceStatus.Pending;\n        void IValueTaskSource<T>.OnCompleted(Action<object?> continuation, object? state, short token, ValueTaskSourceOnCompletedFlags flags) => _core.OnCompleted(continuation, state, token, flags);\n        void IValueTaskSource.OnCompleted(Action<object?> continuation, object? state, short token, ValueTaskSourceOnCompletedFlags flags) => _core.OnCompleted(continuation, state, token, flags);\n        public void Reset() => _core.Reset();\n        public short Token => _core.Version;\n        public void SetResult(T result) => _core.SetResult(result);\n    }\n\n    public class AsyncBenchmarksTests : BenchmarkTestExecutor\n    {\n        public AsyncBenchmarksTests(ITestOutputHelper output) : base(output) { }\n\n        [Fact]\n        public void TaskReturningMethodsAreAwaited()\n        {\n            var summary = CanExecute<TaskDelayMethods>();\n\n            foreach (var report in summary.Reports)\n                foreach (var measurement in report.AllMeasurements)\n                {\n                    double actual = measurement.Nanoseconds;\n                    const double minExpected = TaskDelayMethods.NanosecondsDelay - TaskDelayMethods.MaxTaskDelayResolutionInNanoseconds;\n                    string name = report.BenchmarkCase.Descriptor.GetFilterName();\n                    Assert.True(actual > minExpected, $\"{name} has not been awaited, took {actual}ns, while it should take more than {minExpected}ns\");\n                }\n        }\n\n        [Fact]\n        public void TaskReturningMethodsAreAwaited_AlreadyComplete() => CanExecute<TaskImmediateMethods>();\n\n        public class TaskDelayMethods\n        {\n            private readonly ValueTaskSource<int> valueTaskSource = new();\n\n            private const int MillisecondsDelay = 100;\n\n            internal const double NanosecondsDelay = MillisecondsDelay * 1e+6;\n\n            // The default frequency of the Windows System Timer is 64Hz, so the Task.Delay error is up to 15.625ms.\n            internal const int MaxTaskDelayResolutionInNanoseconds = 1_000_000_000 / 64;\n\n            [Benchmark]\n            public Task ReturningTask() => Task.Delay(MillisecondsDelay);\n\n            [Benchmark]\n            public ValueTask ReturningValueTask() => new ValueTask(Task.Delay(MillisecondsDelay));\n\n            [Benchmark]\n            public ValueTask ReturningValueTaskBackByIValueTaskSource()\n            {\n                valueTaskSource.Reset();\n                Task.Delay(MillisecondsDelay).ContinueWith(_ =>\n                {\n                    valueTaskSource.SetResult(default);\n                });\n                return new ValueTask(valueTaskSource, valueTaskSource.Token);\n            }\n\n            [Benchmark]\n            public async Task Awaiting() => await Task.Delay(MillisecondsDelay);\n\n            [Benchmark]\n            public Task<int> ReturningGenericTask() => ReturningTask().ContinueWith(_ => default(int));\n\n            [Benchmark]\n            public ValueTask<int> ReturningGenericValueTask() => new ValueTask<int>(ReturningGenericTask());\n\n            [Benchmark]\n            public ValueTask<int> ReturningGenericValueTaskBackByIValueTaskSource()\n            {\n                valueTaskSource.Reset();\n                Task.Delay(MillisecondsDelay).ContinueWith(_ =>\n                {\n                    valueTaskSource.SetResult(default);\n                });\n                return new ValueTask<int>(valueTaskSource, valueTaskSource.Token);\n            }\n        }\n\n        public class TaskImmediateMethods\n        {\n            private readonly ValueTaskSource<int> valueTaskSource = new();\n            private readonly ValueTaskSourceCallbackOnly<int> valueTaskSourceCallbackOnly = new();\n\n            [Benchmark]\n            public Task ReturningTask() => Task.CompletedTask;\n\n            [Benchmark]\n            public ValueTask ReturningValueTask() => new ValueTask();\n\n            [Benchmark]\n            public ValueTask ReturningValueTaskBackByIValueTaskSource()\n            {\n                valueTaskSource.Reset();\n                valueTaskSource.SetResult(default);\n                return new ValueTask(valueTaskSource, valueTaskSource.Token);\n            }\n\n            [Benchmark]\n            public ValueTask ReturningValueTaskBackByIValueTaskSource_ImmediateCallback()\n            {\n                valueTaskSourceCallbackOnly.Reset();\n                valueTaskSourceCallbackOnly.SetResult(default);\n                return new ValueTask(valueTaskSourceCallbackOnly, valueTaskSourceCallbackOnly.Token);\n            }\n\n            [Benchmark]\n            public async Task Awaiting() => await Task.CompletedTask;\n\n            [Benchmark]\n            public Task<int> ReturningGenericTask() => ReturningTask().ContinueWith(_ => default(int));\n\n            [Benchmark]\n            public ValueTask<int> ReturningGenericValueTask() => new ValueTask<int>(ReturningGenericTask());\n\n            [Benchmark]\n            public ValueTask<int> ReturningGenericValueTaskBackByIValueTaskSource()\n            {\n                valueTaskSource.Reset();\n                valueTaskSource.SetResult(default);\n                return new ValueTask<int>(valueTaskSource, valueTaskSource.Token);\n            }\n\n            [Benchmark]\n            public ValueTask<int> ReturningGenericValueTaskBackByIValueTaskSource_ImmediateCallback()\n            {\n                valueTaskSourceCallbackOnly.Reset();\n                valueTaskSourceCallbackOnly.SetResult(default);\n                return new ValueTask<int>(valueTaskSourceCallbackOnly, valueTaskSourceCallbackOnly.Token);\n            }\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/AttributesTests.cs",
    "content": "﻿using System;\nusing BenchmarkDotNet.Attributes;\nusing Xunit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.IntegrationTests\n{\n    public class AttributesTests : BenchmarkTestExecutor\n    {\n        public AttributesTests(ITestOutputHelper output) : base(output) { }\n\n        [Fact]\n        public void AttributesAreNotSealed()\n        {\n            CanExecute<ConsumingCustomAttributes>();\n        }\n\n        public class ConsumingCustomAttributes\n        {\n            private const int ExpectedNumber = 123;\n            private const string ExpectedText = \"expectedTest\";\n\n            [CustomParams(ExpectedNumber)]\n            public int Number;\n\n            public required string Text;\n\n            [CustomGlobalSetup]\n            public void Setup()\n            {\n                Text = ExpectedText;\n            }\n\n            [CustomBenchmark]\n            public void Benchmark()\n            {\n                if (ExpectedNumber != Number || ExpectedText != Text)\n                    throw new Exception(\"Custom attributes were not applied!\");\n            }\n        }\n\n        private class CustomParamsAttribute : ParamsAttribute\n        {\n            public CustomParamsAttribute(params object[] values) : base(values) { }\n        }\n\n        private class CustomBenchmarkAttribute : BenchmarkAttribute { }\n\n        private class CustomGlobalSetupAttribute : GlobalSetupAttribute { }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/BaselineRatioColumnTest.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing System.Threading;\nusing Xunit;\nusing BenchmarkDotNet.Reports;\nusing System.Collections.Generic;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Columns;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Exporters;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.IntegrationTests\n{\n    public class BaselineRatioColumnTest : BenchmarkTestExecutor\n    {\n        public BaselineRatioColumnTest(ITestOutputHelper output) : base(output) { }\n\n        [Fact]\n        public void ColumnsWithBaselineGetsRatio()\n        {\n            // This is the common way to run benchmarks, it should wire up the BenchmarkBaselineDeltaResultExtender for us\n            // BenchmarkTestExecutor.CanExecute(..) calls BenchmarkRunner.Run(..) under the hood\n            var summary = CanExecute<BaselineRatioColumnBenchmarks>();\n\n            var table = summary.Table;\n            var headerRow = table.FullHeader;\n            var column = summary.GetColumns()\n                .OfType<BaselineRatioColumn>()\n                .FirstOrDefault(c => c.Metric == BaselineRatioColumn.RatioMetric.Mean);\n            Assert.NotNull(column);\n\n            Assert.Equal(column.ColumnName, headerRow.Last());\n            var testNameColumn = Array.FindIndex(headerRow, c => c == \"Method\");\n            var extraColumn = Array.FindIndex(headerRow, c => c == column.ColumnName);\n            foreach (var row in table.FullContent)\n            {\n                Assert.Equal(row.Length, extraColumn + 1);\n                if (row[testNameColumn] == \"BenchmarkSlow\") // This is our baseline\n                    Assert.Equal(\"1.00\", row[extraColumn]);\n                else if (row[testNameColumn] == \"BenchmarkFast\") // This should have been compared to the baseline\n                    Assert.Contains(\".\", row[extraColumn]);\n            }\n        }\n\n        public class BaselineRatioColumnBenchmarks\n        {\n            [Params(1, 2)]\n            public int ParamProperty { get; set; }\n\n            [Benchmark(Baseline = true)]\n            public void BenchmarkSlow() => Thread.Sleep(20);\n\n            [Benchmark]\n            public void BenchmarkFast() => Thread.Sleep(5);\n        }\n    }\n\n    public class BaselineRatioResultExtenderNoBaselineTest : BenchmarkTestExecutor\n    {\n        public BaselineRatioResultExtenderNoBaselineTest(ITestOutputHelper output) : base(output) { }\n\n        [Fact]\n        public void Test()\n        {\n            var testExporter = new TestExporter();\n            var config = CreateSimpleConfig().AddExporter(testExporter);\n\n            CanExecute<BaselineRatioResultExtenderNoBaseline>(config);\n\n            // Ensure that when the TestBenchmarkExporter() was run, it wasn't passed an instance of \"BenchmarkBaselineDeltaResultExtender\"\n            Assert.False(testExporter.ExportCalled);\n            Assert.True(testExporter.ExportToFileCalled);\n        }\n\n        public class BaselineRatioResultExtenderNoBaseline\n        {\n            [Benchmark]\n            public void BenchmarkSlow() => Thread.Sleep(50);\n\n            [Benchmark]\n            public void BenchmarkFast() => Thread.Sleep(10);\n        }\n\n        public class TestExporter : IExporter\n        {\n            public bool ExportCalled { get; private set; }\n\n            public bool ExportToFileCalled { get; private set; }\n\n            public string Description => \"For Testing Only!\";\n\n            public string Name => \"TestBenchmarkExporter\";\n\n            public void ExportToLog(Summary summary, BenchmarkDotNet.Loggers.ILogger logger) => ExportCalled = true;\n\n            public IEnumerable<string> ExportToFiles(Summary summary, BenchmarkDotNet.Loggers.ILogger consoleLogger)\n            {\n                ExportToFileCalled = true;\n                return [];\n            }\n        }\n    }\n\n    public class BaselineRatioResultExtenderErrorTest : BenchmarkTestExecutor\n    {\n        public BaselineRatioResultExtenderErrorTest(ITestOutputHelper output) : base(output) { }\n\n        [Fact]\n        public void OnlyOneMethodCanBeBaseline()\n        {\n            var summary = CanExecute<BaselineRatioResultExtenderError>(fullValidation: false);\n\n            // You can't have more than 1 method in a class with [Benchmark(Baseline = true)]\n            Assert.True(summary.HasCriticalValidationErrors);\n        }\n\n#pragma warning disable BDN1107\n        public class BaselineRatioResultExtenderError\n        {\n            [Benchmark(Baseline = true)]\n            public void BenchmarkSlow() => Thread.Sleep(50);\n\n            [Benchmark(Baseline = true)]\n            public void BenchmarkFast() => Thread.Sleep(5);\n        }\n#pragma warning restore BDN1107\n    }\n\n    public class BaselineRatioColumnWithLongParamsTest : BenchmarkTestExecutor\n    {\n        public BaselineRatioColumnWithLongParamsTest(ITestOutputHelper output) : base(output) { }\n\n        [Fact]\n        public void ColumnsWithBaselineGetsRatio()\n        {\n            var summary = CanExecute<BaselineRatioColumnWithLongParams>(fullValidation: false);\n\n            // Ensure that Params attribute values will not affect Baseline property\n            Assert.False(summary.HasCriticalValidationErrors);\n        }\n\n        public class BaselineRatioColumnWithLongParams\n        {\n            // Long different parameters with equal length but different values\n            [Params(\"12345ThisIsALongParameter54321\", \"12345ThisIsARongParameter54321\")]\n            public required string LongStringParamProperty { get; set; }\n\n            [Benchmark(Baseline = true)]\n            public void BenchmarkSlow() => Thread.Sleep(20);\n\n            [Benchmark]\n            public void BenchmarkFast() => Thread.Sleep(5);\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/BenchmarkDotNet.IntegrationTests.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\n  <Import Project=\"..\\..\\build\\common.props\" />\n  <PropertyGroup>\n    <AssemblyTitle>BenchmarkDotNet.IntegrationTests</AssemblyTitle>\n    <TargetFrameworks Condition=\"'$(OS)' == 'Windows_NT'\">net462;net8.0</TargetFrameworks>\n    <TargetFramework Condition=\"'$(OS)' != 'Windows_NT'\">net8.0</TargetFramework>\n    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>\n    <AssemblyName>BenchmarkDotNet.IntegrationTests</AssemblyName>\n    <PackageId>BenchmarkDotNet.IntegrationTests</PackageId>\n    <GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>\n    <GenerateDocumentationFile>false</GenerateDocumentationFile>\n    <PlatformTarget>AnyCPU</PlatformTarget>\n    <DebugSymbols>true</DebugSymbols>\n    <NoWarn>$(NoWarn);CA2007;CA1825</NoWarn>\n    <ServerGarbageCollection>true</ServerGarbageCollection>\n  </PropertyGroup>\n  <ItemGroup>\n    <Content Include=\"xunit.runner.json\">\n      <CopyToOutputDirectory>Always</CopyToOutputDirectory>\n    </Content>\n    <None Include=\"wwwroot\\**\" CopyToOutputDirectory=\"PreserveNewest\" />\n    <!-- Disable EventSource to stabilize MemoryDiagnoserTests. https://github.com/dotnet/BenchmarkDotNet/pull/2562#issuecomment-2081317379 -->\n    <RuntimeHostConfigurationOption Include=\"System.Diagnostics.Tracing.EventSource.IsSupported\" Value=\"false\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ProjectReference Include=\"..\\BenchmarkDotNet.IntegrationTests.ConfigPerAssembly\\BenchmarkDotNet.IntegrationTests.ConfigPerAssembly.csproj\" />\n    <ProjectReference Include=\"..\\BenchmarkDotNet.IntegrationTests.DisabledOptimizations\\BenchmarkDotNet.IntegrationTests.DisabledOptimizations.csproj\" />\n    <ProjectReference Include=\"..\\BenchmarkDotNet.IntegrationTests.EnabledOptimizations\\BenchmarkDotNet.IntegrationTests.EnabledOptimizations.csproj\" />\n    <ProjectReference Include=\"..\\BenchmarkDotNet.IntegrationTests.FSharp\\BenchmarkDotNet.IntegrationTests.FSharp.fsproj\" />\n    <ProjectReference Include=\"..\\BenchmarkDotNet.IntegrationTests.VisualBasic\\BenchmarkDotNet.IntegrationTests.VisualBasic.vbproj\" />\n    <ProjectReference Include=\"..\\BenchmarkDotNet.IntegrationTests.Static\\BenchmarkDotNet.IntegrationTests.Static.csproj\" />\n    <ProjectReference Include=\"..\\BenchmarkDotNet.Tests\\BenchmarkDotNet.Tests.csproj\" />\n    <ProjectReference Include=\"..\\..\\src\\BenchmarkDotNet\\BenchmarkDotNet.csproj\" />\n  </ItemGroup>\n  <ItemGroup>\n    <PackageReference Include=\"Microsoft.NET.Test.Sdk\" Version=\"18.0.1\" />\n  </ItemGroup>\n  <ItemGroup>\n    <PackageReference Include=\"xunit\" Version=\"2.9.3\" />\n    <PackageReference Include=\"xunit.runner.visualstudio\" Version=\"[2.8.2]\">\n      <PrivateAssets>all</PrivateAssets>\n      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\n    </PackageReference>\n    <PackageReference Include=\"Mono.Cecil\" Version=\"0.11.6\" />\n  </ItemGroup>\n  <ItemGroup Condition=\" '$(TargetFrameworkIdentifier)' == '.NETCoreApp' \">\n    <PackageReference Include=\"System.Configuration.ConfigurationManager\" Version=\"10.0.3\" />\n  </ItemGroup>\n  <ItemGroup Condition=\" '$(TargetFrameworkIdentifier)' == '.NETFramework' \">\n    <ProjectReference Include=\"..\\..\\src\\BenchmarkDotNet.Diagnostics.Windows\\BenchmarkDotNet.Diagnostics.Windows.csproj\" />\n    <ProjectReference Include=\"..\\BenchmarkDotNet.IntegrationTests.CustomPaths\\BenchmarkDotNet.IntegrationTests.CustomPaths.csproj\" />\n    <PackageReference Include=\"Microsoft.NETCore.Platforms\" Version=\"7.0.4\" />\n    <PackageReference Include=\"System.Runtime.CompilerServices.Unsafe\" Version=\"6.1.2\" />\n    <Reference Include=\"System.Configuration\" />\n    <Reference Include=\"System.Runtime\" />\n    <Reference Include=\"System.Threading.Tasks\" />\n    <Reference Include=\"WindowsBase\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"App.config\" />\n  </ItemGroup>\n  <ItemGroup>\n    <Service Include=\"{508349b6-6b84-4df5-91f0-309beebad82d}\" />\n    <Service Include=\"{82a7f48d-3b50-4b1e-b82e-3ada8210c358}\" />\n  </ItemGroup>\n  <ItemGroup>\n    <Compile Update=\"InProcess.EmitTests.T4\\RunnableClassCaseBenchmark.cs\">\n      <DesignTime>True</DesignTime>\n      <AutoGen>True</AutoGen>\n      <DependentUpon>RunnableClassCaseBenchmark.tt</DependentUpon>\n    </Compile>\n    <Compile Update=\"InProcess.EmitTests.T4\\RunnableManyArgsCaseBenchmark.cs\">\n      <DesignTime>True</DesignTime>\n      <AutoGen>True</AutoGen>\n      <DependentUpon>RunnableManyArgsCaseBenchmark.tt</DependentUpon>\n    </Compile>\n    <Compile Update=\"InProcess.EmitTests.T4\\RunnableRefStructCaseBenchmark.cs\">\n      <DesignTime>True</DesignTime>\n      <AutoGen>True</AutoGen>\n      <DependentUpon>RunnableRefStructCaseBenchmark.tt</DependentUpon>\n    </Compile>\n    <Compile Update=\"InProcess.EmitTests.T4\\RunnableStructCaseBenchmark.cs\">\n      <DesignTime>True</DesignTime>\n      <AutoGen>True</AutoGen>\n      <DependentUpon>RunnableStructCaseBenchmark.tt</DependentUpon>\n    </Compile>\n    <Compile Update=\"InProcess.EmitTests.T4\\RunnableTaskCaseBenchmark.cs\">\n      <DesignTime>True</DesignTime>\n      <AutoGen>True</AutoGen>\n      <DependentUpon>RunnableTaskCaseBenchmark.tt</DependentUpon>\n    </Compile>\n    <Compile Update=\"InProcess.EmitTests.T4\\RunnableVoidCaseBenchmark.cs\">\n      <DesignTime>True</DesignTime>\n      <AutoGen>True</AutoGen>\n      <DependentUpon>RunnableVoidCaseBenchmark.tt</DependentUpon>\n    </Compile>\n  </ItemGroup>\n  <ItemGroup>\n    <None Update=\"InProcess.EmitTests.T4\\RunnableClassCaseBenchmark.tt\">\n      <Generator>TextTemplatingFileGenerator</Generator>\n      <LastGenOutput>RunnableClassCaseBenchmark.cs</LastGenOutput>\n    </None>\n    <None Update=\"InProcess.EmitTests.T4\\RunnableManyArgsCaseBenchmark.tt\">\n      <Generator>TextTemplatingFileGenerator</Generator>\n      <LastGenOutput>RunnableManyArgsCaseBenchmark.cs</LastGenOutput>\n    </None>\n    <None Update=\"InProcess.EmitTests.T4\\RunnableRefStructCaseBenchmark.tt\">\n      <LastGenOutput>RunnableRefStructCaseBenchmark.cs</LastGenOutput>\n      <Generator>TextTemplatingFileGenerator</Generator>\n    </None>\n    <None Update=\"InProcess.EmitTests.T4\\RunnableStructCaseBenchmark.tt\">\n      <Generator>TextTemplatingFileGenerator</Generator>\n      <LastGenOutput>RunnableStructCaseBenchmark.cs</LastGenOutput>\n    </None>\n    <None Update=\"InProcess.EmitTests.T4\\RunnableTaskCaseBenchmark.tt\">\n      <Generator>TextTemplatingFileGenerator</Generator>\n      <LastGenOutput>RunnableTaskCaseBenchmark.cs</LastGenOutput>\n    </None>\n    <None Update=\"InProcess.EmitTests.T4\\RunnableVoidCaseBenchmark.tt\">\n      <Generator>TextTemplatingFileGenerator</Generator>\n      <LastGenOutput>RunnableVoidCaseBenchmark.cs</LastGenOutput>\n    </None>\n  </ItemGroup>\n  <Import Project=\"..\\..\\build\\common.targets\" />\n</Project>"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/BenchmarkSwitcherTest.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Running;\nusing System.Linq;\nusing Xunit;\nusing BenchmarkDotNet.Exporters;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Tests.Loggers;\nusing BenchmarkDotNet.Tests.XUnit;\nusing Xunit.Abstractions;\nusing System.IO;\n\nnamespace BenchmarkDotNet.IntegrationTests\n{\n    public class BenchmarkSwitcherTest\n    {\n        internal const string TestCategory = \"TestCategory\";\n\n        private ITestOutputHelper Output { get; }\n\n        public BenchmarkSwitcherTest(ITestOutputHelper output) => Output = output;\n\n        [FactEnvSpecific(\n            \"When CommandLineParser wants to display help, it tries to get the Title of the Entry Assembly which is an xunit runner, which has no Title and fails..\",\n            EnvRequirement.DotNetCoreOnly)]\n        public void WhenInvalidCommandLineArgumentIsPassedAnErrorMessageIsDisplayedAndNoBenchmarksAreExecuted()\n        {\n            var logger = new OutputLogger(Output);\n            var config = ManualConfig.CreateEmpty().AddLogger(logger);\n\n            var summaries = BenchmarkSwitcher\n                .FromTypes([])\n                .Run([\"--DOES_NOT_EXIST\"], config);\n\n            Assert.Empty(summaries);\n            Assert.Contains(\"Option 'DOES_NOT_EXIST' is unknown.\", logger.GetLog());\n        }\n\n        [Fact]\n        public void WhenUserAsksForInfoAnInfoIsDisplayedAndNoBenchmarksAreExecuted()\n        {\n            var logger = new OutputLogger(Output);\n            var config = ManualConfig.CreateEmpty().AddLogger(logger);\n\n            var summaries = BenchmarkSwitcher\n                .FromTypes([])\n                .Run([\"--info\"], config);\n\n            Assert.Empty(summaries);\n            Assert.Contains(HostEnvironmentInfo.GetInformation(), logger.GetLog());\n        }\n\n        [Fact]\n        public void WhenInvalidTypeIsProvidedAnErrorMessageIsDisplayedAndNoBenchmarksAreExecuted()\n        {\n            var logger = new OutputLogger(Output);\n            var config = ManualConfig.CreateEmpty().AddLogger(logger);\n\n            var summaries = BenchmarkSwitcher\n                .FromTypes([typeof(ClassC)])\n                .Run([\"--filter\", \"*\"], config);\n\n            Assert.Empty(summaries);\n            Assert.Contains(GetValidationErrorForType(typeof(ClassC)), logger.GetLog());\n        }\n\n        [Fact]\n        public void WhenNoTypesAreProvidedAnErrorMessageIsDisplayedAndNoBenchmarksAreExecuted()\n        {\n            var logger = new OutputLogger(Output);\n            var config = ManualConfig.CreateEmpty().AddLogger(logger);\n\n            var summaries = BenchmarkSwitcher\n                .FromTypes([])\n                .Run([\"--filter\", \"*\"], config);\n\n            Assert.Empty(summaries);\n            Assert.Contains(\"No benchmarks were found.\", logger.GetLog());\n        }\n\n        [Fact]\n        public void WhenFilterReturnsNothingAnErrorMessageIsDisplayedAndNoBenchmarksAreExecuted()\n        {\n            var logger = new OutputLogger(Output);\n            var config = ManualConfig.CreateEmpty().AddLogger(logger);\n\n            const string filter = \"WRONG\";\n            var summaries = BenchmarkSwitcher\n                .FromTypes([typeof(ClassA), typeof(ClassB)])\n                .Run([\"--filter\", filter], config);\n\n            Assert.Empty(summaries);\n            Assert.Contains($\"The filter '{filter}' that you have provided returned 0 benchmarks.\", logger.GetLog());\n        }\n\n        [Fact]\n        public void WhenUserAsksToPrintAListWePrintIt()\n        {\n            var logger = new OutputLogger(Output);\n            var config = ManualConfig.CreateEmpty().AddLogger(logger);\n\n            var summaries = BenchmarkSwitcher\n                .FromTypes([typeof(ClassA)])\n                .Run([\"--list\", \"flat\"], config);\n\n            Assert.Empty(summaries);\n            Assert.Contains(\"BenchmarkDotNet.IntegrationTests.ClassA.Method1\", logger.GetLog());\n            Assert.Contains(\"BenchmarkDotNet.IntegrationTests.ClassA.Method2\", logger.GetLog());\n        }\n\n        [Fact]\n        public void WhenUserAsksToPrintAListAndProvidesAFilterWePrintFilteredList()\n        {\n            var logger = new OutputLogger(Output);\n            var config = ManualConfig.CreateEmpty().AddLogger(logger);\n\n            var summaries = BenchmarkSwitcher\n                .FromTypes([typeof(ClassA)])\n                .Run([\"--list\", \"flat\", \"--filter\", \"*.Method1\"], config);\n\n            Assert.Empty(summaries);\n            Assert.Contains(\"BenchmarkDotNet.IntegrationTests.ClassA.Method1\", logger.GetLog());\n            Assert.DoesNotContain(\"BenchmarkDotNet.IntegrationTests.ClassA.Method2\", logger.GetLog());\n        }\n\n\n        [Fact]\n        public void WhenDisableLogFileWeDontWriteToFile()\n        {\n            var logger = new OutputLogger(Output);\n            var config = ManualConfig.CreateEmpty().AddLogger(logger).WithOptions(ConfigOptions.DisableLogFile).AddJob(Job.Dry);\n\n            string? logFilePath = null;\n            try\n            {\n                var summaries = BenchmarkSwitcher\n                    .FromTypes([typeof(ClassA)])\n                    .RunAll(config);\n\n                var summary = summaries.Single();\n                logFilePath = summary.LogFilePath;\n                Assert.False(File.Exists(logFilePath), $\"Logfile '{logFilePath}' should not exist, but it does.\");\n            }\n            finally\n            {\n                if (!string.IsNullOrWhiteSpace(logFilePath))\n                {\n                    File.Delete(logFilePath);\n                }\n            }\n        }\n\n        [Fact]\n        public void EnsureLogFileIsWritten()\n        {\n            var logger = new OutputLogger(Output);\n            var config = ManualConfig.CreateEmpty().AddLogger(logger).AddJob(Job.Dry);\n\n            string? logFilePath = null;\n            try\n            {\n                var summaries = BenchmarkSwitcher\n                    .FromTypes([typeof(ClassA)])\n                    .RunAll(config);\n\n                var summary = summaries.Single();\n                logFilePath = summary.LogFilePath;\n                Assert.True(File.Exists(logFilePath), $\"Logfile '{logFilePath}' should exist, but it does not.\");\n            }\n            finally\n            {\n                if (!string.IsNullOrWhiteSpace(logFilePath))\n                {\n                    File.Delete(logFilePath);\n                }\n            }\n        }\n\n        [Fact]\n        public void WhenUserDoesNotProvideFilterOrCategoriesViaCommandLineWeAskToChooseBenchmark()\n        {\n            var logger = new OutputLogger(Output);\n            var config = ManualConfig.CreateEmpty().AddLogger(logger);\n            var userInteractionMock = new UserInteractionMock(returnValue: []);\n\n            var summaries = new BenchmarkSwitcher(userInteractionMock)\n                .With([typeof(WithDryAttributeAndCategory)])\n                .Run([], config);\n\n            Assert.Empty(summaries); // summaries is empty because the returnValue configured for mock returns 0 types\n            Assert.Equal(1, userInteractionMock.AskUserCalledTimes);\n        }\n\n        [Theory]\n        [InlineData(\"--allCategories\")]\n        [InlineData(\"--anyCategories\")]\n        public void WhenUserProvidesCategoriesWithoutFiltersWeDontAskToChooseBenchmarkJustRunGivenCategories(string categoriesConsoleLineArgument)\n        {\n            var logger = new OutputLogger(Output);\n            var config = ManualConfig.CreateEmpty().AddLogger(logger);\n            var types = new[] { typeof(WithDryAttributeAndCategory) };\n            var userInteractionMock = new UserInteractionMock(returnValue: types);\n\n            var summaries = new BenchmarkSwitcher(userInteractionMock)\n                .With(types)\n                .Run([categoriesConsoleLineArgument, TestCategory], config);\n\n            Assert.Single(summaries);\n            Assert.Equal(0, userInteractionMock.AskUserCalledTimes);\n        }\n\n        [Theory]\n        [InlineData(\"--allCategories\")]\n        [InlineData(\"--anyCategories\")]\n        public void WhenUserProvidesCategoriesWithFiltersWeDontAskToChooseBenchmarkJustUseCombinedFilterAndRunTheBenchmarks(string categoriesConsoleLineArgument)\n        {\n            var logger = new OutputLogger(Output);\n            var config = ManualConfig.CreateEmpty().AddLogger(logger);\n            var types = new[] { typeof(WithDryAttributeAndCategory) };\n            var userInteractionMock = new UserInteractionMock(returnValue: types);\n\n            var summaries = new BenchmarkSwitcher(userInteractionMock)\n                .With(types)\n                .Run([categoriesConsoleLineArgument, TestCategory, \"--filter\", \"nothing\"], config);\n\n            Assert.Empty(summaries); // the summaries is empty because the provided filter returns nothing\n            Assert.Equal(0, userInteractionMock.AskUserCalledTimes);\n        }\n\n        [Fact]\n        public void ValidCommandLineArgumentsAreProperlyHandled()\n        {\n            var logger = new OutputLogger(Output);\n            var config = ManualConfig.CreateEmpty().AddLogger(logger);\n\n            // Don't cover every combination, just pick a complex scenario and check\n            // it works end-to-end, i.e. \"method=Method1\" and \"class=ClassB\"\n            var types = new[] { typeof(ClassA), typeof(ClassB), typeof(NOTIntegrationTests.ClassD) };\n            var switcher = new BenchmarkSwitcher(types);\n\n            // BenchmarkSwitcher only picks up config values via the args passed in, not via class annotations (e.g \"[DryConfig]\")\n            var results = switcher.Run([\"-j\", \"Dry\", \"--filter\", \"*ClassB.Method4\"], config);\n            Assert.Single(results);\n            Assert.Single(results.SelectMany(r => r.BenchmarksCases));\n            Assert.Single(results.SelectMany(r => r.BenchmarksCases.Select(bc => bc.Job)));\n            Assert.True(results.All(r => r.BenchmarksCases.All(bc => bc.Job == Job.Dry)));\n            Assert.True(results.All(r => r.BenchmarksCases.All(b => b.Descriptor.Type.Name == \"ClassB\" && b.Descriptor.WorkloadMethod.Name == \"Method4\")));\n        }\n\n        [Fact]\n        public void WhenJobIsDefinedInTheConfigAndArgumentsDontContainJobArgumentOnlySingleJobIsUsed()\n        {\n            var types = new[] { typeof(ClassB) };\n            var switcher = new BenchmarkSwitcher(types);\n            MockExporter mockExporter = new MockExporter();\n            var configWithJobDefined = ManualConfig.CreateEmpty().AddExporter(mockExporter).AddJob(Job.Dry);\n\n            var results = switcher.Run([\"--filter\", \"*Method3\"], configWithJobDefined);\n\n            Assert.True(mockExporter.exported);\n\n            Assert.Single(results);\n            Assert.Single(results.SelectMany(r => r.BenchmarksCases));\n            Assert.Single(results.SelectMany(r => r.BenchmarksCases.Select(bc => bc.Job)));\n            Assert.True(results.All(r => r.BenchmarksCases.All(bc => bc.Job == Job.Dry)));\n        }\n\n        [Fact]\n        public void WhenJobIsDefinedViaAttributeAndArgumentsDontContainJobArgumentOnlySingleJobIsUsed()\n        {\n            var types = new[] { typeof(WithDryAttributeAndCategory) };\n            var switcher = new BenchmarkSwitcher(types);\n            MockExporter mockExporter = new MockExporter();\n            var configWithoutJobDefined = ManualConfig.CreateEmpty().AddExporter(mockExporter);\n\n            var results = switcher.Run([\"--filter\", \"*WithDryAttribute*\"], configWithoutJobDefined);\n\n            Assert.True(mockExporter.exported);\n\n            Assert.Single(results);\n            Assert.Single(results.SelectMany(r => r.BenchmarksCases));\n            Assert.Single(results.SelectMany(r => r.BenchmarksCases.Select(bc => bc.Job)));\n            Assert.True(results.All(r => r.BenchmarksCases.All(bc => bc.Job == Job.Dry)));\n        }\n\n        [Fact]\n        public void JobNotDefinedButStillBenchmarkIsExecuted()\n        {\n            var types = new[] { typeof(JustBenchmark) };\n            var switcher = new BenchmarkSwitcher(types);\n            MockExporter mockExporter = new MockExporter();\n            var configWithoutJobDefined = ManualConfig.CreateEmpty().AddExporter(mockExporter);\n\n            var results = switcher.Run([\"--filter\", \"*\"], configWithoutJobDefined);\n\n            Assert.True(mockExporter.exported);\n\n            Assert.Single(results);\n            Assert.Single(results.SelectMany(r => r.BenchmarksCases));\n            Assert.Single(results.SelectMany(r => r.BenchmarksCases.Select(bc => bc.Job)));\n            Assert.True(results.All(r => r.BenchmarksCases.All(bc => bc.Job == Job.Default)));\n        }\n\n        [Fact]\n        public void WhenUserCreatesStaticBenchmarkMethodWeDisplayAnError_FromTypes()\n        {\n            var logger = new OutputLogger(Output);\n            var config = ManualConfig.CreateEmpty().AddLogger(logger);\n\n            var summariesForType = BenchmarkSwitcher\n                .FromTypes([typeof(Static.BenchmarkClassWithStaticMethodsOnly)])\n                .Run([\"--filter\", \"*\"], config);\n\n            Assert.True(summariesForType.Single().HasCriticalValidationErrors);\n            Assert.Contains(\"static\", logger.GetLog());\n        }\n\n        [Fact]\n        public void WhenUserCreatesStaticBenchmarkMethodWeDisplayAnError_FromAssembly()\n        {\n            var logger = new OutputLogger(Output);\n            var config = ManualConfig.CreateEmpty().AddLogger(logger);\n\n            var summariesForAssembly = BenchmarkSwitcher\n                .FromAssembly(typeof(Static.BenchmarkClassWithStaticMethodsOnly).Assembly)\n                .Run([\"--filter\", \"*\"], config);\n\n            Assert.True(summariesForAssembly.Single().HasCriticalValidationErrors);\n            Assert.Contains(\"static\", logger.GetLog());\n        }\n\n        [FactEnvSpecific(\"For some reason this test is flaky on Full Framework\", EnvRequirement.DotNetCoreOnly)]\n        public void WhenUserAddTheResumeAttributeAndRunTheBenchmarks()\n        {\n            var logger = new OutputLogger(Output);\n            var config = ManualConfig.CreateEmpty().AddLogger(logger);\n\n            var types = new[] { typeof(WithDryAttributeAndCategory) };\n            var switcher = new BenchmarkSwitcher(types);\n\n            // the first run should execute all benchmarks\n            Assert.Single(switcher.Run([\"--filter\", \"*WithDryAttributeAndCategory*\"], config));\n            // resuming after succesfull run should run nothing\n            Assert.Empty(switcher.Run([\"--resume\", \"--filter\", \"*WithDryAttributeAndCategory*\"], config));\n        }\n\n        private class UserInteractionMock : IUserInteraction\n        {\n            private readonly IReadOnlyList<Type> returnValue;\n            internal int PrintNoBenchmarksErrorCalledTimes = 0;\n            internal int PrintWrongFilterInfoCalledTimes = 0;\n            internal int AskUserCalledTimes = 0;\n\n            internal UserInteractionMock(IReadOnlyList<Type> returnValue) => this.returnValue = returnValue;\n\n            public void PrintNoBenchmarksError(ILogger logger) => PrintNoBenchmarksErrorCalledTimes++;\n\n            public void PrintWrongFilterInfo(IReadOnlyList<Type> allTypes, ILogger logger, string[] userFilters) => PrintWrongFilterInfoCalledTimes++;\n\n            public IReadOnlyList<Type> AskUser(IReadOnlyList<Type> allTypes, ILogger logger)\n            {\n                AskUserCalledTimes++;\n\n                return returnValue;\n            }\n        }\n\n        private string GetValidationErrorForType(Type type)\n        {\n            return $\"No [Benchmark] attribute found on '{type.Name}' benchmark case.\";\n        }\n    }\n}\n\nnamespace BenchmarkDotNet.IntegrationTests\n{\n    public class ClassA\n    {\n        [Benchmark]\n        public void Method1() { }\n        [Benchmark]\n        public void Method2() { }\n    }\n\n    public class ClassB\n    {\n        [Benchmark]\n        public void Method1() { }\n        [Benchmark]\n        public void Method2() { }\n        [Benchmark]\n        public void Method3() { }\n        [Benchmark]\n        public void Method4() { }\n    }\n\n    public class ClassC\n    {\n        // None of these methods are actually Benchmarks!!\n        public void Method1() { }\n        public void Method2() { }\n        public void Method3() { }\n    }\n\n    [DryJob]\n    [BenchmarkCategory(BenchmarkSwitcherTest.TestCategory)]\n    public class WithDryAttributeAndCategory\n    {\n        [Benchmark]\n        public void Method() { }\n    }\n\n    public class JustBenchmark\n    {\n        [Benchmark]\n        public void Method() { }\n    }\n\n    public class MockExporter : ExporterBase\n    {\n        public bool exported = false;\n        public override void ExportToLog(Summary summary, ILogger logger)\n        {\n            exported = true;\n        }\n    }\n\n\n}\n\nnamespace BenchmarkDotNet.NOTIntegrationTests\n{\n    [DryJob]\n    public class ClassD\n    {\n        [Benchmark]\n        public void Method1() { }\n        [Benchmark]\n        public void Method2() { }\n    }\n}\n"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/BenchmarkTestExecutor.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing BenchmarkDotNet.Columns;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Tests.Loggers;\nusing Xunit;\nusing Xunit.Abstractions;\nusing System.Collections.Generic;\nusing BenchmarkDotNet.IntegrationTests.Xunit;\nusing BenchmarkDotNet.Reports;\n\nnamespace BenchmarkDotNet.IntegrationTests\n{\n    public class BenchmarkTestExecutor\n    {\n        protected readonly ITestOutputHelper Output;\n\n        protected BenchmarkTestExecutor(ITestOutputHelper output)\n        {\n            Output = output;\n        }\n\n        /// <summary>\n        /// Runs Benchmarks with the most simple config (SingleRunFastConfig)\n        /// combined with any benchmark config applied to TBenchmark (via an attribute)\n        /// By default will verify if every benchmark was successfully executed\n        /// </summary>\n        /// <typeparam name=\"TBenchmark\">type that defines Benchmarks</typeparam>\n        /// <param name=\"config\">Optional custom config to be used instead of the default</param>\n        /// <param name=\"fullValidation\">Optional: disable validation (default = true/enabled)</param>\n        /// <returns>The summary from the benchmark run</returns>\n        public Reports.Summary CanExecute<TBenchmark>(IConfig? config = null, bool fullValidation = true)\n        {\n            return CanExecute(typeof(TBenchmark), config, fullValidation);\n        }\n\n        /// <summary>\n        /// Runs Benchmarks with the most simple config (SingleRunFastConfig)\n        /// combined with any benchmark config applied to Type (via an attribute)\n        /// By default will verify if every benchmark was successfully executed\n        /// </summary>\n        /// <param name=\"type\">type that defines Benchmarks</param>\n        /// <param name=\"config\">Optional custom config to be used instead of the default</param>\n        /// <param name=\"fullValidation\">Optional: disable validation (default = true/enabled)</param>\n        /// <returns>The summary from the benchmark run</returns>\n        public Reports.Summary CanExecute(Type type, IConfig? config = null, bool fullValidation = true)\n        {\n            // Add logging, so the Benchmark execution is in the TestRunner output (makes Debugging easier)\n            if (config == null)\n                config = CreateSimpleConfig();\n\n            if (!config.GetLoggers().OfType<OutputLogger>().Any())\n                config = config.AddLogger(Output != null ? new OutputLogger(Output) : ConsoleLogger.Default);\n            if (!config.GetLoggers().OfType<ConsoleLogger>().Any())\n                config = config.AddLogger(ConsoleLogger.Default);\n\n            if (!config.GetColumnProviders().Any())\n                config = config.AddColumnProvider(DefaultColumnProviders.Instance);\n\n            // Make sure we ALWAYS combine the Config (default or passed in) with any Config applied to the Type/Class\n            var summary = BenchmarkRunner.Run(type, config);\n\n            if (fullValidation)\n            {\n                Assert.False(summary.HasCriticalValidationErrors, \"The \\\"Summary\\\" should have NOT \\\"HasCriticalValidationErrors\\\"\");\n\n                Assert.True(summary.Reports.Any(), \"The \\\"Summary\\\" should contain at least one \\\"BenchmarkReport\\\" in the \\\"Reports\\\" collection\");\n\n                summary.CheckPlatformLinkerIssues();\n\n                Assert.True(summary.Reports.All(r => r.BuildResult.IsBuildSuccess),\n                    \"The following benchmarks have failed to build: \" +\n                    string.Join(\", \", summary.Reports.Where(r => !r.BuildResult.IsBuildSuccess).Select(r => r.BenchmarkCase.DisplayInfo)));\n\n                Assert.True(summary.Reports.All(r => r.ExecuteResults != null),\n                    \"The following benchmarks don't have any execution results: \" +\n                    string.Join(\", \", summary.Reports.Where(r => r.ExecuteResults == null).Select(r => r.BenchmarkCase.DisplayInfo)));\n\n                Assert.True(summary.Reports.All(r => r.ExecuteResults.All(er => er.IsSuccess)),\n                    \"All reports should have succeeded to execute\");\n            }\n\n            return summary;\n        }\n\n        protected IConfig CreateSimpleConfig(OutputLogger? logger = null, Job? job = null)\n        {\n            var baseConfig = job == null ? (IConfig)new SingleRunFastConfig() : new SingleJobConfig(job);\n            return baseConfig\n                .AddLogger(logger ?? (Output != null ? new OutputLogger(Output) : ConsoleLogger.Default))\n                .AddColumnProvider(DefaultColumnProviders.Instance)\n                .AddAnalyser(DefaultConfig.Instance.GetAnalysers().ToArray());\n        }\n\n        protected static IReadOnlyList<string> GetSingleStandardOutput(Summary summary)\n            => summary.Reports.Single().ExecuteResults.Single().StandardOutput;\n\n        protected static IReadOnlyList<string> GetCombinedStandardOutput(Summary summary)\n            => summary.Reports.SelectMany(r => r.ExecuteResults).SelectMany(e => e.StandardOutput).ToArray();\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/BuildTimeoutTests.cs",
    "content": "﻿using System;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Detectors;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Portability;\nusing BenchmarkDotNet.Toolchains.NativeAot;\nusing Xunit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.IntegrationTests\n{\n    public class BuildTimeoutTests: BenchmarkTestExecutor\n    {\n        public BuildTimeoutTests(ITestOutputHelper outputHelper) : base(outputHelper) { }\n\n        [Fact]\n        public void WhenBuildTakesMoreTimeThanTheTimeoutTheBuildIsCancelled()\n        {\n            if (!RuntimeInformation.Is64BitPlatform()) // NativeAOT does not support 32bit yet\n                return;\n            if (OsDetector.IsMacOS())\n                return; // currently not supported\n\n            // we use NativeAOT on purpose because it takes a LOT of time to build it\n            // so we can be sure that timeout = 1s should fail!\n            var timeout = TimeSpan.FromSeconds(1);\n\n            var config = ManualConfig.CreateEmpty()\n                .WithBuildTimeout(timeout)\n                .AddJob(Job.Dry\n                    .WithRuntime(NativeAotRuntime.Net80)\n                    .WithToolchain(NativeAotToolchain.CreateBuilder()\n                        .UseNuGet(\"8.0.0\", \"https://api.nuget.org/v3/index.json\")\n                        .TargetFrameworkMoniker(\"net8.0\")\n                        .ToToolchain()));\n\n            var summary = CanExecute<NativeAotBenchmark>(config, fullValidation: false);\n\n            Assert.All(summary.Reports, report => Assert.False(report.BuildResult.IsBuildSuccess));\n            Assert.All(summary.Reports, report => Assert.Contains(\"The configured timeout\", report.BuildResult.ErrorMessage));\n        }\n    }\n\n    public class Impossible\n    {\n        [Benchmark]\n        public void Check() => Environment.FailFast(\"This benchmark should have been never executed because 1s is not enough to build NativeAOT benchmark!\");\n    }\n}\n"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/ConflictingNamesTests.cs",
    "content": "﻿using BenchmarkDotNet.Attributes;\nusing Xunit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.IntegrationTests;\n\npublic class ConflictingNamesTests(ITestOutputHelper output) : BenchmarkTestExecutor(output)\n{\n    [Fact]\n    public void BenchmarkMethodsCanUseTemplateNames() => CanExecute<WithNamesUsedByTemplate>();\n\n    public class WithNamesUsedByTemplate\n    {\n        [Params(1)]\n        public int OverheadActionUnroll { get; set; }\n\n        [Benchmark]\n        [Arguments(2)]\n        public void System(int OverheadActionNoUnroll)\n        {\n\n        }\n\n        [Benchmark]\n        public void BenchmarkDotNet()\n        {\n\n        }\n\n        [Benchmark]\n        public void __Overhead()\n        {\n\n        }\n\n        [Benchmark]\n        [Arguments(3)]\n        public void WorkloadActionUnroll(int WorkloadActionNoUnroll)\n        {\n\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/ContinuousIntegration.cs",
    "content": "﻿using BenchmarkDotNet.Portability;\nusing System;\nusing BenchmarkDotNet.Detectors;\n\nnamespace BenchmarkDotNet.IntegrationTests\n{\n    internal static class ContinuousIntegration\n    {\n        private static bool IsGitHubActions() => !string.IsNullOrEmpty(Environment.GetEnvironmentVariable(\"GITHUB_ACTION\"));\n\n        internal static bool IsGitHubActionsOnWindows()\n            => OsDetector.IsWindows() && IsGitHubActions();\n\n        internal static bool IsLocalRun() => !IsGitHubActions();\n    }\n}\n"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/CopyToOutputTests.cs",
    "content": "#if NETFRAMEWORK\nusing BenchmarkDotNet.IntegrationTests.CustomPaths;\nusing Xunit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.IntegrationTests\n{\n    public class CopyToOutputTests : BenchmarkTestExecutor\n    {\n        public CopyToOutputTests(ITestOutputHelper output) : base(output) { }\n\n        [Fact]\n        public void CopyToOutputIsSupported() => CanExecute<BenchmarksThatUsesFileFromOutput>();\n    }\n}\n#endif"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/CustomBuildConfigurationTests.cs",
    "content": "﻿using System;\nusing System.Reflection;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Portability;\nusing BenchmarkDotNet.Tests.XUnit;\n#if !DEBUG\nusing Xunit;\n#endif\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.IntegrationTests\n{\n    public class CustomBuildConfigurationTests : BenchmarkTestExecutor\n    {\n        public CustomBuildConfigurationTests(ITestOutputHelper output) : base(output)\n        {\n        }\n\n        [FactEnvSpecific(\"Flaky, see https://github.com/dotnet/BenchmarkDotNet/issues/2376\", EnvRequirement.NonFullFramework)]\n        public void UserCanSpecifyCustomBuildConfiguration()\n        {\n            var jobWithCustomConfiguration = Job.Dry.WithCustomBuildConfiguration(\"CUSTOM\");\n\n            var config = CreateSimpleConfig(job: jobWithCustomConfiguration);\n            config = ((ManualConfig)config).WithBuildTimeout(TimeSpan.FromSeconds(240));\n\n            var report = CanExecute<CustomBuildConfiguration>(config);\n\n#if !DEBUG\n            Assert.NotEqual(RuntimeInformation.DebugConfigurationName, report.HostEnvironmentInfo.Configuration);\n            Assert.DoesNotContain(report.AllRuntimes, RuntimeInformation.DebugConfigurationName);\n#endif\n        }\n\n        public class CustomBuildConfiguration\n        {\n            [Benchmark]\n            public void Benchmark()\n            {\n                if (Assembly.GetEntryAssembly().IsJitOptimizationDisabled().IsTrue())\n                {\n                    throw new InvalidOperationException(\"Auto-generated project has not enabled optimizations!\");\n                }\n                if (typeof(CustomBuildConfiguration).Assembly.IsJitOptimizationDisabled().IsTrue())\n                {\n                    throw new InvalidOperationException(\"Project that defines benchmarks has not enabled optimizations!\");\n                }\n                if (RuntimeInformation.GetConfiguration() == RuntimeInformation.DebugConfigurationName)\n                {\n                    throw new InvalidOperationException($\"Configuration rezognized as {RuntimeInformation.DebugConfigurationName}!\");\n                }\n\n#if !CUSTOM\n                throw new InvalidOperationException(\"Should never happen\");\n#endif\n            }\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/CustomEngineTests.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing BenchmarkDotNet.Attributes;\nusing Xunit;\nusing Xunit.Abstractions;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Reports;\nusing Perfolizer.Mathematics.OutlierDetection;\n\nnamespace BenchmarkDotNet.IntegrationTests\n{\n    public class CustomEngineTests : BenchmarkTestExecutor\n    {\n        private const string GlobalSetupMessage = \"// GlobalSetup got called\";\n        private const string EngineRunMessage = \"// EngineRun got called\";\n        private const string GlobalCleanupMessage = \"// GlobalCleanup got called\";\n\n        public CustomEngineTests(ITestOutputHelper output) : base(output)\n        {\n        }\n\n        [Fact]\n        public void CustomEnginesAreSupported()\n        {\n            var config = ManualConfig.CreateEmpty()\n                .AddJob(new Job(Job.Dry) { Infrastructure = { EngineFactory = new CustomFactory() } });\n\n            var summary = CanExecute<SimpleBenchmark>(config, fullValidation: false);\n\n            IReadOnlyList<string> standardOutput = GetSingleStandardOutput(summary);\n\n            Assert.Contains(GlobalSetupMessage, standardOutput);\n            Assert.Contains(EngineRunMessage, standardOutput);\n            Assert.Contains(GlobalCleanupMessage, standardOutput);\n        }\n\n        public class SimpleBenchmark\n        {\n            [GlobalSetup]\n            public void Setup() => Console.WriteLine(GlobalSetupMessage);\n\n            [GlobalCleanup]\n            public void Cleanup() => Console.WriteLine(GlobalCleanupMessage);\n\n            [Benchmark]\n            public void Empty() { }\n        }\n\n        public class CustomFactory : IEngineFactory\n        {\n            public IEngine Create(EngineParameters engineParameters)\n                => new CustomEngine(engineParameters);\n        }\n\n        public class CustomEngine(EngineParameters engineParameters) : IEngine\n        {\n            public RunResults Run()\n            {\n                engineParameters.GlobalSetupAction.Invoke();\n                Console.WriteLine(EngineRunMessage);\n                try\n                {\n                    return new RunResults(\n                        [\n                            new(1, IterationMode.Overhead, IterationStage.Actual, 1, 1, 1),\n                            new(1, IterationMode.Workload, IterationStage.Actual, 1, 1, 1)\n                        ],\n                        OutlierMode.DontRemove,\n                        default\n                    );\n                }\n                finally\n                {\n                    engineParameters.GlobalCleanupAction.Invoke();\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/Diagnosers/MockInProcessDiagnoser.cs",
    "content": "﻿using BenchmarkDotNet.Analysers;\nusing BenchmarkDotNet.Diagnosers;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Exporters;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Validators;\nusing System;\nusing System.Collections.Generic;\nusing System.Threading;\n\nnamespace BenchmarkDotNet.IntegrationTests.Diagnosers;\n\npublic abstract class BaseMockInProcessDiagnoser(RunMode runMode) : IInProcessDiagnoser\n{\n    public static Queue<(RunMode runMode, int order, string result)> s_completedResults = new();\n\n    public Dictionary<BenchmarkCase, string> Results { get; } = [];\n\n    public RunMode RunMode { get; } = runMode;\n    public string ExpectedResult => $\"MockResult-{RunMode}\";\n\n    public IEnumerable<string> Ids => [GetType().Name];\n\n    public IEnumerable<IExporter> Exporters => [];\n\n    public IEnumerable<IAnalyser> Analysers => [];\n\n    public void DisplayResults(ILogger logger) => logger.WriteLine($\"{GetType().Name} results: [{string.Join(\", \", Results.Values)}]\");\n\n    public RunMode GetRunMode(BenchmarkCase benchmarkCase) => RunMode;\n\n    public void Handle(HostSignal signal, DiagnoserActionParameters parameters) { }\n\n    public IEnumerable<Metric> ProcessResults(DiagnoserResults results) => [];\n\n    public IEnumerable<ValidationError> Validate(ValidationParameters validationParameters) => [];\n\n    InProcessDiagnoserHandlerData IInProcessDiagnoser.GetHandlerData(BenchmarkCase benchmarkCase)\n        => RunMode == RunMode.None\n            ? default\n            : new(typeof(MockInProcessDiagnoserHandler), $\"{GetSignal()} {ExpectedResult}\");\n\n    private BenchmarkSignal GetSignal() => RunMode switch\n    {\n        RunMode.NoOverhead => BenchmarkSignal.AfterActualRun,\n        RunMode.ExtraIteration => BenchmarkSignal.AfterExtraIteration,\n        RunMode.ExtraRun => BenchmarkSignal.AfterActualRun,\n        _ => BenchmarkSignal.SeparateLogic\n    };\n\n    public void DeserializeResults(BenchmarkCase benchmarkCase, string results)\n    {\n        var split = results.Split(' ');\n        int order = int.Parse(split[0]);\n        string result = split[1];\n        Results.Add(benchmarkCase, result);\n        s_completedResults.Enqueue((RunMode, order, result));\n    }\n}\n\npublic sealed class MockInProcessDiagnoserHandler : IInProcessDiagnoserHandler\n{\n    private static int s_order;\n\n    private BenchmarkSignal _signal;\n    private string _result = default!;\n\n    public void Initialize(string? serializedConfig)\n    {\n        var split = serializedConfig!.Split(' ');\n        _signal = (BenchmarkSignal) Enum.Parse(typeof(BenchmarkSignal), split[0]);\n        _result = split[1];\n    }\n\n    public void Handle(BenchmarkSignal signal, InProcessDiagnoserActionArgs args)\n    {\n        if (signal == _signal)\n        {\n            _result = $\"{Interlocked.Increment(ref s_order)} {_result}\";\n        }\n    }\n\n    public string SerializeResults() => _result;\n}\n\n// Diagnosers are made unique per-type rather than per-instance, so we have to create separate types to test multiple.\npublic sealed class MockInProcessDiagnoser1(RunMode runMode) : BaseMockInProcessDiagnoser(runMode) { }\npublic sealed class MockInProcessDiagnoser2(RunMode runMode) : BaseMockInProcessDiagnoser(runMode) { }\npublic sealed class MockInProcessDiagnoser3(RunMode runMode) : BaseMockInProcessDiagnoser(runMode) { }"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/Diagnosers/ProcessMetricsTests.cs",
    "content": "﻿#if NETFRAMEWORK\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing BenchmarkDotNet.Diagnosers;\nusing BenchmarkDotNet.Diagnostics.Windows.Tracing;\nusing BenchmarkDotNet.Engines;\nusing Xunit;\n\nnamespace BenchmarkDotNet.IntegrationTests.Diagnosers\n{\n    public class ProcessMetricsTests\n    {\n        [Fact]\n        public void TheNumberOfStopEventsMustBeEqualToStartEvents()\n        {\n            var sut = new ProcessMetrics();\n\n            sut.HandleIterationEvent(0, IterationMode.Overhead, 100); // start but no stop later on\n\n            Assert.Throws<InvalidOperationException>(() => sut.CalculateMetrics(null!, []));\n        }\n\n        [Fact]\n        public void TheNumberOfTotalOperationsPerIterationIsTheSameForAllIterations()\n        {\n            var sut = new ProcessMetrics();\n\n            sut.HandleIterationEvent(0, IterationMode.Workload, 100); // start\n\n            Assert.Throws<InvalidOperationException>(() => sut.HandleIterationEvent(0, IterationMode.Workload, 100 + 1));\n        }\n\n        [Fact]\n        public void MetricsAreCorrectlyCalculatedPerIteration()\n        {\n            const int profileSourceId = 123;\n            const int interval = 100;\n            const ulong ip = 12345;\n            const long totalOperations = 100;\n\n            var sut = new ProcessMetrics();\n\n            for (int relativeTimestamp = 0; relativeTimestamp < 20; relativeTimestamp++)\n            {\n                sut.HandleIterationEvent(relativeTimestamp, IterationMode.Overhead, totalOperations); // Overhead iteration start at i\n\n                sut.HandleNewSample(relativeTimestamp + 0.1, ip, profileSourceId); // Engine overhead produces one PMC event per iteration\n\n                sut.HandleIterationEvent(relativeTimestamp + 0.5, IterationMode.Overhead, totalOperations); // Overhead iteration stop at i + 0.5\n            }\n\n            for (int relativeTimestamp = 20; relativeTimestamp < 40; relativeTimestamp++)\n            {\n                sut.HandleIterationEvent(relativeTimestamp, IterationMode.Workload, totalOperations); // Workload iteration start at i\n\n                sut.HandleNewSample(relativeTimestamp + 0.1, ip, profileSourceId); // Engine overhead produces one PMC event per iteration\n                sut.HandleNewSample(relativeTimestamp + 0.2, ip, profileSourceId); // benchmarked code\n                sut.HandleNewSample(relativeTimestamp + 0.3, ip, profileSourceId); // benchmarked code\n                sut.HandleNewSample(relativeTimestamp + 0.4, ip, profileSourceId); // benchmarked code\n\n                sut.HandleIterationEvent(relativeTimestamp + 0.5, IterationMode.Workload, totalOperations); // Workload iteration stop at i + 0.5\n            }\n\n            var metrics = sut.CalculateMetrics(\n                new Dictionary<int, int> { { profileSourceId, interval } },\n                [new PreciseMachineCounter(profileSourceId, \"test\", HardwareCounter.InstructionRetired, interval),]);\n\n            const ulong expected = (4 * interval - interval) / totalOperations; // every workload was 4 events, the overhead was one and totalOperations times per iteration\n\n            Assert.Equal(expected, metrics.Single().Value);\n        }\n    }\n}\n#endif"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/DisassemblyDiagnoserTests.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Runtime.CompilerServices;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Columns;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Diagnosers;\nusing BenchmarkDotNet.Disassemblers;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.IntegrationTests.Xunit;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Portability;\nusing BenchmarkDotNet.Tests.Loggers;\nusing BenchmarkDotNet.Tests.XUnit;\nusing BenchmarkDotNet.Toolchains;\nusing BenchmarkDotNet.Toolchains.CsProj;\nusing BenchmarkDotNet.Toolchains.InProcess.Emit;\nusing Xunit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.IntegrationTests\n{\n    public class DisassemblyDiagnoserTests : BenchmarkTestExecutor\n    {\n        public DisassemblyDiagnoserTests(ITestOutputHelper output) : base(output) { }\n\n        public static IEnumerable<object[]> GetAllJits()\n        {\n            yield return [JitInfo.GetCurrentJit(), RuntimeInformation.GetCurrentPlatform(), InProcessEmitToolchain.Default]; // InProcess\n\n            if (RuntimeInformation.IsFullFramework)\n            {\n                yield return [Jit.LegacyJit, Platform.X86, CsProjClassicNetToolchain.Net462]; // 32bit LegacyJit for desktop .NET\n                yield return [Jit.LegacyJit, Platform.X64, CsProjClassicNetToolchain.Net462]; // 64bit LegacyJit for desktop .NET\n                yield return [Jit.RyuJit, Platform.X64, CsProjClassicNetToolchain.Net462]; // RyuJit for desktop .NET\n            }\n            else if (RuntimeInformation.IsNetCore)\n            {\n                if (RuntimeInformation.GetCurrentPlatform() is Platform.X86 or Platform.X64)\n                {\n                    yield return [Jit.RyuJit, Platform.X64, CsProjCoreToolchain.NetCoreApp80]; // .NET Core x64\n                    // We could add Platform.X86 here, but it would make our CI more complicated.\n                }\n                else if (RuntimeInformation.GetCurrentPlatform() is Platform.Arm64)\n                {\n                    yield return [Jit.RyuJit, Platform.Arm64, CsProjCoreToolchain.NetCoreApp80]; // .NET Core arm64\n                }\n            }\n\n            // we could add new object[] { Jit.Llvm, Platform.X64, new MonoRuntime() } here but our CI would need to have Mono installed..\n        }\n\n        public class WithCalls\n        {\n            [Benchmark]\n            [Arguments(int.MaxValue)]\n            public void Benchmark(int someArgument)\n            {\n                if (someArgument != int.MaxValue)\n                    throw new InvalidOperationException(\"Wrong value of the argument!!\");\n\n                // we should rather have test per use case\n                // but running so many tests for all JITs would take too much time\n                // so we have one method that does it all\n                Static();\n                Instance();\n                Recursive();\n\n                Benchmark(true);\n            }\n\n            [MethodImpl(MethodImplOptions.NoInlining)] public static void Static() { }\n\n            [MethodImpl(MethodImplOptions.NoInlining)] public void Instance() { }\n\n            [MethodImpl(MethodImplOptions.NoInlining)] // legacy JIT x64 was able to inline this method ;)\n            public void Recursive()\n            {\n                if (new Random(123).Next(0, 10) == 11) // never true, but JIT does not know it\n                    Recursive();\n            }\n\n            [MethodImpl(MethodImplOptions.NoInlining)] public void Benchmark(bool justAnOverload) { } // we need to test overloads (#562)\n        }\n\n        [TheoryEnvSpecific(\"Not supported on Windows+Arm\", EnvRequirement.NonWindowsArm)]\n        [MemberData(nameof(GetAllJits), DisableDiscoveryEnumeration = true)]\n        [Trait(Constants.Category, Constants.BackwardCompatibilityCategory)]\n        public void CanDisassembleAllMethodCalls(Jit jit, Platform platform, IToolchain toolchain)\n        {\n            var disassemblyDiagnoser = new DisassemblyDiagnoser(\n                new DisassemblyDiagnoserConfig(printSource: true, maxDepth: 3));\n\n            CanExecute<WithCalls>(CreateConfig(jit, platform, toolchain, disassemblyDiagnoser, RunStrategy.ColdStart));\n\n            DisassemblyResult result = disassemblyDiagnoser.Results.Single().Value;\n\n            Assert.Empty(result.Errors);\n            AssertDisassemblyResult(result, $\"{nameof(WithCalls.Benchmark)}(Int32)\");\n            AssertDisassemblyResult(result, $\"{nameof(WithCalls.Benchmark)}(Boolean)\");\n            AssertDisassemblyResult(result, $\"{nameof(WithCalls.Static)}()\");\n            AssertDisassemblyResult(result, $\"{nameof(WithCalls.Instance)}()\");\n            AssertDisassemblyResult(result, $\"{nameof(WithCalls.Recursive)}()\");\n        }\n\n        [TheoryEnvSpecific(\"Not supported on Windows+Arm\", EnvRequirement.NonWindowsArm)]\n        [MemberData(nameof(GetAllJits), DisableDiscoveryEnumeration = true)]\n        [Trait(Constants.Category, Constants.BackwardCompatibilityCategory)]\n        public void CanDisassembleAllMethodCallsUsingFilters(Jit jit, Platform platform, IToolchain toolchain)\n        {\n            var disassemblyDiagnoser = new DisassemblyDiagnoser(\n                new DisassemblyDiagnoserConfig(printSource: true, maxDepth: 1, filters: [\"*WithCalls*\"]));\n\n            CanExecute<WithCalls>(CreateConfig(jit, platform, toolchain, disassemblyDiagnoser, RunStrategy.ColdStart));\n\n            DisassemblyResult result = disassemblyDiagnoser.Results.Single().Value;\n\n            Assert.Empty(result.Errors);\n            AssertDisassemblyResult(result, $\"{nameof(WithCalls.Benchmark)}(Int32)\");\n            AssertDisassemblyResult(result, $\"{nameof(WithCalls.Benchmark)}(Boolean)\");\n            AssertDisassemblyResult(result, $\"{nameof(WithCalls.Static)}()\");\n            AssertDisassemblyResult(result, $\"{nameof(WithCalls.Instance)}()\");\n            AssertDisassemblyResult(result, $\"{nameof(WithCalls.Recursive)}()\");\n        }\n\n        public class Generic<T> where T : new()\n        {\n            [Benchmark]\n            public T Create() => new T();\n        }\n\n        [TheoryEnvSpecific(\"Not supported on Windows+Arm\", EnvRequirement.NonWindowsArm)]\n        [MemberData(nameof(GetAllJits), DisableDiscoveryEnumeration = true)]\n        [Trait(Constants.Category, Constants.BackwardCompatibilityCategory)]\n        public void CanDisassembleGenericTypes(Jit jit, Platform platform, IToolchain toolchain)\n        {\n            var disassemblyDiagnoser = new DisassemblyDiagnoser(\n                new DisassemblyDiagnoserConfig(printSource: true, maxDepth: 3));\n\n            CanExecute<Generic<int>>(CreateConfig(jit, platform, toolchain, disassemblyDiagnoser, RunStrategy.Monitoring));\n\n            var result = disassemblyDiagnoser.Results.Values.Single();\n\n            Assert.Empty(result.Errors);\n            Assert.Contains(result.Methods, method => method.Maps.Any(map => map.SourceCodes.OfType<Asm>().Any()));\n        }\n\n        public class WithInlineable\n        {\n            [Benchmark] public void JustReturn() { }\n        }\n\n        [TheoryEnvSpecific(\"Not supported on Windows+Arm\", EnvRequirement.NonWindowsArm)]\n        [MemberData(nameof(GetAllJits), DisableDiscoveryEnumeration = true)]\n        [Trait(Constants.Category, Constants.BackwardCompatibilityCategory)]\n        public void CanDisassembleInlinableBenchmarks(Jit jit, Platform platform, IToolchain toolchain)\n        {\n            var disassemblyDiagnoser = new DisassemblyDiagnoser(\n                new DisassemblyDiagnoserConfig(printSource: true, maxDepth: 3));\n\n            CanExecute<WithInlineable>(CreateConfig(jit, platform, toolchain, disassemblyDiagnoser, RunStrategy.Monitoring));\n\n            var disassemblyResult = disassemblyDiagnoser.Results.Values.Single(result => result.Methods.Count(method => method.Name.Contains(nameof(WithInlineable.JustReturn))) == 1);\n\n            Assert.Empty(disassemblyResult.Errors);\n            Assert.Contains(disassemblyResult.Methods, method => method.Maps.Any(map => map.SourceCodes.OfType<Asm>().All(asm => asm.ToString()!.Contains(\"ret\"))));\n        }\n\n        private IConfig CreateConfig(Jit jit, Platform platform, IToolchain toolchain, IDiagnoser disassemblyDiagnoser, RunStrategy runStrategy)\n            => ManualConfig.CreateEmpty()\n                .AddJob(Job.Dry.WithJit(jit)\n                    .WithPlatform(platform)\n                    .WithToolchain(toolchain)\n                    .WithStrategy(runStrategy)\n                    // Ensure the build goes through the full process and doesn't build without dependencies like most of the integration tests do.\n#if RELEASE\n                    .WithCustomBuildConfiguration(\"Release\")\n#else\n                    .WithCustomBuildConfiguration(\"Debug\")\n#endif\n                )\n                .AddLogger(DefaultConfig.Instance.GetLoggers().ToArray())\n                .AddColumnProvider(DefaultColumnProviders.Instance)\n                .AddDiagnoser(disassemblyDiagnoser)\n                .AddLogger(new OutputLogger(Output));\n\n        private void AssertDisassemblyResult(DisassemblyResult result, string methodSignature)\n        {\n            Assert.Contains(methodSignature, result.Methods.Select(m => m.Name.Split('.').Last()).ToArray());\n            Assert.Contains(result.Methods.Single(m => m.Name.EndsWith(methodSignature)).Maps, map => map.SourceCodes.Any());\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/DryRunTests.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing System.Threading;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Engines;\nusing Xunit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.IntegrationTests\n{\n    public class DryRunTests(ITestOutputHelper output) : BenchmarkTestExecutor(output)\n    {\n        [Fact]\n        public void BenchWithStatTest() => CanExecute<WelchTTestBench>();\n\n        [DryJob, StatisticalTestColumn]\n        public class WelchTTestBench\n        {\n            [Benchmark(Baseline = true)]\n            public void A() => Thread.Sleep(10);\n\n            [Benchmark]\n            public void B() => Thread.Sleep(10);\n        }\n\n        [Fact]\n        public void ColdStart()\n        {\n            var summary = CanExecute<ColdStartBench>();\n\n            var report = summary.Reports.Single();\n\n            Assert.Equal(2, report.AllMeasurements.Count);\n\n            foreach (var measurement in report.AllMeasurements)\n            {\n                Assert.Equal(1, measurement.LaunchIndex);\n                Assert.Equal(1, measurement.IterationIndex);\n                Assert.Equal(IterationMode.Workload, measurement.IterationMode);\n                Assert.True(measurement.IterationStage is IterationStage.Actual or IterationStage.Result);\n            }\n        }\n\n        [DryJob]\n        public class ColdStartBench\n        {\n            private int counter;\n\n            [Benchmark]\n            public void Foo()\n            {\n                if (++counter > 1)\n                {\n                    throw new InvalidOperationException(\"Benchmark was executed more than once\");\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/EngineTests.cs",
    "content": "using System.Linq;\nusing System.Threading;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Reports;\nusing Xunit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.IntegrationTests\n{\n    public class EngineTests : BenchmarkTestExecutor\n    {\n        public EngineTests(ITestOutputHelper output) : base(output) { }\n\n        [Fact]\n        public void ZeroWarmupCountIsApplied()\n        {\n#pragma warning disable CS0618 // WithEvaluateOverhead is obsolete\n            var job = Job.InProcess\n                .WithEvaluateOverhead(false)\n                .WithWarmupCount(0)\n                .WithIterationCount(1)\n                .WithInvocationCount(1)\n                .WithUnrollFactor(1);\n#pragma warning restore CS0618 // WithEvaluateOverhead is obsolete\n            var config = DefaultConfig.Instance.AddJob(job).WithOptions(ConfigOptions.DisableOptimizationsValidator);\n            var summary = CanExecute<FooBench>(config);\n            var report = summary.Reports.Single();\n            int workloadWarmupCount = report.AllMeasurements\n                .Count(m => m.Is(IterationMode.Workload, IterationStage.Warmup));\n            Assert.Equal(0, workloadWarmupCount);\n        }\n\n        [Fact]\n        public void AllMeasurementsArePerformedDefault() => AllMeasurementsArePerformed(Job.Default);\n\n        [Fact]\n        public void AllMeasurementsArePerformedInProcess() => AllMeasurementsArePerformed(Job.InProcess);\n\n        private void AllMeasurementsArePerformed(Job baseJob)\n        {\n            var job = baseJob\n                .WithWarmupCount(1)\n                .WithIterationCount(1)\n                .WithInvocationCount(1)\n                .WithUnrollFactor(1);\n            var config = DefaultConfig.Instance.AddJob(job).WithOptions(ConfigOptions.DisableOptimizationsValidator);\n            var summary = CanExecute<FooBench>(config);\n            var measurements = summary.Reports.Single().AllMeasurements;\n\n            Output.WriteLine(\"*** AllMeasurements ***\");\n            foreach (var measurement in measurements)\n                Output.WriteLine(measurement.ToString());\n            Output.WriteLine(\"-----\");\n\n            void Check(IterationMode mode, IterationStage stage)\n            {\n                int count = measurements.Count(m => m.Is(mode, stage));\n                Output.WriteLine($\"Count({mode}{stage}) = {count}\");\n                Assert.True(count > 0, $\"AllMeasurements don't contain {mode}{stage}\");\n            }\n\n            Check(IterationMode.Workload, IterationStage.Jitting);\n            Check(IterationMode.Workload, IterationStage.Warmup);\n            Check(IterationMode.Workload, IterationStage.Actual);\n            Check(IterationMode.Workload, IterationStage.Result);\n        }\n\n        public class FooBench\n        {\n            [Benchmark]\n            public void Foo() => Thread.Sleep(10);\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/EnvironmentVariablesTests.cs",
    "content": "using System;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Jobs;\nusing Xunit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.IntegrationTests\n{\n    public class EnvironmentVariablesTests : BenchmarkTestExecutor\n    {\n        internal const string Key = \"VeryNiceKey\";\n        internal const string Value = \"VeryNiceValue\";\n\n        public EnvironmentVariablesTests(ITestOutputHelper output) : base(output)\n        {\n        }\n\n        [Fact]\n        public void UserCanSpecifyEnvironmentVariables()\n        {\n            var variables = new[] { new EnvironmentVariable(Key, Value) };\n            var jobWithCustomConfiguration = Job.Dry.WithEnvironmentVariables(variables);\n            var config = CreateSimpleConfig(job: jobWithCustomConfiguration);\n\n            CanExecute<WithEnvironmentVariables>(config);\n        }\n\n        public class WithEnvironmentVariables\n        {\n            [Benchmark]\n            public void Benchmark()\n            {\n                if (Environment.GetEnvironmentVariable(Key) != Value)\n                    throw new InvalidOperationException(\"The env var was not set\");\n            }\n        }\n\n        [Fact]\n        public void ResharperDynamicProgramAnalysisIsDisabledByDefault()\n            => CanExecute<TestingDpaDisabled>(CreateSimpleConfig(job: Job.Dry));\n\n        public class TestingDpaDisabled\n        {\n            [Benchmark]\n            public void Benchmark()\n            {\n                if (Environment.GetEnvironmentVariable(\"JETBRAINS_DPA_AGENT_ENABLE\") != \"0\")\n                    throw new InvalidOperationException(\"The JETBRAINS_DPA_AGENT_ENABLE env var was not set to zero\");\n            }\n        }\n\n        [Fact]\n        public void ResharperDynamicProgramAnalysisCanBeEnabled()\n        {\n            var jobWithSettingEnabled = Job.Dry.WithEnvironmentVariable(\"JETBRAINS_DPA_AGENT_ENABLE\", \"1\");\n            var config = CreateSimpleConfig(job: jobWithSettingEnabled);\n\n            CanExecute<TestingDpaEnabled>(config);\n        }\n\n        public class TestingDpaEnabled\n        {\n            [Benchmark]\n            public void Benchmark()\n            {\n                if (Environment.GetEnvironmentVariable(\"JETBRAINS_DPA_AGENT_ENABLE\") != \"1\")\n                    throw new InvalidOperationException(\"The JETBRAINS_DPA_AGENT_ENABLE env var was not set to one\");\n            }\n        }\n\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/EventProcessorTests.cs",
    "content": "﻿using BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Characteristics;\nusing BenchmarkDotNet.Columns;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.EventProcessors;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Toolchains;\nusing BenchmarkDotNet.Toolchains.Results;\nusing BenchmarkDotNet.Validators;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing Xunit;\n\nnamespace BenchmarkDotNet.IntegrationTests\n{\n    public class EventProcessorTests\n    {\n        [Fact]\n        public void WhenUsingEventProcessorAndNoBenchmarks()\n        {\n            var events = RunBenchmarksAndRecordEvents([typeof(ClassEmpty)]);\n            Assert.Equal(3, events.Count);\n            Assert.Equal(nameof(EventProcessor.OnStartValidationStage), events[0].EventType);\n            Assert.Equal(nameof(EventProcessor.OnValidationError), events[1].EventType);\n            Assert.Equal(nameof(EventProcessor.OnEndValidationStage), events[2].EventType);\n        }\n\n        [Fact]\n        public void WhenUsingEventProcessorOnSingleClass()\n        {\n            var events = RunBenchmarksAndRecordEvents([typeof(ClassA)]);\n\n            Assert.Equal(13, events.Count);\n\n            Assert.Equal(nameof(EventProcessor.OnStartValidationStage), events[0].EventType);\n            Assert.Equal(nameof(EventProcessor.OnEndValidationStage), events[1].EventType);\n            Assert.Equal(nameof(EventProcessor.OnStartBuildStage), events[2].EventType);\n            Assert.Equal(nameof(EventProcessor.OnBuildComplete), events[3].EventType);\n            Assert.Equal(nameof(EventProcessor.OnEndBuildStage), events[4].EventType);\n            Assert.Equal(nameof(EventProcessor.OnStartRunStage), events[5].EventType);\n\n            var benchmarkTypeAndMethods = new List<(Type Type, string[] MethodNames)>\n            {\n                (typeof(ClassA), new[]{ nameof(ClassA.Method1), nameof(ClassA.Method2) })\n            };\n\n            int eventIndex = 6;\n            foreach ((var type, var methodNames) in benchmarkTypeAndMethods)\n            {\n                Assert.Equal(nameof(EventProcessor.OnStartRunBenchmarksInType), events[eventIndex].EventType);\n                Assert.Equal(type, events[eventIndex++].Args[0] as Type);\n\n                foreach (var method in methodNames)\n                {\n                    var methodDescriptor = type.GetMethod(method);\n                    Assert.Equal(nameof(EventProcessor.OnStartRunBenchmark), events[eventIndex].EventType);\n                    Assert.Equal(methodDescriptor, (events[eventIndex++].Args[0] as BenchmarkCase)!.Descriptor.WorkloadMethod);\n\n                    Assert.Equal(nameof(EventProcessor.OnEndRunBenchmark), events[eventIndex].EventType);\n                    Assert.Equal(methodDescriptor, (events[eventIndex++].Args[0] as BenchmarkCase)!.Descriptor.WorkloadMethod);\n                }\n\n                Assert.Equal(nameof(EventProcessor.OnEndRunBenchmarksInType), events[eventIndex].EventType);\n                Assert.Equal(type, events[eventIndex++].Args[0] as Type);\n            }\n\n            Assert.Equal(nameof(EventProcessor.OnEndRunStage), events[eventIndex].EventType);\n        }\n\n        [Fact]\n        public void WhenUsingEventProcessorOnMultipleClasses()\n        {\n            var events = RunBenchmarksAndRecordEvents([typeof(ClassA), typeof(ClassB)]);\n\n            Assert.Equal(23, events.Count);\n\n            Assert.Equal(nameof(EventProcessor.OnStartValidationStage), events[0].EventType);\n            Assert.Equal(nameof(EventProcessor.OnEndValidationStage), events[1].EventType);\n            Assert.Equal(nameof(EventProcessor.OnStartBuildStage), events[2].EventType);\n            Assert.Equal(nameof(EventProcessor.OnBuildComplete), events[3].EventType);\n            Assert.Equal(nameof(EventProcessor.OnEndBuildStage), events[4].EventType);\n            Assert.Equal(nameof(EventProcessor.OnStartRunStage), events[5].EventType);\n\n            var benchmarkTypeAndMethods = new List<(Type Type, string[] MethodNames)>\n            {\n                (typeof(ClassA), new[]{ nameof(ClassA.Method1), nameof(ClassA.Method2) }),\n                (typeof(ClassB), new[]{ nameof(ClassB.Method1), nameof(ClassB.Method2), nameof(ClassB.Method3), nameof(ClassB.Method4) })\n            };\n\n            int eventIndex = 6;\n            foreach ((var type, var methodNames) in benchmarkTypeAndMethods)\n            {\n                Assert.Equal(nameof(EventProcessor.OnStartRunBenchmarksInType), events[eventIndex].EventType);\n                Assert.Equal(type, events[eventIndex++].Args[0] as Type);\n\n                foreach (var method in methodNames)\n                {\n                    var methodDescriptor = type.GetMethod(method);\n                    Assert.Equal(nameof(EventProcessor.OnStartRunBenchmark), events[eventIndex].EventType);\n                    Assert.Equal(methodDescriptor, (events[eventIndex++].Args[0] as BenchmarkCase)!.Descriptor.WorkloadMethod);\n\n                    Assert.Equal(nameof(EventProcessor.OnEndRunBenchmark), events[eventIndex].EventType);\n                    Assert.Equal(methodDescriptor, (events[eventIndex++].Args[0] as BenchmarkCase)!.Descriptor.WorkloadMethod);\n                }\n\n                Assert.Equal(nameof(EventProcessor.OnEndRunBenchmarksInType), events[eventIndex].EventType);\n                Assert.Equal(type, events[eventIndex++].Args[0] as Type);\n            }\n\n            Assert.Equal(nameof(EventProcessor.OnEndRunStage), events[eventIndex].EventType);\n        }\n\n        [Fact]\n        public void WhenUsingEventProcessorWithValidationErrors()\n        {\n            var validator = new ErrorAllCasesValidator();\n            var events = RunBenchmarksAndRecordEvents([typeof(ClassA)], validator);\n\n            Assert.Equal(15, events.Count);\n            Assert.Equal(nameof(EventProcessor.OnStartValidationStage), events[0].EventType);\n            Assert.Equal(nameof(EventProcessor.OnValidationError), events[1].EventType);\n            Assert.Equal(typeof(ClassA).GetMethod(nameof(ClassA.Method1)), (events[1].Args[0] as ValidationError)!.BenchmarkCase!.Descriptor.WorkloadMethod);\n            Assert.Equal(nameof(EventProcessor.OnValidationError), events[2].EventType);\n            Assert.Equal(typeof(ClassA).GetMethod(nameof(ClassA.Method2)), (events[2].Args[0] as ValidationError)!.BenchmarkCase!.Descriptor.WorkloadMethod);\n            Assert.Equal(nameof(EventProcessor.OnEndValidationStage), events[3].EventType);\n            Assert.Equal(nameof(EventProcessor.OnStartBuildStage), events[4].EventType);\n        }\n\n        [Fact]\n        public void WhenUsingEventProcessorWithUnsupportedBenchmark()\n        {\n            var toolchain = new AllUnsupportedToolchain();\n            var events = RunBenchmarksAndRecordEvents([typeof(ClassA)], toolchain: toolchain);\n\n            Assert.Equal(4, events.Count);\n            Assert.Equal(nameof(EventProcessor.OnStartValidationStage), events[0].EventType);\n            Assert.Equal(nameof(EventProcessor.OnValidationError), events[1].EventType);\n            Assert.Equal(typeof(ClassA).GetMethod(nameof(ClassA.Method1)), (events[1].Args[0] as ValidationError)!.BenchmarkCase!.Descriptor.WorkloadMethod);\n            Assert.Equal(nameof(EventProcessor.OnValidationError), events[2].EventType);\n            Assert.Equal(typeof(ClassA).GetMethod(nameof(ClassA.Method2)), (events[2].Args[0] as ValidationError)!.BenchmarkCase!.Descriptor.WorkloadMethod);\n            Assert.Equal(nameof(EventProcessor.OnEndValidationStage), events[3].EventType);\n        }\n\n        [Fact]\n        public void WhenUsingEventProcessorWithBuildFailures()\n        {\n            var toolchain = new Toolchain(\"Build Failure\", new AllFailsGenerator(), null!, null!);\n            var events = RunBenchmarksAndRecordEvents([typeof(ClassA)], toolchain: toolchain);\n\n            Assert.Equal(9, events.Count);\n            Assert.Equal(nameof(EventProcessor.OnStartValidationStage), events[0].EventType);\n            Assert.Equal(nameof(EventProcessor.OnEndValidationStage), events[1].EventType);\n            Assert.Equal(nameof(EventProcessor.OnStartBuildStage), events[2].EventType);\n            Assert.Equal(nameof(EventProcessor.OnBuildComplete), events[3].EventType);\n            Assert.False((events[3].Args[1] as BuildResult)!.IsGenerateSuccess);\n            Assert.Equal(nameof(EventProcessor.OnEndBuildStage), events[4].EventType);\n            Assert.Equal(nameof(EventProcessor.OnStartRunStage), events[5].EventType);\n        }\n\n        private List<LoggingEventProcessor.EventData> RunBenchmarksAndRecordEvents(Type[] types, IValidator? validator = null, IToolchain? toolchain = null)\n        {\n            var eventProcessor = new LoggingEventProcessor();\n            var job = new Job(Job.Dry);\n            if (toolchain != null)\n                job.Infrastructure.Toolchain = toolchain;\n\n            var config = new ManualConfig()\n                .AddJob(job)\n                .AddEventProcessor(eventProcessor)\n                .WithOptions(ConfigOptions.DisableOptimizationsValidator)\n                .AddExporter(new MockExporter()) // only added to prevent validation warnings about a lack of exporters\n                .AddLogger(ConsoleLogger.Default)\n                .AddColumnProvider(DefaultColumnProviders.Instance)\n                .AddAnalyser(DefaultConfig.Instance.GetAnalysers().ToArray());\n            if (validator != null)\n                config = config.AddValidator(validator);\n            _ = BenchmarkRunner.Run(types, config);\n            return eventProcessor.Events;\n        }\n\n        public class ClassA\n        {\n            [Benchmark]\n            public void Method1() { }\n            [Benchmark]\n            public void Method2() { }\n        }\n\n        public class ClassB\n        {\n            [Benchmark]\n            public void Method1() { }\n            [Benchmark]\n            public void Method2() { }\n            [Benchmark]\n            public void Method3() { }\n            [Benchmark]\n            public void Method4() { }\n        }\n\n        public class ClassEmpty { }\n\n        public class ErrorAllCasesValidator : IValidator\n        {\n            public bool TreatsWarningsAsErrors => true;\n\n            public IEnumerable<ValidationError> Validate(ValidationParameters validationParameters)\n            {\n                foreach (var benchmark in validationParameters.Benchmarks)\n                    yield return new ValidationError(false, \"Mock Validation\", benchmark);\n            }\n        }\n\n        public class AllUnsupportedToolchain : Toolchain\n        {\n            public AllUnsupportedToolchain() : base(\"AllUnsupported\", null!, null!, null!)\n            {\n            }\n\n            public override IEnumerable<ValidationError> Validate(BenchmarkCase benchmarkCase, IResolver resolver)\n            {\n                yield return new ValidationError(true, \"Unsupported Benchmark\", benchmarkCase);\n            }\n        }\n\n        public class AllFailsGenerator : IGenerator\n        {\n            public GenerateResult GenerateProject(BuildPartition buildPartition, ILogger logger, string rootArtifactsFolderPath)\n            {\n                return GenerateResult.Failure(ArtifactsPaths.Empty, [], new Exception(\"Generation Failed\"));\n            }\n        }\n\n        public class LoggingEventProcessor : EventProcessor\n        {\n            public class EventData\n            {\n                public EventData(string eventType, IReadOnlyList<object> args)\n                {\n                    EventType = eventType;\n                    Args = args;\n                }\n\n                public string EventType { get; }\n                public IReadOnlyList<object> Args { get; }\n            }\n\n            public List<EventData> Events { get; } = [];\n\n            public override void OnBuildComplete(BuildPartition buildPartition, BuildResult buildResult)\n            {\n                Events.Add(new EventData(nameof(OnBuildComplete), [buildPartition, buildResult]));\n            }\n\n            public override void OnEndRunBenchmark(BenchmarkCase benchmarkCase, BenchmarkReport report)\n            {\n                Events.Add(new EventData(nameof(OnEndRunBenchmark), [benchmarkCase, report]));\n            }\n\n            public override void OnEndRunBenchmarksInType(Type type, Summary summary)\n            {\n                Events.Add(new EventData(nameof(OnEndRunBenchmarksInType), [type, summary]));\n            }\n\n            public override void OnStartRunBenchmark(BenchmarkCase benchmarkCase)\n            {\n                Events.Add(new EventData(nameof(OnStartRunBenchmark), [benchmarkCase]));\n            }\n\n            public override void OnStartRunBenchmarksInType(Type type, IReadOnlyList<BenchmarkCase> benchmarks)\n            {\n                Events.Add(new EventData(nameof(OnStartRunBenchmarksInType), [type, benchmarks]));\n            }\n\n            public override void OnStartBuildStage(IReadOnlyList<BuildPartition> partitions)\n            {\n                Events.Add(new EventData(nameof(OnStartBuildStage), [partitions]));\n            }\n\n            public override void OnStartRunStage()\n            {\n                Events.Add(new EventData(nameof(OnStartRunStage), []));\n            }\n\n            public override void OnStartValidationStage()\n            {\n                Events.Add(new EventData(nameof(OnStartValidationStage), []));\n            }\n\n            public override void OnValidationError(ValidationError validationError)\n            {\n                Events.Add(new EventData(nameof(OnValidationError), [validationError]));\n            }\n\n            public override void OnEndValidationStage()\n            {\n                Events.Add(new EventData(nameof(OnEndValidationStage), []));\n            }\n\n            public override void OnEndBuildStage()\n            {\n                Events.Add(new EventData(nameof(OnEndBuildStage), []));\n            }\n\n            public override void OnEndRunStage()\n            {\n                Events.Add(new EventData(nameof(OnEndRunStage), []));\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/ExceptionDiagnoserTests.cs",
    "content": "﻿using BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Columns;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Diagnosers;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Running;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing Xunit;\n\nnamespace BenchmarkDotNet.IntegrationTests\n{\n    public class ExceptionDiagnoserTests\n    {\n        [Fact]\n        public void ExceptionCountIsAccurate()\n        {\n            var config = CreateConfig();\n\n            var summary = BenchmarkRunner.Run<ExceptionCount>(config);\n\n            AssertStats(summary, new Dictionary<string, (string metricName, double expectedValue)>\n            {\n                { nameof(ExceptionCount.DoNothing), (\"ExceptionFrequency\", 0.0) },\n                { nameof(ExceptionCount.ThrowOneException), (\"ExceptionFrequency\", 1.0) },\n                { nameof(ExceptionCount.ThrowFromMultipleThreads), (\"ExceptionFrequency\", 100.0) }\n            });\n        }\n\n        public class ExceptionCount\n        {\n            [Benchmark]\n            public void ThrowOneException()\n            {\n                try\n                {\n                    throw new Exception();\n                }\n                catch { }\n            }\n\n            [Benchmark]\n            public void DoNothing() { }\n\n            [Benchmark]\n            public async Task ThrowFromMultipleThreads()\n            {\n                void ThrowMultipleExceptions()\n                {\n                    for (int i = 0; i < 10; i++)\n                    {\n                        ThrowOneException();\n                    }\n                }\n\n                var tasks = Enumerable.Range(1, 10).Select(\n                    i => Task.Run(ThrowMultipleExceptions));\n                await Task.WhenAll(tasks);\n            }\n        }\n\n        private IConfig CreateConfig()\n#pragma warning disable CS0618 // WithEvaluateOverhead is obsolete\n            => ManualConfig.CreateEmpty()\n                .AddJob(Job.ShortRun\n                    .WithEvaluateOverhead(false) // no need to run idle for this test\n                    .WithWarmupCount(0) // don't run warmup to save some time for our CI runs\n                    .WithIterationCount(1)) // single iteration is enough for us\n                .AddColumnProvider(DefaultColumnProviders.Instance)\n                .AddDiagnoser(ExceptionDiagnoser.Default);\n#pragma warning restore CS0618 // WithEvaluateOverhead is obsolete\n\n        private void AssertStats(Summary summary, Dictionary<string, (string metricName, double expectedValue)> assertions)\n        {\n            foreach (var assertion in assertions)\n            {\n                var selectedReport = summary.Reports.Single(report => report.BenchmarkCase.DisplayInfo.Contains(assertion.Key));\n                var metric = selectedReport.Metrics.Single(m => m.Key == assertion.Value.metricName);\n                Assert.Equal(assertion.Value.expectedValue, metric.Value.Value);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/ExceptionHandlingTests.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Diagnosers;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Toolchains.InProcess.Emit;\nusing JetBrains.Annotations;\nusing Xunit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.IntegrationTests\n{\n    public class ExceptionHandlingTests : BenchmarkTestExecutor\n    {\n        private const string BenchmarkExceptionMessage = \"we have a problem in our benchmark method\";\n        private const string IterationCleanupExceptionMessage = \"we have a problem in our iteration cleanup method\";\n        private const string GlobalCleanupExceptionMessage = \"we have a problem in our global cleanup method\";\n\n        public ExceptionHandlingTests(ITestOutputHelper output) : base(output) { }\n\n        [Fact]\n        public void DryJobDoesNotEatExceptions()\n            => SourceExceptionMessageIsDisplayed<AlwaysThrow>(Job.Dry);\n\n        [Fact]\n        public void DryJobDoesNotEatExceptionsWhenIterationCleanupThrows()\n            => SourceExceptionMessageIsDisplayed<ThrowInBenchmarkAndInIterationCleanup>(Job.Dry);\n\n        [Fact]\n        public void DryJobDoesNotEatExceptionsWhenGlobalCleanupThrows()\n            => SourceExceptionMessageIsDisplayed<ThrowInBenchmarkAndInGlobalCleanup>(Job.Dry);\n\n        [Fact]\n        public void DefaultJobDoesNotEatExceptions()\n            => SourceExceptionMessageIsDisplayed<AlwaysThrow>(Job.Default);\n\n        [Fact]\n        public void DefaultJobDoesNotEatExceptionsWhenIterationCleanupThrows()\n            => SourceExceptionMessageIsDisplayed<ThrowInBenchmarkAndInIterationCleanup>(Job.Default);\n\n        [Fact]\n        public void DefaultJobDoesNotEatExceptionsWhenGlobalCleanupThrows()\n            => SourceExceptionMessageIsDisplayed<ThrowInBenchmarkAndInGlobalCleanup>(Job.Default);\n\n        [Fact]\n        public void DryJobWithInProcessToolchainDoesNotEatExceptions()\n            => SourceExceptionMessageIsDisplayed<AlwaysThrow>(Job.Dry.WithToolchain(InProcessEmitToolchain.Default));\n\n        [Fact]\n        public void DryJobWithInProcessToolchainDoesNotEatExceptionsWhenIterationCleanupThrows()\n            => SourceExceptionMessageIsDisplayed<ThrowInBenchmarkAndInIterationCleanup>(Job.Dry.WithToolchain(InProcessEmitToolchain.Default));\n\n        [Fact]\n        public void DryJobWithInProcessToolchainDoesNotEatExceptionsWhenGlobalCleanupThrows()\n            => SourceExceptionMessageIsDisplayed<ThrowInBenchmarkAndInGlobalCleanup>(Job.Dry.WithToolchain(InProcessEmitToolchain.Default));\n\n        [Fact]\n        public void DefaultJobWithInProcessToolchainDoesNotEatExceptions()\n            => SourceExceptionMessageIsDisplayed<AlwaysThrow>(Job.Default.WithToolchain(InProcessEmitToolchain.Default));\n\n        [Fact]\n        public void DefaultJobWithInProcessToolchainDoesNotEatExceptionsWhenIterationCleanupThrows()\n            => SourceExceptionMessageIsDisplayed<ThrowInBenchmarkAndInIterationCleanup>(Job.Default.WithToolchain(InProcessEmitToolchain.Default));\n\n        [Fact]\n        public void DefaultJobWithInProcessToolchainDoesNotEatExceptionsWhenGlobalCleanupThrows()\n            => SourceExceptionMessageIsDisplayed<ThrowInBenchmarkAndInGlobalCleanup>(Job.Default.WithToolchain(InProcessEmitToolchain.Default));\n\n        [AssertionMethod]\n        private void SourceExceptionMessageIsDisplayed<TBenchmark>(Job job)\n        {\n            var logger = new AccumulationLogger();\n            var config = ManualConfig.CreateEmpty().AddJob(job).AddLogger(logger);\n\n            CanExecute<TBenchmark>(config, fullValidation: false); // we don't validate here because the report is expected to have no results\n\n            Assert.Contains(BenchmarkExceptionMessage, logger.GetLog());\n        }\n\n        public class AlwaysThrow\n        {\n            [Benchmark] public void Throw() => throw new Exception(BenchmarkExceptionMessage);\n        }\n\n        public class ThrowInBenchmarkAndInGlobalCleanup\n        {\n            [GlobalCleanup] public void Cleanup() => throw new Exception(GlobalCleanupExceptionMessage);\n\n            [Benchmark] public void Throw() => throw new Exception(BenchmarkExceptionMessage);\n        }\n\n        public class ThrowInBenchmarkAndInIterationCleanup\n        {\n            [IterationCleanup] public void Cleanup() => throw new Exception(IterationCleanupExceptionMessage);\n\n            [Benchmark] public void Throw() => throw new Exception(BenchmarkExceptionMessage);\n        }\n\n        [Fact]\n        public void WhenOneBenchmarkThrowsTheRunnerDoesNotThrow()\n            => CanExecute<OneIsThrowing>(fullValidation: false); // we don't validate here because the report is expected to miss some results\n\n        [Fact]\n        public void WhenAllBenchmarksThrowsTheRunnerDoesNotThrow()\n            => CanExecute<AlwaysThrow>(fullValidation: false); // we don't validate here because the report is expected to have no results\n\n        public class OneIsThrowing\n        {\n            [Benchmark(Baseline = true)]\n            public void Bar1() { }\n            [Benchmark]\n            public void Bar2() => throw new Exception();\n        }\n\n        [Theory]\n        [InlineData(false)]\n        [InlineData(true)]\n        public void StopOnFirstErrorIsRespected(bool value)\n        {\n            var config = ManualConfig.CreateEmpty()\n                .AddJob(Job.Dry)\n                .AddDiagnoser(MemoryDiagnoser.Default) // crucial to repro the bug\n                .WithOption(ConfigOptions.StopOnFirstError, value);\n\n            var summary = CanExecute<MoreThanOneNonThrowingBenchmark>(config, fullValidation: false);\n\n            if (value)\n            {\n                Assert.Equal(1, summary.Reports.Count(report => !report.Success));\n            }\n            else\n            {\n                Assert.Equal(3, summary.Reports.Count(report => report.Success));\n                Assert.Equal(4, summary.Reports.Count(report => !report.Success));\n            }\n        }\n\n        public class MoreThanOneNonThrowingBenchmark\n        {\n            [Benchmark] public void Ok1() { }\n            [Benchmark] public void Throw1() => throw new Exception(BenchmarkExceptionMessage);\n            [Benchmark] public void Ok2() { }\n            [Benchmark] public void Throw2() => throw new Exception(BenchmarkExceptionMessage);\n            [Benchmark] public void Ok3() { }\n            [Benchmark] public void Throw3() => throw new Exception(BenchmarkExceptionMessage);\n            [Benchmark] public void Throw4() => throw new Exception(BenchmarkExceptionMessage);\n        }\n\n        [Fact]\n        public void DiagnosersCantCrashRunnerWhenTheyHaveNothingToParse()\n        {\n            var config = ManualConfig.CreateEmpty()\n                .AddJob(Job.Dry.WithIterationCount(10))\n                .AddDiagnoser(MemoryDiagnoser.Default); // crucial to repro the bug;\n\n            var summary = CanExecute<ThrowButNotImmediately>(config, fullValidation: false);\n\n            var benchmarkReport = summary.Reports.Single();\n            Assert.Equal(default, benchmarkReport.GcStats);\n        }\n\n        public class ThrowButNotImmediately\n        {\n            private int iterationCount;\n\n            [IterationSetup]\n            public void Setup() => ++iterationCount;\n\n            [Benchmark]\n            public void Throwing()\n            {\n                if (iterationCount >= 5)\n                {\n                    throw new Exception();\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/ExporterIOTests.cs",
    "content": "﻿using System;\nusing System.Collections.Immutable;\nusing System.IO;\nusing System.Linq;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Columns;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Exporters;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Tests.XUnit;\nusing BenchmarkDotNet.Validators;\nusing Xunit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.IntegrationTests\n{\n    public class ExporterIOTests : BenchmarkTestExecutor\n    {\n        public ExporterIOTests(ITestOutputHelper output) : base(output) { }\n\n        [Fact]\n        public void ExporterWritesToFile()\n        {\n            string resultsDirectoryPath = Path.GetTempPath();\n            var exporter = new MockExporter();\n            var mockSummary = GetMockSummary(resultsDirectoryPath, config: null);\n            var filePath = $\"{Path.Combine(mockSummary.ResultsDirectoryPath, mockSummary.Title)}-report.txt\"; // ExporterBase default\n\n            try\n            {\n                exporter.ExportToFiles(mockSummary, NullLogger.Instance);\n\n                Assert.Equal(1, exporter.ExportCount);\n                Assert.True(File.Exists(filePath));\n            }\n            finally\n            {\n                if (File.Exists(filePath))\n                    File.Delete(filePath);\n            }\n        }\n\n        [FactEnvSpecific(\"On Unix, it's possible to write to an opened file\", EnvRequirement.WindowsOnly)]\n        public void ExporterWorksWhenFileIsLocked()\n        {\n            string resultsDirectoryPath = Path.GetTempPath();\n            var exporter = new MockExporter();\n            var mockSummary = GetMockSummary(resultsDirectoryPath, config: null);\n            var filePath = $\"{Path.Combine(mockSummary.ResultsDirectoryPath, mockSummary.Title)}-report.txt\"; // ExporterBase default\n\n            try\n            {\n                exporter.ExportToFiles(mockSummary, NullLogger.Instance);\n\n                Assert.Equal(1, exporter.ExportCount);\n                Assert.True(File.Exists(filePath));\n                using (var handle = File.OpenRead(filePath)) // Gets a lock on the target file\n                {\n                    exporter.ExportToFiles(mockSummary, NullLogger.Instance);\n                    Assert.Equal(2, exporter.ExportCount);\n                }\n                var savedFiles = Directory.EnumerateFiles(Path.GetDirectoryName(filePath)!, Path.GetFileNameWithoutExtension(filePath) + \"*\");\n                Assert.Equal(2, savedFiles.Count());\n            }\n            finally\n            {\n                if (File.Exists(filePath))\n                    File.Delete(filePath);\n                var otherFiles = Directory.EnumerateFiles(Path.GetDirectoryName(filePath)!, Path.GetFileNameWithoutExtension(filePath) + \"*\");\n                foreach (var file in otherFiles)\n                    File.Delete(file);\n            }\n        }\n\n        [Fact]\n        public void ExporterUsesFullyQualifiedTypeNameAsFileName()\n        {\n            string resultsDirectoryPath = Path.GetTempPath();\n            var exporter = new MockExporter();\n            var mockSummary = GetMockSummary(resultsDirectoryPath, config: null, typeof(Generic<int>));\n            var expectedFilePath = $\"{Path.Combine(mockSummary.ResultsDirectoryPath, \"BenchmarkDotNet.IntegrationTests.Generic_Int32_\")}-report.txt\";\n            string? actualFilePath = null;\n\n            try\n            {\n                actualFilePath = exporter.ExportToFiles(mockSummary, NullLogger.Instance).First();\n\n                Assert.Equal(expectedFilePath, actualFilePath);\n            }\n            finally\n            {\n                if (File.Exists(actualFilePath))\n                    File.Delete(actualFilePath);\n            }\n        }\n\n        [Fact]\n        public void ExporterUsesSummaryTitleAsFileNameWhenBenchmarksJoinedToSingleSummary()\n        {\n            string resultsDirectoryPath = Path.GetTempPath();\n            var exporter = new MockExporter();\n            var joinConfig = ManualConfig.CreateEmpty().WithOptions(ConfigOptions.JoinSummary);\n            var mockSummary = GetMockSummary(resultsDirectoryPath, joinConfig, typeof(ClassA), typeof(ClassB));\n            var expectedFilePath = $\"{Path.Combine(mockSummary.ResultsDirectoryPath, mockSummary.Title)}-report.txt\";\n            string? actualFilePath = null;\n\n            try\n            {\n                actualFilePath = exporter.ExportToFiles(mockSummary, NullLogger.Instance).First();\n\n                Assert.Equal(expectedFilePath, actualFilePath);\n            }\n            finally\n            {\n                if (File.Exists(actualFilePath))\n                    File.Delete(actualFilePath);\n            }\n        }\n\n        private Summary GetMockSummary(string resultsDirectoryPath, IConfig? config, params Type[] typesWithBenchmarks)\n        {\n            return new Summary(\n                title: \"bdn-test\",\n                reports: typesWithBenchmarks.Length > 0 ? CreateReports(typesWithBenchmarks, config) : [],\n                hostEnvironmentInfo: Environments.HostEnvironmentInfo.GetCurrent(),\n                resultsDirectoryPath: resultsDirectoryPath,\n                logFilePath: string.Empty,\n                totalTime: System.TimeSpan.Zero,\n                cultureInfo: TestCultureInfo.Instance,\n                validationErrors: [],\n                columnHidingRules: []\n            );\n        }\n\n        private class MockExporter : ExporterBase\n        {\n            public int ExportCount;\n\n            public override void ExportToLog(Summary summary, ILogger logger)\n            {\n                ExportCount++;\n            }\n        }\n\n        private ImmutableArray<BenchmarkReport> CreateReports(Type[] types, IConfig? config = null)\n            => CreateBenchmarks(types, config).Select(CreateReport).ToImmutableArray();\n\n        private BenchmarkCase[] CreateBenchmarks(Type[] types, IConfig? config)\n        {\n            return types.SelectMany(type => BenchmarkConverter.TypeToBenchmarks(type, config).BenchmarksCases).ToArray();\n        }\n\n        private BenchmarkReport CreateReport(BenchmarkCase benchmarkCase)\n        {\n            return new BenchmarkReport(success: true,\n                                       benchmarkCase: benchmarkCase,\n                                       generateResult: null!,\n                                       buildResult: null!,\n                                       executeResults: null!,\n                                       metrics: null!);\n        }\n    }\n\n    public class Generic<T>\n    {\n        [Benchmark]\n        public void Method() { }\n    }\n}\n"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/ExtraAttributesForEntryMethodTests.cs",
    "content": "﻿using System.Threading;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Tests.XUnit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.IntegrationTests\n{\n    public class ExtraAttributesForEntryMethodTests : BenchmarkTestExecutor\n    {\n        public ExtraAttributesForEntryMethodTests(ITestOutputHelper output) : base(output)\n        {\n        }\n\n        [FactEnvSpecific(\"STAThread attribute is not respected in netcoreapp https://github.com/dotnet/coreclr/issues/13688\", EnvRequirement.FullFrameworkOnly)]\n        public void UserCanMarkBenchmarkAsRequiringSTA() => CanExecute<RequiresSTA>();\n\n        public class RequiresSTA\n        {\n            [Benchmark, System.STAThread]\n            public void CheckForSTA()\n            {\n                if (Thread.CurrentThread.GetApartmentState() != ApartmentState.STA)\n                {\n                    throw new ThreadStateException(\"The current threads apartment state is not STA\");\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/FSharpTests.cs",
    "content": "﻿using Xunit;\nusing Xunit.Abstractions;\nusing static FSharpBenchmarks;\n\nnamespace BenchmarkDotNet.IntegrationTests\n{\n    public class FSharpTests : BenchmarkTestExecutor\n    {\n        public FSharpTests(ITestOutputHelper output) : base(output) { }\n\n        [Fact]\n        public void ParamsSupportFSharpEnums() => CanExecute<EnumParamsTest>();\n\n        // #2530\n        [Fact]\n        public void FSharpAnonymousRecordIsSupported() => CanExecute<AnonymousRecordTest>();\n    }\n}\n"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/FailingProcessSpawnTests.cs",
    "content": "﻿using BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Portability;\nusing System.Linq;\nusing Xunit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.IntegrationTests\n{\n    public class FailingProcessSpawnTests : BenchmarkTestExecutor\n    {\n        public FailingProcessSpawnTests(ITestOutputHelper output) : base(output)\n        {\n        }\n\n        [Fact]\n        public void NoHangs()\n        {\n            Platform wrongPlatform = RuntimeInformation.GetCurrentPlatform() switch\n            {\n                Platform.X64 or Platform.X86 => Platform.Arm64,\n                _ => Platform.X64\n            };\n\n            if (wrongPlatform == Platform.X64 && RuntimeInformation.IsFullFramework)\n            {\n                // It seems full Framework on Arm ignores the platform and simply runs the native platform, causing this test to fail.\n                return;\n            }\n\n            var invalidPlatformJob = Job.Dry.WithPlatform(wrongPlatform);\n            var config = CreateSimpleConfig(job: invalidPlatformJob);\n\n            var summary = CanExecute<Simple>(config, fullValidation: false);\n\n            var executeResults = summary.Reports.Single().ExecuteResults.Single();\n\n            Assert.True(executeResults.FoundExecutable);\n            Assert.False(executeResults.IsSuccess);\n            Assert.NotEqual(0, executeResults.ExitCode);\n        }\n\n        public class Simple\n        {\n            [Benchmark]\n            public void DoNothing() { }\n        }\n    }\n}\n"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/GcModeTests.cs",
    "content": "﻿using System;\nusing System.Runtime;\nusing Xunit;\nusing Xunit.Abstractions;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Jobs;\n#if NETFRAMEWORK\nusing BenchmarkDotNet.Environments;\n#endif\n\nnamespace BenchmarkDotNet.IntegrationTests\n{\n    public class GcModeTests : BenchmarkTestExecutor\n    {\n        public GcModeTests(ITestOutputHelper outputHelper) : base(outputHelper) { }\n\n        private IConfig CreateConfig(GcMode gc) => ManualConfig.CreateEmpty().AddJob(new Job(Job.Dry, gc));\n\n        [Fact]\n        public void HostProcessSettingsAreCopiedByDefault()\n        {\n            var config = CreateConfig(GcMode.Default);\n\n            if (GCSettings.IsServerGC)\n                CanExecute<ServerModeEnabled>(config);\n            else\n                CanExecute<WorkstationGcOnly>(config);\n        }\n\n        [Fact]\n        public void CanEnableServerGcMode()\n        {\n            var config = CreateConfig(new GcMode { Server = true });\n            CanExecute<ServerModeEnabled>(config);\n        }\n\n        [Fact]\n        public void CanDisableServerGcMode()\n        {\n            var config = CreateConfig(new GcMode { Server = false });\n            CanExecute<WorkstationGcOnly>(config);\n        }\n\n        [Fact]\n        public void CanEnableConcurrentGcMode()\n        {\n            var config = CreateConfig(new GcMode { Concurrent = true });\n            CanExecute<ConcurrentModeEnabled>(config);\n        }\n\n        [Fact]\n        public void CanDisableConcurrentGcMode()\n        {\n            var config = CreateConfig(new GcMode { Concurrent = false });\n            CanExecute<ConcurrentModeDisabled>(config);\n        }\n\n        [Fact]\n        public void CanAvoidForcingGarbageCollections()\n        {\n            var config = CreateConfig(new GcMode { Force = false });\n            CanExecute<AvoidForcingGarbageCollection>(config);\n        }\n\n#if NETFRAMEWORK // not supported by project.json so far\n        [Fact]\n        public void CanAllowToCreateVeryLargeObjectsFor64Bit()\n        {\n            var config = ManualConfig.CreateEmpty().AddJob(\n                new Job(Job.Dry)\n                {\n                    Environment =\n                    {\n                        Platform = Platform.X64,\n                        Gc =\n                        {\n                            AllowVeryLargeObjects = true\n                        }\n                    }\n                });\n\n            CanExecute<CreateVeryLargeObjects>(config);\n        }\n#endif\n    }\n\n    public class ServerModeEnabled\n    {\n        [Benchmark]\n        public void Benchmark()\n        {\n            if (GCSettings.IsServerGC == false)\n            {\n                throw new InvalidOperationException(\"Did not enable GC Server mode\");\n            }\n        }\n    }\n\n    public class WorkstationGcOnly\n    {\n        [Benchmark]\n        public void Benchmark()\n        {\n            if (GCSettings.IsServerGC)\n            {\n                throw new InvalidOperationException(\"Did not disable GC Server mode\");\n            }\n        }\n    }\n\n    public class ConcurrentModeEnabled\n    {\n        [Benchmark]\n        public void Benchmark()\n        {\n            if (GCSettings.LatencyMode == GCLatencyMode.Batch)\n            {\n                throw new InvalidOperationException(\"Did not enable Concurrent GC mode\");\n            }\n        }\n    }\n\n    public class ConcurrentModeDisabled\n    {\n        [Benchmark]\n        public void Benchmark()\n        {\n            if (GCSettings.LatencyMode != GCLatencyMode.Batch)\n            {\n                throw new InvalidOperationException(\"Did not disable Concurrent GC mode\");\n            }\n        }\n    }\n\n    public class AvoidForcingGarbageCollection\n    {\n        private int initialCollectionCountGen1;\n        private int initialCollectionCountGen2;\n\n        [GlobalSetup]\n        public void GlobalSetup()\n        {\n            initialCollectionCountGen1 = GC.CollectionCount(1);\n            initialCollectionCountGen2 = GC.CollectionCount(2);\n        }\n\n        [Benchmark]\n        public void Benchmark()\n        {\n            if (initialCollectionCountGen1 != GC.CollectionCount(1)\n                || initialCollectionCountGen2 != GC.CollectionCount(2))\n            {\n                throw new InvalidOperationException(\"Did not disable GC Force\");\n            }\n        }\n    }\n\n    public class CreateVeryLargeObjects\n    {\n        [Benchmark]\n        public long[] Benchmark()\n        {\n            return new long[2147483648 / sizeof(long)]; // 2GB is the default limit\n        }\n    }\n\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/GlobalSetupAttributeInvalidMethodTest.cs",
    "content": "﻿using System;\nusing System.Threading;\nusing BenchmarkDotNet.Attributes;\nusing Xunit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.IntegrationTests\n{\n    public class GlobalSetupAttributeInvalidMethodTest : BenchmarkTestExecutor\n    {\n        public GlobalSetupAttributeInvalidMethodTest(ITestOutputHelper output) : base(output) { }\n\n        [Fact]\n        public void GlobalSetupAttributeMethodsMustHaveNoParameters()\n        {\n            var summary = CanExecute<GlobalSetupAttributeInvalidMethod>(fullValidation: false);\n            Assert.Equal(\"GlobalSetup method GlobalSetup has incorrect signature.\\nMethod shouldn't have any arguments.\", summary.Title);\n        }\n\n        public class GlobalSetupAttributeInvalidMethod\n        {\n            [GlobalSetup]\n            public void GlobalSetup(int someParameters) // [GlobalSetup] methods must have no parameters\n            {\n                Console.WriteLine(\"// ### GlobalSetup called ###\");\n            }\n\n            [Benchmark]\n            public void Benchmark()\n            {\n                Thread.Sleep(5);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/InProcess.EmitTests/NaiveRunnableEmitDiff.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing BenchmarkDotNet.Loggers;\nusing Mono.Cecil;\nusing Mono.Cecil.Cil;\nusing Mono.Collections.Generic;\n\nnamespace BenchmarkDotNet.IntegrationTests.InProcess.EmitTests\n{\n    public class NaiveRunnableEmitDiff\n    {\n        private static readonly HashSet<string> IgnoredTypeNames =\n        [\n            \"BenchmarkDotNet.Autogenerated.UniqueProgramName\",\n            \"BenchmarkDotNet.Autogenerated.DirtyAssemblyResolveHelper\", // not required to be used in the InProcess toolchains (it's already used in the host process)\n            \"System.Diagnostics.CodeAnalysis.SetsRequiredMembersAttribute\", // Conditionally added in runtimes older than .Net 7.\n            \"System.Runtime.CompilerServices.CompilerFeatureRequiredAttribute\",\n            \"System.Runtime.CompilerServices.RequiredMemberAttribute\"\n        ];\n\n        private static readonly HashSet<string> IgnoredAttributeTypeNames =\n        [\n            \"System.Runtime.CompilerServices.CompilerGeneratedAttribute\"\n        ];\n\n        private static readonly HashSet<string> IgnoredRunnableMethodNames =\n        [\n            \"Run\",\n            \".ctor\"\n        ];\n\n        private static readonly IReadOnlyDictionary<OpCode, OpCode> AltOpCodes = new Dictionary<OpCode, OpCode>()\n        {\n            { OpCodes.Br_S, OpCodes.Br },\n            { OpCodes.Blt_S, OpCodes.Blt },\n            { OpCodes.Bne_Un_S, OpCodes.Bne_Un },\n            { OpCodes.Bge_S, OpCodes.Bge }\n        };\n\n        public static void RunDiff(string roslynAssemblyPath, string emittedAssemblyPath, ILogger logger)\n        {\n            using (var roslynAssemblyDefinition = AssemblyDefinition.ReadAssembly(roslynAssemblyPath))\n            using (var emittedAssemblyDefinition = AssemblyDefinition.ReadAssembly(emittedAssemblyPath))\n            {\n                Diff(roslynAssemblyDefinition, emittedAssemblyDefinition, logger);\n            }\n\n            // all checks have passed, so we can remove the files to avoid \"file in use\" problems\n            System.IO.File.Delete(roslynAssemblyPath);\n            System.IO.File.Delete(emittedAssemblyPath);\n        }\n\n        private static bool IsRunnable(TypeReference t) =>\n            t.FullName.StartsWith(\"BenchmarkDotNet.Autogenerated.Runnable_\");\n\n        private static bool AreSameTypeIgnoreNested(TypeReference left, TypeReference right)\n        {\n            if (left == null)\n                return right == null;\n            if (right == null)\n                return false;\n\n            return left.FullName.Replace(\"/\", \"\").Replace(\".ReplaceMe.\", \".\") ==\n                   right.FullName.Replace(\"/\", \"\").Replace(\".ReplaceMe.\", \".\");\n        }\n\n        private static bool AreSameSignature(MethodReference left, MethodReference right)\n        {\n            return (left.Name == right.Name || (left.Name.StartsWith(\"<.ctor>\") && right.Name == \"__Workload\"))\n                && AreSameTypeIgnoreNested(left.ReturnType, right.ReturnType)\n                && left.Parameters.Count == right.Parameters.Count\n                && left.Parameters\n                    .Zip(right.Parameters, (p1, p2) => (p1, p2))\n                    .All(p => AreSameTypeIgnoreNested(p.p1.ParameterType, p.p2.ParameterType));\n        }\n\n        private static List<Instruction> GetOpInstructions(MethodDefinition method)\n        {\n            var bodyInstructions = method.Body.GetILProcessor().Body.Instructions;\n\n            // There's something wrong with ldloc/ldarg with index >= 255. The c# compiler emits random nops for them.\n            var compareNops = method.Body.Variables.Count < 255 && method.Parameters.Count < 255;\n            var result = new List<Instruction>(bodyInstructions.Count);\n            foreach (var instruction in bodyInstructions)\n            {\n                if (compareNops || instruction.OpCode != OpCodes.Nop)\n                    result.Add(instruction);\n            }\n\n            return result;\n        }\n\n        private static void DiffSignature(TypeReference left, TypeReference? right)\n        {\n            if (right == null)\n                throw new InvalidOperationException($\"No matching type for {left}\");\n\n            if (!AreSameTypeIgnoreNested(left, right))\n                throw new InvalidOperationException($\"No matching type for {left}\");\n        }\n\n        private static void DiffSignature(FieldReference left, FieldReference right)\n        {\n            if (right == null)\n                throw new InvalidOperationException($\"No matching field for {left.FullName}\");\n\n            if (!AreSameTypeIgnoreNested(left.FieldType, right.FieldType))\n                throw new InvalidOperationException($\"No matching field for {left.FullName}\");\n\n            if (!AreSameTypeIgnoreNested(left.DeclaringType, right.DeclaringType))\n                throw new InvalidOperationException($\"No matching field for {left.FullName}\");\n        }\n\n        private static void DiffSignature(MethodReference left, MethodReference right)\n        {\n            if (right == null)\n                throw new InvalidOperationException($\"No matching method for {left}\");\n\n            if (!AreSameSignature(left, right))\n                throw new InvalidOperationException($\"No matching method for {left}\");\n\n            if (!AreSameTypeIgnoreNested(left.DeclaringType, right.DeclaringType))\n                throw new InvalidOperationException($\"No matching method for {left}\");\n        }\n\n        private static void DiffSignature(ParameterDefinition left, ParameterDefinition right)\n        {\n            if (left.Name != right.Name)\n                throw new InvalidOperationException($\"No matching parameter for {left.Name} ({left.Method})\");\n\n            if (!AreSameTypeIgnoreNested(left.ParameterType, right.ParameterType))\n                throw new InvalidOperationException($\"No matching parameter for {left.Name} ({left.Method})\");\n\n            if (left.Attributes != right.Attributes)\n                throw new InvalidOperationException($\"No matching parameter for {left.Name} ({left.Method})\");\n        }\n\n        private static void DiffSignature(Instruction left, Instruction right, MethodDefinition method)\n        {\n            if (left.OpCode != right.OpCode)\n            {\n                if (!AltOpCodes.TryGetValue(left.OpCode, out var altOpCode1) || altOpCode1 != right.OpCode)\n                    throw new InvalidOperationException($\"No matching op for {left} ({method}).\");\n            }\n            else if (left.GetSize() != right.GetSize())\n            {\n                throw new InvalidOperationException($\"No matching op for {left} ({method}).\");\n            }\n\n            if (left.Operand == null && right.Operand != null)\n                throw new InvalidOperationException($\"No matching op for {left} ({method}).\");\n\n            if (left.Operand != null && right.Operand == null)\n                throw new InvalidOperationException($\"No matching op for {left} ({method}).\");\n        }\n\n        private static void DiffSignature(VariableDefinition left, VariableDefinition right, MethodDefinition method)\n        {\n            if (left.Index != right.Index)\n                throw new InvalidOperationException($\"No matching variable for {left} ({method}).\");\n\n            if (left.IsPinned != right.IsPinned)\n                throw new InvalidOperationException($\"No matching variable for {left} ({method}).\");\n\n            if (!AreSameTypeIgnoreNested(left.VariableType, right.VariableType))\n                throw new InvalidOperationException($\"No matching variable for {left} ({method}).\");\n        }\n\n        private static void Diff(\n            Collection<CustomAttribute> left,\n            Collection<CustomAttribute> right,\n            ICustomAttributeProvider owner)\n        {\n            var attributes2ByTypeName = right.ToLookup(a => a.AttributeType.FullName);\n            foreach (var attribute1 in left)\n            {\n                var attribute2 = attributes2ByTypeName[attribute1.AttributeType.FullName].FirstOrDefault();\n                Diff(attribute1, attribute2, owner);\n            }\n        }\n\n        private static void Diff(CustomAttribute left, CustomAttribute? right, ICustomAttributeProvider owner)\n        {\n            if (IgnoredAttributeTypeNames.Contains(left.AttributeType.FullName) && right == null)\n                return;\n\n            if (right == null)\n                throw new InvalidOperationException($\"No matching attribute for {left.AttributeType} ({owner})\");\n\n            if (!AreSameTypeIgnoreNested(left.AttributeType, right.AttributeType))\n                throw new InvalidOperationException($\"No matching attribute for {left.AttributeType} ({owner})\");\n\n            if (left.ConstructorArguments.Count != right.ConstructorArguments.Count)\n                throw new InvalidOperationException($\"No matching attribute for {left.AttributeType} ({owner})\");\n\n            for (int i = 0; i < left.ConstructorArguments.Count; i++)\n            {\n                var attArg1 = left.ConstructorArguments[i];\n                var attArg2 = right.ConstructorArguments[i];\n\n                if (!AreSameTypeIgnoreNested(attArg1.Type, attArg2.Type))\n                    throw new InvalidOperationException($\"No matching attribute for {left.AttributeType} ({owner})\");\n\n                if (!Equals(attArg1.Value, attArg2.Value))\n                    throw new InvalidOperationException($\"No matching attribute for {left.AttributeType} ({owner})\");\n            }\n        }\n\n        private static void Diff(\n            AssemblyDefinition roslynAssemblyDefinition,\n            AssemblyDefinition emittedAssemblyDefinition,\n            ILogger logger)\n        {\n            Diff(roslynAssemblyDefinition.CustomAttributes, emittedAssemblyDefinition.CustomAttributes, roslynAssemblyDefinition);\n\n            var modules2ByName = emittedAssemblyDefinition.Modules.ToLookup(m => m.Name);\n            foreach (var module1 in roslynAssemblyDefinition.Modules)\n            {\n                var module2 = modules2ByName[module1.Name].SingleOrDefault();\n                if (module2 == null && module1.IsMain)\n                    module2 = emittedAssemblyDefinition.MainModule;\n\n                Diff(module1, module2!, logger);\n            }\n        }\n\n        private static void Diff(ModuleDefinition module1, ModuleDefinition module2, ILogger logger)\n        {\n            Diff(module1.CustomAttributes, module2.CustomAttributes, module1);\n\n            foreach (var type1 in module1.Types)\n            {\n                var type2 = module2.Types.SingleOrDefault(t => AreSameTypeIgnoreNested(type1, t));\n\n                Diff(type1, type2, logger);\n            }\n        }\n\n        private static void Diff(TypeDefinition type1, TypeDefinition? type2, ILogger logger)\n        {\n            try\n            {\n                logger.WriteStatistic($\"Diff {type1.FullName}\");\n\n                if (IgnoredTypeNames.Contains(type1.FullName) && type2 == null)\n                {\n                    logger.WriteLineInfo(\" SKIPPED.\");\n                    return;\n                }\n\n                logger.WriteLine();\n\n                DiffDefinition(type1, type2);\n\n                DiffMembers(type1, type2!, logger);\n            }\n            catch (Exception ex)\n            {\n                logger.WriteLineError(ex.ToString());\n                throw;\n            }\n        }\n\n        private static void DiffDefinition(TypeDefinition type1, TypeDefinition? type2)\n        {\n            DiffSignature(type1, type2);\n\n            if (!AreSameTypeIgnoreNested(type1.BaseType, type2!.BaseType))\n                throw new InvalidOperationException($\"No matching type for {type1.FullName}\");\n\n            if (!AreSameTypeIgnoreNested(type1.DeclaringType, type2.DeclaringType))\n                throw new InvalidOperationException($\"No matching type for {type1.FullName}\");\n\n            if (type1.Attributes != type2.Attributes)\n                throw new InvalidOperationException($\"No matching type for {type1.FullName}\");\n\n            Diff(type1.CustomAttributes, type2.CustomAttributes, type1);\n        }\n\n        private static void DiffMembers(TypeDefinition type1, TypeDefinition type2, ILogger logger)\n        {\n            var fields2ByName = type2.Fields.ToLookup(f => f.Name);\n            foreach (var field1 in type1.Fields)\n            {\n                logger.Write($\"    field {field1.FullName}\");\n\n                var field2 = fields2ByName[field1.Name].SingleOrDefault();\n                Diff(field1, field2);\n\n                logger.WriteLineHelp(\" OK.\");\n            }\n\n            var methods2ByName = type2.Methods.ToLookup(f => f.Name);\n            foreach (var method1 in type1.Methods)\n            {\n                logger.Write($\"    method {method1.FullName}\");\n\n                var method2 = methods2ByName[method1.Name].SingleOrDefault(m => AreSameSignature(method1, m));\n                if (method2 == null)\n                    method2 = type2.Methods.SingleOrDefault(m => AreSameSignature(method1, m));\n                if (method2 == null)\n                    method2 = methods2ByName[method1.Name].SingleOrDefault();\n\n                if (Diff(method1, method2!))\n                    logger.WriteLineHelp(\" OK.\");\n                else\n                    logger.WriteLineInfo(\" SKIPPED.\");\n            }\n        }\n\n        private static void Diff(FieldDefinition field1, FieldDefinition? field2)\n        {\n            DiffSignature(field1, field1);\n\n            if (field1.Attributes != field2!.Attributes)\n                throw new InvalidOperationException($\"No matching field for {field1.FullName}\");\n\n            Diff(field1.CustomAttributes, field2.CustomAttributes, field1);\n        }\n\n        private static bool Diff(MethodDefinition method1, MethodDefinition method2)\n        {\n            if (IsRunnable(method1.DeclaringType) && IgnoredRunnableMethodNames.Contains(method1.Name))\n            {\n                return false;\n            }\n\n            DiffDefinition(method1, method2);\n\n            DiffVariables(method1, method2);\n\n            DiffBody(method1, method2);\n\n            return true;\n        }\n\n        private static void DiffDefinition(MethodDefinition method1, MethodDefinition method2)\n        {\n            DiffSignature(method1, method2);\n\n            if (method1.Attributes != method2.Attributes)\n                throw new InvalidOperationException($\"No matching method for {method1}\");\n\n            if (method1.ImplAttributes != method2.ImplAttributes)\n                throw new InvalidOperationException($\"No matching method for {method1}\");\n\n            if (method1.Parameters.Count != method2.Parameters.Count)\n                throw new InvalidOperationException($\"No matching method for {method1}\");\n\n            for (int i = 0; i < method1.Parameters.Count; i++)\n            {\n                var parameter1 = method1.Parameters[i];\n                var parameter2 = method2.Parameters[i];\n                Diff(parameter1, parameter2);\n            }\n\n            Diff(method1.MethodReturnType, method2.MethodReturnType);\n\n            Diff(method1.CustomAttributes, method2.CustomAttributes, method1);\n        }\n\n        private static void Diff(ParameterDefinition parameter1, ParameterDefinition parameter2)\n        {\n            DiffSignature(parameter1, parameter2);\n\n            Diff(parameter1.CustomAttributes, parameter2.CustomAttributes, parameter1);\n        }\n\n        private static void Diff(MethodReturnType returnType1, MethodReturnType returnType2)\n        {\n            if (!AreSameTypeIgnoreNested(returnType1.ReturnType, returnType2.ReturnType))\n                throw new InvalidOperationException($\"No matching method for {returnType1.Method}\");\n\n            if (returnType1.Attributes != returnType2.Attributes)\n                throw new InvalidOperationException($\"No matching method for {returnType1.Method}\");\n\n            Diff(returnType1.CustomAttributes, returnType2.CustomAttributes, returnType1);\n        }\n\n        private static void DiffVariables(MethodDefinition method1, MethodDefinition method2)\n        {\n            var variables1 = method1.Body.Variables.ToList();\n            var variables2 = method2.Body.Variables.ToList();\n            var diffMax = Math.Min(variables1.Count, variables2.Count);\n\n            for (var i = 0; i < diffMax; i++)\n            {\n                DiffSignature(variables1[i], variables2[i], method1);\n            }\n\n            if (variables1.Count > diffMax)\n                throw new InvalidOperationException($\"There are additional variables in {method1}.\");\n\n            if (variables2.Count > diffMax)\n                throw new InvalidOperationException($\"There are additional variables in {method2}.\");\n        }\n\n        private static void DiffBody(MethodDefinition method1, MethodDefinition method2)\n        {\n            var instructions1 = GetOpInstructions(method1);\n            var instructions2 = GetOpInstructions(method2);\n            var diffMax = Math.Min(instructions1.Count, instructions2.Count);\n\n            var op2ToOp1Map = instructions1.Take(diffMax)\n                .Zip(\n                    instructions2.Take(diffMax),\n                    (i1, i2) => (i1, i2))\n                .ToDictionary(x => x.i2, x => x.i1);\n\n            for (var i = 0; i < diffMax; i++)\n            {\n                Diff(instructions1[i], instructions2[i], method1, op2ToOp1Map);\n            }\n\n            if (instructions1.Count > diffMax)\n                throw new InvalidOperationException($\"There are additional instructions in {method1}.\");\n\n            if (instructions2.Count > diffMax)\n                throw new InvalidOperationException($\"There are additional instructions in {method2}.\");\n        }\n\n        private static void Diff(Instruction op1, Instruction op2, MethodDefinition method1, Dictionary<Instruction, Instruction> op2ToOp1Map)\n        {\n            DiffSignature(op1, op2, method1);\n\n            if (op1.Operand == null)\n            {\n                // Do nothing\n            }\n            else if (op1.Operand is TypeReference tr)\n            {\n                DiffSignature(tr, (TypeReference)op2.Operand);\n            }\n            else if (op1.Operand is FieldReference fr)\n            {\n                DiffSignature(fr, (FieldReference)op2.Operand);\n            }\n            else if (op1.Operand is MethodReference mr)\n            {\n                DiffSignature(mr, (MethodReference)op2.Operand);\n            }\n            else if (op1.Operand is ParameterDefinition p)\n            {\n                DiffSignature(p, (ParameterDefinition)op2.Operand);\n            }\n            else if (op1.Operand is VariableDefinition v)\n            {\n                DiffSignature(v, (VariableDefinition)op2.Operand, method1);\n            }\n            else if (op1.Operand is Instruction i)\n            {\n                op2ToOp1Map.TryGetValue((Instruction)op2.Operand, out var expectedOp1Operand);\n                if (i != expectedOp1Operand)\n                    throw new InvalidOperationException($\"No matching op for {op1} ({method1}).\");\n            }\n            else if (!Equals(op1.Operand, op2.Operand))\n                throw new InvalidOperationException($\"No matching op for {op1} ({method1}).\");\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/InProcess.EmitTests/RunnableTestCasesHelperTypes.cs",
    "content": "﻿using System;\nusing System.Runtime.CompilerServices;\n// ReSharper disable UnusedMember.Global\n\nnamespace BenchmarkDotNet.IntegrationTests.InProcess.EmitTests\n{\n    public enum CustomEnumNonConsumable\n    {\n    }\n\n    public enum CustomEnumConsumable\n    {\n        Default = 0\n    }\n\n\n    public struct CustomStructNonConsumable\n    {\n    }\n\n    public struct CustomStructConsumable\n    {\n        public int Value;\n    }\n\n    public struct CustomStructConsumable<T>\n    {\n        public required T? Value;\n    }\n\n    public class CustomClassConsumable\n    {\n    }\n\n    public class CustomClassConsumable<T>\n    {\n        public required T? Value;\n    }\n\n    public struct CustomAwaitableStruct\n    {\n        public CustomAwaiterStruct GetAwaiter() => new CustomAwaiterStruct();\n    }\n\n    public struct CustomAwaitableStruct2\n    {\n        public CustomAwaiterClass GetAwaiter() => new CustomAwaiterClass();\n    }\n\n    public struct CustomAwaitableClass\n    {\n        public CustomAwaiterStruct GetAwaiter() => new CustomAwaiterStruct();\n    }\n\n    public struct CustomAwaitableClass2\n    {\n        public CustomAwaiterClass GetAwaiter() => new CustomAwaiterClass();\n    }\n\n    public struct CustomAwaiterStruct : INotifyCompletion\n    {\n        public bool IsCompleted => true;\n        public double GetResult() => 0;\n\n        public void OnCompleted(Action continuation)\n        {\n        }\n    }\n\n    public class CustomAwaiterClass : INotifyCompletion\n    {\n        public bool IsCompleted => true;\n        public double GetResult() => 0;\n\n        public void OnCompleted(Action continuation)\n        {\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/InProcess.EmitTests/Runnable_0.cs",
    "content": "﻿using BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Toolchains.InProcess.Emit.Implementation;\nusing BenchmarkDotNet.Toolchains.Parameters;\n\n// ReSharper disable once CheckNamespace\nnamespace BenchmarkDotNet.Autogenerated.ReplaceMe\n{\n    // Stub for diff for RunMethod\n    // Used as a template for EmitRunMethod()\n    internal class Runnable_0\n    {\n        public static void Run(IHost host, ExecuteParameters parameters)\n        {\n            var instance = new Runnable_0();\n\n            var (job, engineParameters, engineFactory) = RunnableReuse.PrepareForRun(instance, host, parameters);\n\n            if (job == null)\n                return;\n\n            var results = engineFactory.Create(engineParameters).Run();\n            host.ReportResults(results); // printing costs memory, do this after runs\n\n            instance.__TrickTheJIT__(); // compile the method for disassembler, but without actual run of the benchmark ;)\n            engineParameters.InProcessDiagnoserHandler.Handle(BenchmarkSignal.AfterEngine);\n        }\n\n        public void __TrickTheJIT__()\n        {\n            throw new System.NotImplementedException();\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/InProcess.EmitTests/SampleBenchmark.cs",
    "content": "﻿using System;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing BenchmarkDotNet.Attributes;\n\nnamespace BenchmarkDotNet.IntegrationTests.InProcess.EmitTests\n{\n    public class SampleBenchmark\n    {\n        [GlobalSetup] public void GlobalSetup() { }\n\n        [IterationSetup] public void IterationSetup() { }\n\n        [IterationCleanup] public void IterationCleanup() { }\n\n        [GlobalCleanup] public void GlobalCleanup() { }\n\n        [Benchmark]\n        public void VoidNoParamsCase()\n        {\n            Thread.Sleep(100);\n        }\n\n        [Benchmark, Arguments(1)]\n        public string ReturnSingleArgCase(int i)\n        {\n            Thread.Sleep(100);\n            return i.ToString();\n        }\n\n        [Benchmark, Arguments(123.0, 4, \"5\", null)]\n        public CustomStructNonConsumable ReturnManyArgsCase(ref double i, int j, string k, object l)\n        {\n            Thread.Sleep(100);\n            return default;\n        }\n\n        private int refValueHolder;\n\n        [Benchmark, Arguments(123.0, 4, \"5\", null)]\n        public ref int RefReturnManyArgsCase(ref double i, int j, string k, object l)\n        {\n            Thread.Sleep(100);\n            return ref refValueHolder;\n        }\n\n        [Benchmark]\n        public unsafe int* ReturnsIntPointer()\n        {\n            Thread.Sleep(100);\n            return default;\n        }\n\n        [Benchmark]\n        public unsafe void* ReturnsVoidPointer()\n        {\n            Thread.Sleep(100);\n            return default;\n        }\n\n        [Benchmark]\n        public unsafe CustomStructNonConsumable* ReturnsStructPointer()\n        {\n            Thread.Sleep(100);\n            return default;\n        }\n\n        [Benchmark, Arguments(12)]\n        public Task<int> TaskSample(long arg)\n        {\n            Thread.Sleep(100);\n            return Task.FromResult(0);\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/InProcess.EmitTests.T4/RunnableClassCaseBenchmark.cs",
    "content": "﻿//------------------------------------------------------------------------------\n// <auto-generated>\n//     This code was generated by a tool.\n//\n//     Changes to this file may cause incorrect behavior and will be lost if\n//     the code is regenerated.\n// </auto-generated>\n//------------------------------------------------------------------------------\n\nusing BenchmarkDotNet.Attributes;\n\nnamespace BenchmarkDotNet.IntegrationTests.InProcess.EmitTests\n{\n    /// <summary>\n    /// Generated class to check emitted msil cases\n    /// </summary>\n    public class RunnableClassCaseBenchmark\n    {\n        // ---- Begin ClassCase(string) ----\n\n        private string _refResultHolder1;\n\n        [Benchmark]\n        public string ClassCase1() => default;\n\n        [Benchmark, Arguments(null, \"1\", 0.1)]\n        public string ClassCase1(string x, ref string y, double? z) => default;\n\n        [Benchmark]\n        public ref string RefReturnClassCase1() => ref _refResultHolder1;\n\n        [Benchmark, Arguments(null, \"1\", 0.1)]\n        public ref string RefReturnClassCase1(string x, ref string y, double? z) => ref _refResultHolder1;\n\n        // ---- Begin ClassCase(CustomClassConsumable<int>) ----\n\n        private CustomClassConsumable<int> _refResultHolder2;\n\n        [Benchmark]\n        public CustomClassConsumable<int> ClassCase2() => default;\n\n        [Benchmark, Arguments(null, \"2\", 0.2)]\n        public CustomClassConsumable<int> ClassCase2(CustomClassConsumable<int> x, ref string y, double? z) => default;\n\n        [Benchmark]\n        public ref CustomClassConsumable<int> RefReturnClassCase2() => ref _refResultHolder2;\n\n        [Benchmark, Arguments(null, \"2\", 0.2)]\n        public ref CustomClassConsumable<int> RefReturnClassCase2(CustomClassConsumable<int> x, ref string y, double? z) => ref _refResultHolder2;\n\n        // ---- Begin ClassCase(CustomClassConsumable<string>) ----\n\n        private CustomClassConsumable<string> _refResultHolder3;\n\n        [Benchmark]\n        public CustomClassConsumable<string> ClassCase3() => default;\n\n        [Benchmark, Arguments(null, \"3\", 0.3)]\n        public CustomClassConsumable<string> ClassCase3(CustomClassConsumable<string> x, ref string y, double? z) => default;\n\n        [Benchmark]\n        public ref CustomClassConsumable<string> RefReturnClassCase3() => ref _refResultHolder3;\n\n        [Benchmark, Arguments(null, \"3\", 0.3)]\n        public ref CustomClassConsumable<string> RefReturnClassCase3(CustomClassConsumable<string> x, ref string y, double? z) => ref _refResultHolder3;\n\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/InProcess.EmitTests.T4/RunnableClassCaseBenchmark.tt",
    "content": "﻿<#@ template debug=\"false\" hostspecific=\"false\" language=\"C#\" #>\n<#@ assembly name=\"System.Core\" #>\n<#@ output extension=\".cs\" #>\n//------------------------------------------------------------------------------\n// <auto-generated>\n//     This code was generated by a tool.\n//\n//     Changes to this file may cause incorrect behavior and will be lost if\n//     the code is regenerated.\n// </auto-generated>\n//------------------------------------------------------------------------------\n\nusing BenchmarkDotNet.Attributes;\n\nnamespace BenchmarkDotNet.IntegrationTests.InProcess.EmitTests\n{\n    /// <summary>\n    /// Generated class to check emitted msil cases\n    /// </summary>\n    public class RunnableClassCaseBenchmark\n    {\n<#\n    int counter = 1;\n    EmitClassCaseBenchmark(ref counter, \"string\");\n    EmitClassCaseBenchmark(ref counter, \"CustomClassConsumable<int>\");\n    EmitClassCaseBenchmark(ref counter, \"CustomClassConsumable<string>\");\n#>\n    }\n}<#+\n\n    private void EmitClassCaseBenchmark(ref int counter, string type)\n    {\n        var argValue = \"null\";\n#>\n        // ---- Begin ClassCase(<#=type#>) ----\n\n        private <#=type#> _refResultHolder<#=counter#>;\n\n        [Benchmark]\n        public <#=type#> ClassCase<#=counter#>() => default;\n\n        [Benchmark, Arguments(<#=argValue#>, \"<#=counter#>\", 0.<#=counter#>)]\n        public <#=type#> ClassCase<#=counter#>(<#=type#> x, ref string y, double? z) => default;\n\n        [Benchmark]\n        public ref <#=type#> RefReturnClassCase<#=counter#>() => ref _refResultHolder<#=counter#>;\n\n        [Benchmark, Arguments(<#=argValue#>, \"<#=counter#>\", 0.<#=counter#>)]\n        public ref <#=type#> RefReturnClassCase<#=counter#>(<#=type#> x, ref string y, double? z) => ref _refResultHolder<#=counter#>;\n\n<#+\n        counter++;\n    }\n#>\n"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/InProcess.EmitTests.T4/RunnableManyArgsCaseBenchmark.cs",
    "content": "﻿//------------------------------------------------------------------------------\n// <auto-generated>\n//     This code was generated by a tool.\n//\n//     Changes to this file may cause incorrect behavior and will be lost if\n//     the code is regenerated.\n// </auto-generated>\n//------------------------------------------------------------------------------\n\nusing BenchmarkDotNet.Attributes;\n\nusing System;\nusing System.Threading.Tasks;\n\nnamespace BenchmarkDotNet.IntegrationTests.InProcess.EmitTests\n{\n    /// <summary>\n    /// Generated class to check emitted msil cases\n    /// </summary>\n    public class RunnableManyArgsCaseBenchmark\n    {\n        // ---- Begin ManyArgsCase(string x 4) ----        \n\n        private string _refResultHolder4;\n        \n        [Benchmark, Arguments(\"\", \"\", \"\", \"\")]\n        public string ManyArgsCase4(string arg0, string arg1, string arg2, string arg3) => default;\n\n        [Benchmark, Arguments(\"\", \"\", \"\", \"\")]\n        public Task ManyArgsTaskCase4(string arg0, string arg1, string arg2, string arg3) => Task.CompletedTask;\n\n        [Benchmark, Arguments(\"\", \"\", \"\", \"\")]\n        public ref string RefReturnManyArgsCase4(ref string arg0, ref string arg1, ref string arg2, ref string arg3) => ref _refResultHolder4;\n        // ---- Begin ManyArgsCase(int x 16) ----        \n\n        private int _refResultHolder16;\n        \n        [Benchmark, Arguments(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)]\n        public int ManyArgsCase16(int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7, int arg8, int arg9, int arg10, int arg11, int arg12, int arg13, int arg14, int arg15) => default;\n\n        [Benchmark, Arguments(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)]\n        public Task ManyArgsTaskCase16(int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7, int arg8, int arg9, int arg10, int arg11, int arg12, int arg13, int arg14, int arg15) => Task.CompletedTask;\n\n        [Benchmark, Arguments(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)]\n        public ref int RefReturnManyArgsCase16(ref int arg0, ref int arg1, ref int arg2, ref int arg3, ref int arg4, ref int arg5, ref int arg6, ref int arg7, ref int arg8, ref int arg9, ref int arg10, ref int arg11, ref int arg12, ref int arg13, ref int arg14, ref int arg15) => ref _refResultHolder16;\n        // ---- Begin ManyArgsCase(long x 64) ----        \n\n        private long _refResultHolder64;\n        \n        [Benchmark, Arguments(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L)]\n        public long ManyArgsCase64(long arg0, long arg1, long arg2, long arg3, long arg4, long arg5, long arg6, long arg7, long arg8, long arg9, long arg10, long arg11, long arg12, long arg13, long arg14, long arg15, long arg16, long arg17, long arg18, long arg19, long arg20, long arg21, long arg22, long arg23, long arg24, long arg25, long arg26, long arg27, long arg28, long arg29, long arg30, long arg31, long arg32, long arg33, long arg34, long arg35, long arg36, long arg37, long arg38, long arg39, long arg40, long arg41, long arg42, long arg43, long arg44, long arg45, long arg46, long arg47, long arg48, long arg49, long arg50, long arg51, long arg52, long arg53, long arg54, long arg55, long arg56, long arg57, long arg58, long arg59, long arg60, long arg61, long arg62, long arg63) => default;\n\n        [Benchmark, Arguments(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L)]\n        public Task ManyArgsTaskCase64(long arg0, long arg1, long arg2, long arg3, long arg4, long arg5, long arg6, long arg7, long arg8, long arg9, long arg10, long arg11, long arg12, long arg13, long arg14, long arg15, long arg16, long arg17, long arg18, long arg19, long arg20, long arg21, long arg22, long arg23, long arg24, long arg25, long arg26, long arg27, long arg28, long arg29, long arg30, long arg31, long arg32, long arg33, long arg34, long arg35, long arg36, long arg37, long arg38, long arg39, long arg40, long arg41, long arg42, long arg43, long arg44, long arg45, long arg46, long arg47, long arg48, long arg49, long arg50, long arg51, long arg52, long arg53, long arg54, long arg55, long arg56, long arg57, long arg58, long arg59, long arg60, long arg61, long arg62, long arg63) => Task.CompletedTask;\n\n        [Benchmark, Arguments(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L)]\n        public ref long RefReturnManyArgsCase64(ref long arg0, ref long arg1, ref long arg2, ref long arg3, ref long arg4, ref long arg5, ref long arg6, ref long arg7, ref long arg8, ref long arg9, ref long arg10, ref long arg11, ref long arg12, ref long arg13, ref long arg14, ref long arg15, ref long arg16, ref long arg17, ref long arg18, ref long arg19, ref long arg20, ref long arg21, ref long arg22, ref long arg23, ref long arg24, ref long arg25, ref long arg26, ref long arg27, ref long arg28, ref long arg29, ref long arg30, ref long arg31, ref long arg32, ref long arg33, ref long arg34, ref long arg35, ref long arg36, ref long arg37, ref long arg38, ref long arg39, ref long arg40, ref long arg41, ref long arg42, ref long arg43, ref long arg44, ref long arg45, ref long arg46, ref long arg47, ref long arg48, ref long arg49, ref long arg50, ref long arg51, ref long arg52, ref long arg53, ref long arg54, ref long arg55, ref long arg56, ref long arg57, ref long arg58, ref long arg59, ref long arg60, ref long arg61, ref long arg62, ref long arg63) => ref _refResultHolder64;\n        // ---- Begin ManyArgsCase(byte x 512) ----        \n\n        private byte _refResultHolder512;\n        \n        [Benchmark, Arguments(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)]\n        public byte ManyArgsCase512(byte arg0, byte arg1, byte arg2, byte arg3, byte arg4, byte arg5, byte arg6, byte arg7, byte arg8, byte arg9, byte arg10, byte arg11, byte arg12, byte arg13, byte arg14, byte arg15, byte arg16, byte arg17, byte arg18, byte arg19, byte arg20, byte arg21, byte arg22, byte arg23, byte arg24, byte arg25, byte arg26, byte arg27, byte arg28, byte arg29, byte arg30, byte arg31, byte arg32, byte arg33, byte arg34, byte arg35, byte arg36, byte arg37, byte arg38, byte arg39, byte arg40, byte arg41, byte arg42, byte arg43, byte arg44, byte arg45, byte arg46, byte arg47, byte arg48, byte arg49, byte arg50, byte arg51, byte arg52, byte arg53, byte arg54, byte arg55, byte arg56, byte arg57, byte arg58, byte arg59, byte arg60, byte arg61, byte arg62, byte arg63, byte arg64, byte arg65, byte arg66, byte arg67, byte arg68, byte arg69, byte arg70, byte arg71, byte arg72, byte arg73, byte arg74, byte arg75, byte arg76, byte arg77, byte arg78, byte arg79, byte arg80, byte arg81, byte arg82, byte arg83, byte arg84, byte arg85, byte arg86, byte arg87, byte arg88, byte arg89, byte arg90, byte arg91, byte arg92, byte arg93, byte arg94, byte arg95, byte arg96, byte arg97, byte arg98, byte arg99, byte arg100, byte arg101, byte arg102, byte arg103, byte arg104, byte arg105, byte arg106, byte arg107, byte arg108, byte arg109, byte arg110, byte arg111, byte arg112, byte arg113, byte arg114, byte arg115, byte arg116, byte arg117, byte arg118, byte arg119, byte arg120, byte arg121, byte arg122, byte arg123, byte arg124, byte arg125, byte arg126, byte arg127, byte arg128, byte arg129, byte arg130, byte arg131, byte arg132, byte arg133, byte arg134, byte arg135, byte arg136, byte arg137, byte arg138, byte arg139, byte arg140, byte arg141, byte arg142, byte arg143, byte arg144, byte arg145, byte arg146, byte arg147, byte arg148, byte arg149, byte arg150, byte arg151, byte arg152, byte arg153, byte arg154, byte arg155, byte arg156, byte arg157, byte arg158, byte arg159, byte arg160, byte arg161, byte arg162, byte arg163, byte arg164, byte arg165, byte arg166, byte arg167, byte arg168, byte arg169, byte arg170, byte arg171, byte arg172, byte arg173, byte arg174, byte arg175, byte arg176, byte arg177, byte arg178, byte arg179, byte arg180, byte arg181, byte arg182, byte arg183, byte arg184, byte arg185, byte arg186, byte arg187, byte arg188, byte arg189, byte arg190, byte arg191, byte arg192, byte arg193, byte arg194, byte arg195, byte arg196, byte arg197, byte arg198, byte arg199, byte arg200, byte arg201, byte arg202, byte arg203, byte arg204, byte arg205, byte arg206, byte arg207, byte arg208, byte arg209, byte arg210, byte arg211, byte arg212, byte arg213, byte arg214, byte arg215, byte arg216, byte arg217, byte arg218, byte arg219, byte arg220, byte arg221, byte arg222, byte arg223, byte arg224, byte arg225, byte arg226, byte arg227, byte arg228, byte arg229, byte arg230, byte arg231, byte arg232, byte arg233, byte arg234, byte arg235, byte arg236, byte arg237, byte arg238, byte arg239, byte arg240, byte arg241, byte arg242, byte arg243, byte arg244, byte arg245, byte arg246, byte arg247, byte arg248, byte arg249, byte arg250, byte arg251, byte arg252, byte arg253, byte arg254, byte arg255, byte arg256, byte arg257, byte arg258, byte arg259, byte arg260, byte arg261, byte arg262, byte arg263, byte arg264, byte arg265, byte arg266, byte arg267, byte arg268, byte arg269, byte arg270, byte arg271, byte arg272, byte arg273, byte arg274, byte arg275, byte arg276, byte arg277, byte arg278, byte arg279, byte arg280, byte arg281, byte arg282, byte arg283, byte arg284, byte arg285, byte arg286, byte arg287, byte arg288, byte arg289, byte arg290, byte arg291, byte arg292, byte arg293, byte arg294, byte arg295, byte arg296, byte arg297, byte arg298, byte arg299, byte arg300, byte arg301, byte arg302, byte arg303, byte arg304, byte arg305, byte arg306, byte arg307, byte arg308, byte arg309, byte arg310, byte arg311, byte arg312, byte arg313, byte arg314, byte arg315, byte arg316, byte arg317, byte arg318, byte arg319, byte arg320, byte arg321, byte arg322, byte arg323, byte arg324, byte arg325, byte arg326, byte arg327, byte arg328, byte arg329, byte arg330, byte arg331, byte arg332, byte arg333, byte arg334, byte arg335, byte arg336, byte arg337, byte arg338, byte arg339, byte arg340, byte arg341, byte arg342, byte arg343, byte arg344, byte arg345, byte arg346, byte arg347, byte arg348, byte arg349, byte arg350, byte arg351, byte arg352, byte arg353, byte arg354, byte arg355, byte arg356, byte arg357, byte arg358, byte arg359, byte arg360, byte arg361, byte arg362, byte arg363, byte arg364, byte arg365, byte arg366, byte arg367, byte arg368, byte arg369, byte arg370, byte arg371, byte arg372, byte arg373, byte arg374, byte arg375, byte arg376, byte arg377, byte arg378, byte arg379, byte arg380, byte arg381, byte arg382, byte arg383, byte arg384, byte arg385, byte arg386, byte arg387, byte arg388, byte arg389, byte arg390, byte arg391, byte arg392, byte arg393, byte arg394, byte arg395, byte arg396, byte arg397, byte arg398, byte arg399, byte arg400, byte arg401, byte arg402, byte arg403, byte arg404, byte arg405, byte arg406, byte arg407, byte arg408, byte arg409, byte arg410, byte arg411, byte arg412, byte arg413, byte arg414, byte arg415, byte arg416, byte arg417, byte arg418, byte arg419, byte arg420, byte arg421, byte arg422, byte arg423, byte arg424, byte arg425, byte arg426, byte arg427, byte arg428, byte arg429, byte arg430, byte arg431, byte arg432, byte arg433, byte arg434, byte arg435, byte arg436, byte arg437, byte arg438, byte arg439, byte arg440, byte arg441, byte arg442, byte arg443, byte arg444, byte arg445, byte arg446, byte arg447, byte arg448, byte arg449, byte arg450, byte arg451, byte arg452, byte arg453, byte arg454, byte arg455, byte arg456, byte arg457, byte arg458, byte arg459, byte arg460, byte arg461, byte arg462, byte arg463, byte arg464, byte arg465, byte arg466, byte arg467, byte arg468, byte arg469, byte arg470, byte arg471, byte arg472, byte arg473, byte arg474, byte arg475, byte arg476, byte arg477, byte arg478, byte arg479, byte arg480, byte arg481, byte arg482, byte arg483, byte arg484, byte arg485, byte arg486, byte arg487, byte arg488, byte arg489, byte arg490, byte arg491, byte arg492, byte arg493, byte arg494, byte arg495, byte arg496, byte arg497, byte arg498, byte arg499, byte arg500, byte arg501, byte arg502, byte arg503, byte arg504, byte arg505, byte arg506, byte arg507, byte arg508, byte arg509, byte arg510, byte arg511) => default;\n\n        [Benchmark, Arguments(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)]\n        public Task ManyArgsTaskCase512(byte arg0, byte arg1, byte arg2, byte arg3, byte arg4, byte arg5, byte arg6, byte arg7, byte arg8, byte arg9, byte arg10, byte arg11, byte arg12, byte arg13, byte arg14, byte arg15, byte arg16, byte arg17, byte arg18, byte arg19, byte arg20, byte arg21, byte arg22, byte arg23, byte arg24, byte arg25, byte arg26, byte arg27, byte arg28, byte arg29, byte arg30, byte arg31, byte arg32, byte arg33, byte arg34, byte arg35, byte arg36, byte arg37, byte arg38, byte arg39, byte arg40, byte arg41, byte arg42, byte arg43, byte arg44, byte arg45, byte arg46, byte arg47, byte arg48, byte arg49, byte arg50, byte arg51, byte arg52, byte arg53, byte arg54, byte arg55, byte arg56, byte arg57, byte arg58, byte arg59, byte arg60, byte arg61, byte arg62, byte arg63, byte arg64, byte arg65, byte arg66, byte arg67, byte arg68, byte arg69, byte arg70, byte arg71, byte arg72, byte arg73, byte arg74, byte arg75, byte arg76, byte arg77, byte arg78, byte arg79, byte arg80, byte arg81, byte arg82, byte arg83, byte arg84, byte arg85, byte arg86, byte arg87, byte arg88, byte arg89, byte arg90, byte arg91, byte arg92, byte arg93, byte arg94, byte arg95, byte arg96, byte arg97, byte arg98, byte arg99, byte arg100, byte arg101, byte arg102, byte arg103, byte arg104, byte arg105, byte arg106, byte arg107, byte arg108, byte arg109, byte arg110, byte arg111, byte arg112, byte arg113, byte arg114, byte arg115, byte arg116, byte arg117, byte arg118, byte arg119, byte arg120, byte arg121, byte arg122, byte arg123, byte arg124, byte arg125, byte arg126, byte arg127, byte arg128, byte arg129, byte arg130, byte arg131, byte arg132, byte arg133, byte arg134, byte arg135, byte arg136, byte arg137, byte arg138, byte arg139, byte arg140, byte arg141, byte arg142, byte arg143, byte arg144, byte arg145, byte arg146, byte arg147, byte arg148, byte arg149, byte arg150, byte arg151, byte arg152, byte arg153, byte arg154, byte arg155, byte arg156, byte arg157, byte arg158, byte arg159, byte arg160, byte arg161, byte arg162, byte arg163, byte arg164, byte arg165, byte arg166, byte arg167, byte arg168, byte arg169, byte arg170, byte arg171, byte arg172, byte arg173, byte arg174, byte arg175, byte arg176, byte arg177, byte arg178, byte arg179, byte arg180, byte arg181, byte arg182, byte arg183, byte arg184, byte arg185, byte arg186, byte arg187, byte arg188, byte arg189, byte arg190, byte arg191, byte arg192, byte arg193, byte arg194, byte arg195, byte arg196, byte arg197, byte arg198, byte arg199, byte arg200, byte arg201, byte arg202, byte arg203, byte arg204, byte arg205, byte arg206, byte arg207, byte arg208, byte arg209, byte arg210, byte arg211, byte arg212, byte arg213, byte arg214, byte arg215, byte arg216, byte arg217, byte arg218, byte arg219, byte arg220, byte arg221, byte arg222, byte arg223, byte arg224, byte arg225, byte arg226, byte arg227, byte arg228, byte arg229, byte arg230, byte arg231, byte arg232, byte arg233, byte arg234, byte arg235, byte arg236, byte arg237, byte arg238, byte arg239, byte arg240, byte arg241, byte arg242, byte arg243, byte arg244, byte arg245, byte arg246, byte arg247, byte arg248, byte arg249, byte arg250, byte arg251, byte arg252, byte arg253, byte arg254, byte arg255, byte arg256, byte arg257, byte arg258, byte arg259, byte arg260, byte arg261, byte arg262, byte arg263, byte arg264, byte arg265, byte arg266, byte arg267, byte arg268, byte arg269, byte arg270, byte arg271, byte arg272, byte arg273, byte arg274, byte arg275, byte arg276, byte arg277, byte arg278, byte arg279, byte arg280, byte arg281, byte arg282, byte arg283, byte arg284, byte arg285, byte arg286, byte arg287, byte arg288, byte arg289, byte arg290, byte arg291, byte arg292, byte arg293, byte arg294, byte arg295, byte arg296, byte arg297, byte arg298, byte arg299, byte arg300, byte arg301, byte arg302, byte arg303, byte arg304, byte arg305, byte arg306, byte arg307, byte arg308, byte arg309, byte arg310, byte arg311, byte arg312, byte arg313, byte arg314, byte arg315, byte arg316, byte arg317, byte arg318, byte arg319, byte arg320, byte arg321, byte arg322, byte arg323, byte arg324, byte arg325, byte arg326, byte arg327, byte arg328, byte arg329, byte arg330, byte arg331, byte arg332, byte arg333, byte arg334, byte arg335, byte arg336, byte arg337, byte arg338, byte arg339, byte arg340, byte arg341, byte arg342, byte arg343, byte arg344, byte arg345, byte arg346, byte arg347, byte arg348, byte arg349, byte arg350, byte arg351, byte arg352, byte arg353, byte arg354, byte arg355, byte arg356, byte arg357, byte arg358, byte arg359, byte arg360, byte arg361, byte arg362, byte arg363, byte arg364, byte arg365, byte arg366, byte arg367, byte arg368, byte arg369, byte arg370, byte arg371, byte arg372, byte arg373, byte arg374, byte arg375, byte arg376, byte arg377, byte arg378, byte arg379, byte arg380, byte arg381, byte arg382, byte arg383, byte arg384, byte arg385, byte arg386, byte arg387, byte arg388, byte arg389, byte arg390, byte arg391, byte arg392, byte arg393, byte arg394, byte arg395, byte arg396, byte arg397, byte arg398, byte arg399, byte arg400, byte arg401, byte arg402, byte arg403, byte arg404, byte arg405, byte arg406, byte arg407, byte arg408, byte arg409, byte arg410, byte arg411, byte arg412, byte arg413, byte arg414, byte arg415, byte arg416, byte arg417, byte arg418, byte arg419, byte arg420, byte arg421, byte arg422, byte arg423, byte arg424, byte arg425, byte arg426, byte arg427, byte arg428, byte arg429, byte arg430, byte arg431, byte arg432, byte arg433, byte arg434, byte arg435, byte arg436, byte arg437, byte arg438, byte arg439, byte arg440, byte arg441, byte arg442, byte arg443, byte arg444, byte arg445, byte arg446, byte arg447, byte arg448, byte arg449, byte arg450, byte arg451, byte arg452, byte arg453, byte arg454, byte arg455, byte arg456, byte arg457, byte arg458, byte arg459, byte arg460, byte arg461, byte arg462, byte arg463, byte arg464, byte arg465, byte arg466, byte arg467, byte arg468, byte arg469, byte arg470, byte arg471, byte arg472, byte arg473, byte arg474, byte arg475, byte arg476, byte arg477, byte arg478, byte arg479, byte arg480, byte arg481, byte arg482, byte arg483, byte arg484, byte arg485, byte arg486, byte arg487, byte arg488, byte arg489, byte arg490, byte arg491, byte arg492, byte arg493, byte arg494, byte arg495, byte arg496, byte arg497, byte arg498, byte arg499, byte arg500, byte arg501, byte arg502, byte arg503, byte arg504, byte arg505, byte arg506, byte arg507, byte arg508, byte arg509, byte arg510, byte arg511) => Task.CompletedTask;\n\n        [Benchmark, Arguments(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)]\n        public ref byte RefReturnManyArgsCase512(ref byte arg0, ref byte arg1, ref byte arg2, ref byte arg3, ref byte arg4, ref byte arg5, ref byte arg6, ref byte arg7, ref byte arg8, ref byte arg9, ref byte arg10, ref byte arg11, ref byte arg12, ref byte arg13, ref byte arg14, ref byte arg15, ref byte arg16, ref byte arg17, ref byte arg18, ref byte arg19, ref byte arg20, ref byte arg21, ref byte arg22, ref byte arg23, ref byte arg24, ref byte arg25, ref byte arg26, ref byte arg27, ref byte arg28, ref byte arg29, ref byte arg30, ref byte arg31, ref byte arg32, ref byte arg33, ref byte arg34, ref byte arg35, ref byte arg36, ref byte arg37, ref byte arg38, ref byte arg39, ref byte arg40, ref byte arg41, ref byte arg42, ref byte arg43, ref byte arg44, ref byte arg45, ref byte arg46, ref byte arg47, ref byte arg48, ref byte arg49, ref byte arg50, ref byte arg51, ref byte arg52, ref byte arg53, ref byte arg54, ref byte arg55, ref byte arg56, ref byte arg57, ref byte arg58, ref byte arg59, ref byte arg60, ref byte arg61, ref byte arg62, ref byte arg63, ref byte arg64, ref byte arg65, ref byte arg66, ref byte arg67, ref byte arg68, ref byte arg69, ref byte arg70, ref byte arg71, ref byte arg72, ref byte arg73, ref byte arg74, ref byte arg75, ref byte arg76, ref byte arg77, ref byte arg78, ref byte arg79, ref byte arg80, ref byte arg81, ref byte arg82, ref byte arg83, ref byte arg84, ref byte arg85, ref byte arg86, ref byte arg87, ref byte arg88, ref byte arg89, ref byte arg90, ref byte arg91, ref byte arg92, ref byte arg93, ref byte arg94, ref byte arg95, ref byte arg96, ref byte arg97, ref byte arg98, ref byte arg99, ref byte arg100, ref byte arg101, ref byte arg102, ref byte arg103, ref byte arg104, ref byte arg105, ref byte arg106, ref byte arg107, ref byte arg108, ref byte arg109, ref byte arg110, ref byte arg111, ref byte arg112, ref byte arg113, ref byte arg114, ref byte arg115, ref byte arg116, ref byte arg117, ref byte arg118, ref byte arg119, ref byte arg120, ref byte arg121, ref byte arg122, ref byte arg123, ref byte arg124, ref byte arg125, ref byte arg126, ref byte arg127, ref byte arg128, ref byte arg129, ref byte arg130, ref byte arg131, ref byte arg132, ref byte arg133, ref byte arg134, ref byte arg135, ref byte arg136, ref byte arg137, ref byte arg138, ref byte arg139, ref byte arg140, ref byte arg141, ref byte arg142, ref byte arg143, ref byte arg144, ref byte arg145, ref byte arg146, ref byte arg147, ref byte arg148, ref byte arg149, ref byte arg150, ref byte arg151, ref byte arg152, ref byte arg153, ref byte arg154, ref byte arg155, ref byte arg156, ref byte arg157, ref byte arg158, ref byte arg159, ref byte arg160, ref byte arg161, ref byte arg162, ref byte arg163, ref byte arg164, ref byte arg165, ref byte arg166, ref byte arg167, ref byte arg168, ref byte arg169, ref byte arg170, ref byte arg171, ref byte arg172, ref byte arg173, ref byte arg174, ref byte arg175, ref byte arg176, ref byte arg177, ref byte arg178, ref byte arg179, ref byte arg180, ref byte arg181, ref byte arg182, ref byte arg183, ref byte arg184, ref byte arg185, ref byte arg186, ref byte arg187, ref byte arg188, ref byte arg189, ref byte arg190, ref byte arg191, ref byte arg192, ref byte arg193, ref byte arg194, ref byte arg195, ref byte arg196, ref byte arg197, ref byte arg198, ref byte arg199, ref byte arg200, ref byte arg201, ref byte arg202, ref byte arg203, ref byte arg204, ref byte arg205, ref byte arg206, ref byte arg207, ref byte arg208, ref byte arg209, ref byte arg210, ref byte arg211, ref byte arg212, ref byte arg213, ref byte arg214, ref byte arg215, ref byte arg216, ref byte arg217, ref byte arg218, ref byte arg219, ref byte arg220, ref byte arg221, ref byte arg222, ref byte arg223, ref byte arg224, ref byte arg225, ref byte arg226, ref byte arg227, ref byte arg228, ref byte arg229, ref byte arg230, ref byte arg231, ref byte arg232, ref byte arg233, ref byte arg234, ref byte arg235, ref byte arg236, ref byte arg237, ref byte arg238, ref byte arg239, ref byte arg240, ref byte arg241, ref byte arg242, ref byte arg243, ref byte arg244, ref byte arg245, ref byte arg246, ref byte arg247, ref byte arg248, ref byte arg249, ref byte arg250, ref byte arg251, ref byte arg252, ref byte arg253, ref byte arg254, ref byte arg255, ref byte arg256, ref byte arg257, ref byte arg258, ref byte arg259, ref byte arg260, ref byte arg261, ref byte arg262, ref byte arg263, ref byte arg264, ref byte arg265, ref byte arg266, ref byte arg267, ref byte arg268, ref byte arg269, ref byte arg270, ref byte arg271, ref byte arg272, ref byte arg273, ref byte arg274, ref byte arg275, ref byte arg276, ref byte arg277, ref byte arg278, ref byte arg279, ref byte arg280, ref byte arg281, ref byte arg282, ref byte arg283, ref byte arg284, ref byte arg285, ref byte arg286, ref byte arg287, ref byte arg288, ref byte arg289, ref byte arg290, ref byte arg291, ref byte arg292, ref byte arg293, ref byte arg294, ref byte arg295, ref byte arg296, ref byte arg297, ref byte arg298, ref byte arg299, ref byte arg300, ref byte arg301, ref byte arg302, ref byte arg303, ref byte arg304, ref byte arg305, ref byte arg306, ref byte arg307, ref byte arg308, ref byte arg309, ref byte arg310, ref byte arg311, ref byte arg312, ref byte arg313, ref byte arg314, ref byte arg315, ref byte arg316, ref byte arg317, ref byte arg318, ref byte arg319, ref byte arg320, ref byte arg321, ref byte arg322, ref byte arg323, ref byte arg324, ref byte arg325, ref byte arg326, ref byte arg327, ref byte arg328, ref byte arg329, ref byte arg330, ref byte arg331, ref byte arg332, ref byte arg333, ref byte arg334, ref byte arg335, ref byte arg336, ref byte arg337, ref byte arg338, ref byte arg339, ref byte arg340, ref byte arg341, ref byte arg342, ref byte arg343, ref byte arg344, ref byte arg345, ref byte arg346, ref byte arg347, ref byte arg348, ref byte arg349, ref byte arg350, ref byte arg351, ref byte arg352, ref byte arg353, ref byte arg354, ref byte arg355, ref byte arg356, ref byte arg357, ref byte arg358, ref byte arg359, ref byte arg360, ref byte arg361, ref byte arg362, ref byte arg363, ref byte arg364, ref byte arg365, ref byte arg366, ref byte arg367, ref byte arg368, ref byte arg369, ref byte arg370, ref byte arg371, ref byte arg372, ref byte arg373, ref byte arg374, ref byte arg375, ref byte arg376, ref byte arg377, ref byte arg378, ref byte arg379, ref byte arg380, ref byte arg381, ref byte arg382, ref byte arg383, ref byte arg384, ref byte arg385, ref byte arg386, ref byte arg387, ref byte arg388, ref byte arg389, ref byte arg390, ref byte arg391, ref byte arg392, ref byte arg393, ref byte arg394, ref byte arg395, ref byte arg396, ref byte arg397, ref byte arg398, ref byte arg399, ref byte arg400, ref byte arg401, ref byte arg402, ref byte arg403, ref byte arg404, ref byte arg405, ref byte arg406, ref byte arg407, ref byte arg408, ref byte arg409, ref byte arg410, ref byte arg411, ref byte arg412, ref byte arg413, ref byte arg414, ref byte arg415, ref byte arg416, ref byte arg417, ref byte arg418, ref byte arg419, ref byte arg420, ref byte arg421, ref byte arg422, ref byte arg423, ref byte arg424, ref byte arg425, ref byte arg426, ref byte arg427, ref byte arg428, ref byte arg429, ref byte arg430, ref byte arg431, ref byte arg432, ref byte arg433, ref byte arg434, ref byte arg435, ref byte arg436, ref byte arg437, ref byte arg438, ref byte arg439, ref byte arg440, ref byte arg441, ref byte arg442, ref byte arg443, ref byte arg444, ref byte arg445, ref byte arg446, ref byte arg447, ref byte arg448, ref byte arg449, ref byte arg450, ref byte arg451, ref byte arg452, ref byte arg453, ref byte arg454, ref byte arg455, ref byte arg456, ref byte arg457, ref byte arg458, ref byte arg459, ref byte arg460, ref byte arg461, ref byte arg462, ref byte arg463, ref byte arg464, ref byte arg465, ref byte arg466, ref byte arg467, ref byte arg468, ref byte arg469, ref byte arg470, ref byte arg471, ref byte arg472, ref byte arg473, ref byte arg474, ref byte arg475, ref byte arg476, ref byte arg477, ref byte arg478, ref byte arg479, ref byte arg480, ref byte arg481, ref byte arg482, ref byte arg483, ref byte arg484, ref byte arg485, ref byte arg486, ref byte arg487, ref byte arg488, ref byte arg489, ref byte arg490, ref byte arg491, ref byte arg492, ref byte arg493, ref byte arg494, ref byte arg495, ref byte arg496, ref byte arg497, ref byte arg498, ref byte arg499, ref byte arg500, ref byte arg501, ref byte arg502, ref byte arg503, ref byte arg504, ref byte arg505, ref byte arg506, ref byte arg507, ref byte arg508, ref byte arg509, ref byte arg510, ref byte arg511) => ref _refResultHolder512;\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/InProcess.EmitTests.T4/RunnableManyArgsCaseBenchmark.tt",
    "content": "﻿<#@ template debug=\"false\" hostspecific=\"false\" language=\"C#\" #>\n<#@ assembly name=\"System.Core\" #>\n<#@ import namespace=\"System.Linq\" #>\n<#@ output extension=\".cs\" #>\n//------------------------------------------------------------------------------\n// <auto-generated>\n//     This code was generated by a tool.\n//\n//     Changes to this file may cause incorrect behavior and will be lost if\n//     the code is regenerated.\n// </auto-generated>\n//------------------------------------------------------------------------------\n\nusing BenchmarkDotNet.Attributes;\n\nusing System;\nusing System.Threading.Tasks;\n\nnamespace BenchmarkDotNet.IntegrationTests.InProcess.EmitTests\n{\n    /// <summary>\n    /// Generated class to check emitted msil cases\n    /// </summary>\n    public class RunnableManyArgsCaseBenchmark\n    {\n<#\n    EmitManyArgsCaseBenchmark(\"string\", 4, \"\\\"\\\"\");\n    EmitManyArgsCaseBenchmark(\"int\", 16, \"0\");\n    EmitManyArgsCaseBenchmark(\"long\", 512/sizeof(long), \"1L\");\n    EmitManyArgsCaseBenchmark(\"byte\", 512, \"1\");\n#>\n    }\n}<#+\n\n    private void EmitManyArgsCaseBenchmark(string type, int argsCount, string argValue)\n    {\n        var argDefinition = string.Join(\n            \", \", \n            Enumerable.Range(0, argsCount).Select(i=>$\"{type} arg{i}\"));\n\n        var refArgDefinition = string.Join(\n            \", \", \n            Enumerable.Range(0, argsCount).Select(i=>$\"ref {type} arg{i}\"));\n\n        var argValues = string.Join(\", \", Enumerable.Repeat(argValue, argsCount));\n\n#>\n        // ---- Begin ManyArgsCase(<#=type#> x <#=argsCount#>) ----        \n\n        private <#=type#> _refResultHolder<#=argsCount#>;\n        \n        [Benchmark, Arguments(<#=argValues#>)]\n        public <#=type#> ManyArgsCase<#=argsCount#>(<#=argDefinition#>) => default;\n\n        [Benchmark, Arguments(<#=argValues#>)]\n        public Task ManyArgsTaskCase<#=argsCount#>(<#=argDefinition#>) => Task.CompletedTask;\n\n        [Benchmark, Arguments(<#=argValues#>)]\n        public ref <#=type#> RefReturnManyArgsCase<#=argsCount#>(<#=refArgDefinition#>) => ref _refResultHolder<#=argsCount#>;\n<#+\n    }\n#>\n"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/InProcess.EmitTests.T4/RunnableRefStructCaseBenchmark.cs",
    "content": "﻿//------------------------------------------------------------------------------\n// <auto-generated>\n//     This code was generated by a tool.\n//\n//     Changes to this file may cause incorrect behavior and will be lost if\n//     the code is regenerated.\n// </auto-generated>\n//------------------------------------------------------------------------------\n\nusing BenchmarkDotNet.Attributes;\n\nusing System;\n\nnamespace BenchmarkDotNet.IntegrationTests.InProcess.EmitTests\n{\n    /// <summary>\n    /// Generated class to check emitted msil cases\n    /// </summary>\n    public class RunnableRefStructCaseBenchmark\n    {\n        // ---- Begin StructCase(Span<int>) ----\n\n        [Benchmark, Arguments(new[] { 0, 1, 2 }, \"1\", 0.1)]\n        public Span<int> RefStructCase1(Span<int> x, ref string y, double? z) => x;\n\n        // ---- Begin StructCase(ReadOnlySpan<string>) ----\n\n        [Benchmark, Arguments(new[] { \"A\", \"B\", \"C\" }, \"2\", 0.2)]\n        public ReadOnlySpan<string> RefStructCase2(ReadOnlySpan<string> x, ref string y, double? z) => x;\n\n        // ---- Begin StructCase(Memory<int>) ----\n\n        [Benchmark, Arguments(new[] { 0, 1, 2 }, \"3\", 0.3)]\n        public Memory<int> RefStructCase3(Memory<int> x, ref string y, double? z) => x;\n\n        // ---- Begin StructCase(ReadOnlyMemory<string>) ----\n\n        [Benchmark, Arguments(new[] { \"A\", \"B\", \"C\" }, \"4\", 0.4)]\n        public ReadOnlyMemory<string> RefStructCase4(ReadOnlyMemory<string> x, ref string y, double? z) => x;\n\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/InProcess.EmitTests.T4/RunnableRefStructCaseBenchmark.tt",
    "content": "﻿<#@ template debug=\"false\" hostspecific=\"false\" language=\"C#\" #>\n<#@ assembly name=\"System.Core\" #>\n<#@ output extension=\".cs\" #>\n//------------------------------------------------------------------------------\n// <auto-generated>\n//     This code was generated by a tool.\n//\n//     Changes to this file may cause incorrect behavior and will be lost if\n//     the code is regenerated.\n// </auto-generated>\n//------------------------------------------------------------------------------\n\nusing BenchmarkDotNet.Attributes;\n\nusing System;\n\nnamespace BenchmarkDotNet.IntegrationTests.InProcess.EmitTests\n{\n    /// <summary>\n    /// Generated class to check emitted msil cases\n    /// </summary>\n    public class RunnableRefStructCaseBenchmark\n    {\n<#\n    int counter = 1;\n\n    EmitRefStructCaseBenchmark(ref counter, \"Span<int>\", \"new[] { 0, 1, 2 }\");\n    EmitRefStructCaseBenchmark(ref counter, \"ReadOnlySpan<string>\", \"new[] { \\\"A\\\", \\\"B\\\", \\\"C\\\" }\");\n    EmitRefStructCaseBenchmark(ref counter, \"Memory<int>\", \"new[] { 0, 1, 2 }\");\n    EmitRefStructCaseBenchmark(ref counter, \"ReadOnlyMemory<string>\", \"new[] { \\\"A\\\", \\\"B\\\", \\\"C\\\" }\");\n#>\n    }\n}<#+\n\n    private void EmitRefStructCaseBenchmark(ref int counter, string type, string argValue)\n    {\n#>\n        // ---- Begin StructCase(<#=type#>) ----\n\n        [Benchmark, Arguments(<#=argValue#>, \"<#=counter#>\", 0.<#=counter#>)]\n        public <#=type#> RefStructCase<#=counter#>(<#=type#> x, ref string y, double? z) => x;\n\n<#+\n        counter++;\n    }\n#>\n"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/InProcess.EmitTests.T4/RunnableStructCaseBenchmark.cs",
    "content": "﻿//------------------------------------------------------------------------------\n// <auto-generated>\n//     This code was generated by a tool.\n//\n//     Changes to this file may cause incorrect behavior and will be lost if\n//     the code is regenerated.\n// </auto-generated>\n//------------------------------------------------------------------------------\n\nusing BenchmarkDotNet.Attributes;\n\nusing System;\nusing System.Threading.Tasks;\n\nnamespace BenchmarkDotNet.IntegrationTests.InProcess.EmitTests\n{\n    /// <summary>\n    /// Generated class to check emitted msil cases\n    /// </summary>\n    public class RunnableStructCaseBenchmark\n    {\n        // ---- Begin StructCase(bool) ----\n\n        private bool _refResultHolder1;\n\n        [Benchmark]\n        public ref readonly bool RefReadonlyReturnStructCase1() => ref _refResultHolder1;\n\n        [Benchmark]\n        public ref bool RefReturnStructCase1() => ref _refResultHolder1;\n\n        [Benchmark, Arguments(false, \"1\", 0.1)]\n        public bool StructCase1(bool x, ref string y, double? z) => default;\n\n        // ---- Begin StructCase(byte) ----\n\n        private byte _refResultHolder2;\n\n        [Benchmark]\n        public ref readonly byte RefReadonlyReturnStructCase2() => ref _refResultHolder2;\n\n        [Benchmark]\n        public ref byte RefReturnStructCase2() => ref _refResultHolder2;\n\n        [Benchmark, Arguments(0, \"2\", 0.2)]\n        public byte StructCase2(byte x, ref string y, double? z) => default;\n\n        // ---- Begin StructCase(sbyte) ----\n\n        private sbyte _refResultHolder3;\n\n        [Benchmark]\n        public ref readonly sbyte RefReadonlyReturnStructCase3() => ref _refResultHolder3;\n\n        [Benchmark]\n        public ref sbyte RefReturnStructCase3() => ref _refResultHolder3;\n\n        [Benchmark, Arguments(0, \"3\", 0.3)]\n        public sbyte StructCase3(sbyte x, ref string y, double? z) => default;\n\n        // ---- Begin StructCase(short) ----\n\n        private short _refResultHolder4;\n\n        [Benchmark]\n        public ref readonly short RefReadonlyReturnStructCase4() => ref _refResultHolder4;\n\n        [Benchmark]\n        public ref short RefReturnStructCase4() => ref _refResultHolder4;\n\n        [Benchmark, Arguments(0, \"4\", 0.4)]\n        public short StructCase4(short x, ref string y, double? z) => default;\n\n        // ---- Begin StructCase(ushort) ----\n\n        private ushort _refResultHolder5;\n\n        [Benchmark]\n        public ref readonly ushort RefReadonlyReturnStructCase5() => ref _refResultHolder5;\n\n        [Benchmark]\n        public ref ushort RefReturnStructCase5() => ref _refResultHolder5;\n\n        [Benchmark, Arguments(0, \"5\", 0.5)]\n        public ushort StructCase5(ushort x, ref string y, double? z) => default;\n\n        // ---- Begin StructCase(int) ----\n\n        private int _refResultHolder6;\n\n        [Benchmark]\n        public ref readonly int RefReadonlyReturnStructCase6() => ref _refResultHolder6;\n\n        [Benchmark]\n        public ref int RefReturnStructCase6() => ref _refResultHolder6;\n\n        [Benchmark, Arguments(0, \"6\", 0.6)]\n        public int StructCase6(int x, ref string y, double? z) => default;\n\n        // ---- Begin StructCase(uint) ----\n\n        private uint _refResultHolder7;\n\n        [Benchmark]\n        public ref readonly uint RefReadonlyReturnStructCase7() => ref _refResultHolder7;\n\n        [Benchmark]\n        public ref uint RefReturnStructCase7() => ref _refResultHolder7;\n\n        [Benchmark, Arguments(0, \"7\", 0.7)]\n        public uint StructCase7(uint x, ref string y, double? z) => default;\n\n        // ---- Begin StructCase(long) ----\n\n        private long _refResultHolder8;\n\n        [Benchmark]\n        public ref readonly long RefReadonlyReturnStructCase8() => ref _refResultHolder8;\n\n        [Benchmark]\n        public ref long RefReturnStructCase8() => ref _refResultHolder8;\n\n        [Benchmark, Arguments(0, \"8\", 0.8)]\n        public long StructCase8(long x, ref string y, double? z) => default;\n\n        // ---- Begin StructCase(ulong) ----\n\n        private ulong _refResultHolder9;\n\n        [Benchmark]\n        public ref readonly ulong RefReadonlyReturnStructCase9() => ref _refResultHolder9;\n\n        [Benchmark]\n        public ref ulong RefReturnStructCase9() => ref _refResultHolder9;\n\n        [Benchmark, Arguments(0, \"9\", 0.9)]\n        public ulong StructCase9(ulong x, ref string y, double? z) => default;\n\n        // ---- Begin StructCase(IntPtr) ----\n\n        private IntPtr _refResultHolder10;\n\n        [Benchmark]\n        public ref readonly IntPtr RefReadonlyReturnStructCase10() => ref _refResultHolder10;\n\n        [Benchmark]\n        public ref IntPtr RefReturnStructCase10() => ref _refResultHolder10;\n\n        [Benchmark, Arguments(10, \"10\", 0.10)]\n        public IntPtr StructCase10(int x, ref string y, double? z) => default;\n\n        // ---- Begin StructCase(UIntPtr) ----\n\n        private UIntPtr _refResultHolder11;\n\n        [Benchmark]\n        public ref readonly UIntPtr RefReadonlyReturnStructCase11() => ref _refResultHolder11;\n\n        [Benchmark]\n        public ref UIntPtr RefReturnStructCase11() => ref _refResultHolder11;\n\n        [Benchmark, Arguments(11, \"11\", 0.11)]\n        public UIntPtr StructCase11(int x, ref string y, double? z) => default;\n\n        // ---- Begin StructCase(char) ----\n\n        private char _refResultHolder12;\n\n        [Benchmark]\n        public ref readonly char RefReadonlyReturnStructCase12() => ref _refResultHolder12;\n\n        [Benchmark]\n        public ref char RefReturnStructCase12() => ref _refResultHolder12;\n\n        [Benchmark, Arguments(' ', \"12\", 0.12)]\n        public char StructCase12(char x, ref string y, double? z) => default;\n\n        // ---- Begin StructCase(double) ----\n\n        private double _refResultHolder13;\n\n        [Benchmark]\n        public ref readonly double RefReadonlyReturnStructCase13() => ref _refResultHolder13;\n\n        [Benchmark]\n        public ref double RefReturnStructCase13() => ref _refResultHolder13;\n\n        [Benchmark, Arguments(0, \"13\", 0.13)]\n        public double StructCase13(double x, ref string y, double? z) => default;\n\n        // ---- Begin StructCase(float) ----\n\n        private float _refResultHolder14;\n\n        [Benchmark]\n        public ref readonly float RefReadonlyReturnStructCase14() => ref _refResultHolder14;\n\n        [Benchmark]\n        public ref float RefReturnStructCase14() => ref _refResultHolder14;\n\n        [Benchmark, Arguments(0, \"14\", 0.14)]\n        public float StructCase14(float x, ref string y, double? z) => default;\n\n        // ---- Begin StructCase(decimal) ----\n\n        private decimal _refResultHolder15;\n\n        [Benchmark]\n        public ref readonly decimal RefReadonlyReturnStructCase15() => ref _refResultHolder15;\n\n        [Benchmark]\n        public ref decimal RefReturnStructCase15() => ref _refResultHolder15;\n\n        [Benchmark, Arguments(0, \"15\", 0.15)]\n        public decimal StructCase15(decimal x, ref string y, double? z) => default;\n\n        // ---- Begin StructCase(int?) ----\n\n        private int? _refResultHolder16;\n\n        [Benchmark]\n        public ref readonly int? RefReadonlyReturnStructCase16() => ref _refResultHolder16;\n\n        [Benchmark]\n        public ref int? RefReturnStructCase16() => ref _refResultHolder16;\n\n        [Benchmark, Arguments(null, \"16\", 0.16)]\n        public int? StructCase16(int? x, ref string y, double? z) => default;\n\n        // ---- Begin StructCase((int, int)) ----\n\n        private (int, int) _refResultHolder17;\n\n        [Benchmark]\n        public ref readonly (int, int) RefReadonlyReturnStructCase17() => ref _refResultHolder17;\n\n        [Benchmark]\n        public ref (int, int) RefReturnStructCase17() => ref _refResultHolder17;\n\n        [Benchmark, Arguments(17, \"17\", 0.17)]\n        public (int, int) StructCase17(int x, ref string y, double? z) => default;\n\n        // ---- Begin StructCase(DateTime) ----\n\n        private DateTime _refResultHolder18;\n\n        [Benchmark]\n        public ref readonly DateTime RefReadonlyReturnStructCase18() => ref _refResultHolder18;\n\n        [Benchmark]\n        public ref DateTime RefReturnStructCase18() => ref _refResultHolder18;\n\n        [Benchmark, Arguments(18, \"18\", 0.18)]\n        public DateTime StructCase18(int x, ref string y, double? z) => default;\n\n        // ---- Begin StructCase(TimeSpan?) ----\n\n        private TimeSpan? _refResultHolder19;\n\n        [Benchmark]\n        public ref readonly TimeSpan? RefReadonlyReturnStructCase19() => ref _refResultHolder19;\n\n        [Benchmark]\n        public ref TimeSpan? RefReturnStructCase19() => ref _refResultHolder19;\n\n        [Benchmark, Arguments(null, \"19\", 0.19)]\n        public TimeSpan? StructCase19(TimeSpan? x, ref string y, double? z) => default;\n\n        // ---- Begin StructCase(CustomEnumNonConsumable) ----\n\n        private CustomEnumNonConsumable _refResultHolder20;\n\n        [Benchmark]\n        public ref readonly CustomEnumNonConsumable RefReadonlyReturnStructCase20() => ref _refResultHolder20;\n\n        [Benchmark]\n        public ref CustomEnumNonConsumable RefReturnStructCase20() => ref _refResultHolder20;\n\n        [Benchmark, Arguments(20, \"20\", 0.20)]\n        public CustomEnumNonConsumable StructCase20(int x, ref string y, double? z) => default;\n\n        // ---- Begin StructCase(CustomEnumConsumable) ----\n\n        private CustomEnumConsumable _refResultHolder21;\n\n        [Benchmark]\n        public ref readonly CustomEnumConsumable RefReadonlyReturnStructCase21() => ref _refResultHolder21;\n\n        [Benchmark]\n        public ref CustomEnumConsumable RefReturnStructCase21() => ref _refResultHolder21;\n\n        [Benchmark, Arguments(21, \"21\", 0.21)]\n        public CustomEnumConsumable StructCase21(int x, ref string y, double? z) => default;\n\n        // ---- Begin StructCase(CustomStructNonConsumable) ----\n\n        private CustomStructNonConsumable _refResultHolder22;\n\n        [Benchmark]\n        public ref readonly CustomStructNonConsumable RefReadonlyReturnStructCase22() => ref _refResultHolder22;\n\n        [Benchmark]\n        public ref CustomStructNonConsumable RefReturnStructCase22() => ref _refResultHolder22;\n\n        [Benchmark, Arguments(22, \"22\", 0.22)]\n        public CustomStructNonConsumable StructCase22(int x, ref string y, double? z) => default;\n\n        // ---- Begin StructCase(CustomStructConsumable) ----\n\n        private CustomStructConsumable _refResultHolder23;\n\n        [Benchmark]\n        public ref readonly CustomStructConsumable RefReadonlyReturnStructCase23() => ref _refResultHolder23;\n\n        [Benchmark]\n        public ref CustomStructConsumable RefReturnStructCase23() => ref _refResultHolder23;\n\n        [Benchmark, Arguments(23, \"23\", 0.23)]\n        public CustomStructConsumable StructCase23(int x, ref string y, double? z) => default;\n\n        // ---- Begin StructCase(CustomStructConsumable<int>) ----\n\n        private CustomStructConsumable<int> _refResultHolder24;\n\n        [Benchmark]\n        public ref readonly CustomStructConsumable<int> RefReadonlyReturnStructCase24() => ref _refResultHolder24;\n\n        [Benchmark]\n        public ref CustomStructConsumable<int> RefReturnStructCase24() => ref _refResultHolder24;\n\n        [Benchmark, Arguments(24, \"24\", 0.24)]\n        public CustomStructConsumable<int> StructCase24(int x, ref string y, double? z) => default;\n\n        // ---- Begin StructCase(CustomStructConsumable<string>) ----\n\n        private CustomStructConsumable<string> _refResultHolder25;\n\n        [Benchmark]\n        public ref readonly CustomStructConsumable<string> RefReadonlyReturnStructCase25() => ref _refResultHolder25;\n\n        [Benchmark]\n        public ref CustomStructConsumable<string> RefReturnStructCase25() => ref _refResultHolder25;\n\n        [Benchmark, Arguments(25, \"25\", 0.25)]\n        public CustomStructConsumable<string> StructCase25(int x, ref string y, double? z) => default;\n\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/InProcess.EmitTests.T4/RunnableStructCaseBenchmark.tt",
    "content": "﻿<#@ template debug=\"false\" hostspecific=\"false\" language=\"C#\" #>\n<#@ assembly name=\"System.Core\" #>\n<#@ output extension=\".cs\" #>\n//------------------------------------------------------------------------------\n// <auto-generated>\n//     This code was generated by a tool.\n//\n//     Changes to this file may cause incorrect behavior and will be lost if\n//     the code is regenerated.\n// </auto-generated>\n//------------------------------------------------------------------------------\n\nusing BenchmarkDotNet.Attributes;\n\nusing System;\nusing System.Threading.Tasks;\n\nnamespace BenchmarkDotNet.IntegrationTests.InProcess.EmitTests\n{\n    /// <summary>\n    /// Generated class to check emitted msil cases\n    /// </summary>\n    public class RunnableStructCaseBenchmark\n    {\n<#\n    int counter = 1;\n    // The primitive types are Boolean, Byte, SByte, Int16, UInt16, Int32, UInt32, Int64, UInt64, IntPtr, UIntPtr, Char, Double, and Single\n    EmitStructCaseBenchmark(ref counter, \"bool\", \"false\");\n    EmitStructCaseBenchmark(ref counter, \"byte\", \"0\");\n    EmitStructCaseBenchmark(ref counter, \"sbyte\", \"0\");\n    EmitStructCaseBenchmark(ref counter, \"short\", \"0\");\n    EmitStructCaseBenchmark(ref counter, \"ushort\", \"0\");\n    EmitStructCaseBenchmark(ref counter, \"int\", \"0\");\n    EmitStructCaseBenchmark(ref counter, \"uint\", \"0\");\n    EmitStructCaseBenchmark(ref counter, \"long\", \"0\");\n    EmitStructCaseBenchmark(ref counter, \"ulong\", \"0\");\n    EmitStructCaseBenchmark(ref counter, \"IntPtr\");\n    EmitStructCaseBenchmark(ref counter, \"UIntPtr\");\n    EmitStructCaseBenchmark(ref counter, \"char\", \"' '\");\n    EmitStructCaseBenchmark(ref counter, \"double\", \"0\");\n    EmitStructCaseBenchmark(ref counter, \"float\", \"0\");\n    EmitStructCaseBenchmark(ref counter, \"decimal\", \"0\");\n    EmitStructCaseBenchmark(ref counter, \"int?\", \"null\");\n    EmitStructCaseBenchmark(ref counter, \"(int, int)\");\n    EmitStructCaseBenchmark(ref counter, \"DateTime\");\n    EmitStructCaseBenchmark(ref counter, \"TimeSpan?\", \"null\");\n    EmitStructCaseBenchmark(ref counter, \"CustomEnumNonConsumable\");\n    EmitStructCaseBenchmark(ref counter, \"CustomEnumConsumable\");\n    EmitStructCaseBenchmark(ref counter, \"CustomStructNonConsumable\");\n    EmitStructCaseBenchmark(ref counter, \"CustomStructConsumable\");\n    EmitStructCaseBenchmark(ref counter, \"CustomStructConsumable<int>\");\n    EmitStructCaseBenchmark(ref counter, \"CustomStructConsumable<string>\");\n#>\n    }\n}<#+\n\n    private void EmitStructCaseBenchmark(ref int counter, string type, string? argValue = null)\n    {\n#>\n        // ---- Begin StructCase(<#=type#>) ----\n\n        private <#=type#> _refResultHolder<#=counter#>;\n\n        [Benchmark]\n        public ref readonly <#=type#> RefReadonlyReturnStructCase<#=counter#>() => ref _refResultHolder<#=counter#>;\n\n        [Benchmark]\n        public ref <#=type#> RefReturnStructCase<#=counter#>() => ref _refResultHolder<#=counter#>;\n\n<#+\n        if (argValue != null)\n        {\n#>\n        [Benchmark, Arguments(<#=argValue#>, \"<#=counter#>\", 0.<#=counter#>)]\n        public <#=type#> StructCase<#=counter#>(<#=type#> x, ref string y, double? z) => default;\n\n<#+\n        }\n        else\n        {\n#>\n        [Benchmark, Arguments(<#=counter#>, \"<#=counter#>\", 0.<#=counter#>)]\n        public <#=type#> StructCase<#=counter#>(int x, ref string y, double? z) => default;\n\n<#+\n        }\n        counter++;\n    }\n#>\n"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/InProcess.EmitTests.T4/RunnableTaskCaseBenchmark.cs",
    "content": "﻿//------------------------------------------------------------------------------\n// <auto-generated>\n//     This code was generated by a tool.\n//\n//     Changes to this file may cause incorrect behavior and will be lost if\n//     the code is regenerated.\n// </auto-generated>\n//------------------------------------------------------------------------------\n\nusing BenchmarkDotNet.Attributes;\n\nusing System.Threading.Tasks;\n\nnamespace BenchmarkDotNet.IntegrationTests.InProcess.EmitTests\n{\n    /// <summary>\n    /// Generated class to check emitted msil cases\n    /// </summary>\n    public class RunnableTaskCaseBenchmark\n    {\n        // ---- Begin TaskCase(Task) ----\n\n        [Benchmark]\n        public Task TaskCase1() => Task.CompletedTask;\n\n        [Benchmark, Arguments(1, \"1\", 0.1)]\n        public Task TaskCase1(int x, string y, double? z) => Task.CompletedTask;\n\n        // ---- Begin TaskCase(Task<int>) ----\n\n        [Benchmark]\n        public Task<int> TaskCase2() => Task.FromResult(123);\n\n        [Benchmark, Arguments(2, \"2\", 0.2)]\n        public Task<int> TaskCase2(int x, string y, double? z) => Task.FromResult(123);\n\n        // ---- Begin TaskCase(ValueTask) ----\n\n        [Benchmark]\n        public ValueTask TaskCase3() => new ValueTask();\n\n        [Benchmark, Arguments(3, \"3\", 0.3)]\n        public ValueTask TaskCase3(int x, string y, double? z) => new ValueTask();\n\n        // ---- Begin TaskCase(ValueTask<string>) ----\n\n        [Benchmark]\n        public ValueTask<string> TaskCase4() => new ValueTask<string>(\"\");\n\n        [Benchmark, Arguments(4, \"4\", 0.4)]\n        public ValueTask<string> TaskCase4(int x, string y, double? z) => new ValueTask<string>(\"\");\n\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/InProcess.EmitTests.T4/RunnableTaskCaseBenchmark.tt",
    "content": "﻿<#@ template debug=\"false\" hostspecific=\"false\" language=\"C#\" #>\n<#@ assembly name=\"System.Core\" #>\n<#@ output extension=\".cs\" #>\n//------------------------------------------------------------------------------\n// <auto-generated>\n//     This code was generated by a tool.\n//\n//     Changes to this file may cause incorrect behavior and will be lost if\n//     the code is regenerated.\n// </auto-generated>\n//------------------------------------------------------------------------------\n\nusing BenchmarkDotNet.Attributes;\n\nusing System.Threading.Tasks;\n\nnamespace BenchmarkDotNet.IntegrationTests.InProcess.EmitTests\n{\n    /// <summary>\n    /// Generated class to check emitted msil cases\n    /// </summary>\n    public class RunnableTaskCaseBenchmark\n    {\n<#\n    int counter = 1;\n    EmitTaskCaseBenchmark(ref counter, \"Task\", \"Task.CompletedTask\");\n    EmitTaskCaseBenchmark(ref counter, \"Task<int>\", \"Task.FromResult(123)\");\n    EmitTaskCaseBenchmark(ref counter, \"ValueTask\", \"new ValueTask()\");\n    EmitTaskCaseBenchmark(ref counter, \"ValueTask<string>\", \"new ValueTask<string>(\\\"\\\")\");\n\n    // BDN do not support custom awaitables\n    //EmitTaskCaseBenchmark(ref counter, \"ConfiguredTaskAwaitable\", \"Task.CompletedTask.ConfigureAwait(false)\");\n    //EmitTaskCaseBenchmark(ref counter, \"ConfiguredTaskAwaitable<int?>\", \"Task.FromResult((int?)123).ConfigureAwait(false)\");\n    //EmitTaskCaseBenchmark(ref counter, \"ConfiguredValueTaskAwaitable<string>\", \"new ValueTask<string>(\\\"\\\").ConfigureAwait(false)\");\n\n    //EmitTaskCaseBenchmark(ref counter, \"CustomAwatiableStruct\", \"new CustomAwatiableStruct()\");\n    //EmitTaskCaseBenchmark(ref counter, \"CustomAwatiableStruct2\", \"new CustomAwatiableStruct2()\");\n    //EmitTaskCaseBenchmark(ref counter, \"CustomAwatiableClass\", \"new CustomAwatiableClass()\");\n    //EmitTaskCaseBenchmark(ref counter, \"CustomAwatiableClass2\", \"new CustomAwatiableClass2()\");\n#>\n    }\n}<#+\n\n    private void EmitTaskCaseBenchmark(ref int counter, string type, string returnCode)\n    {\n#>\n        // ---- Begin TaskCase(<#=type#>) ----\n\n        [Benchmark]\n        public <#=type#> TaskCase<#=counter#>() => <#=returnCode#>;\n\n        [Benchmark, Arguments(<#=counter#>, \"<#=counter#>\", 0.<#=counter#>)]\n        public <#=type#> TaskCase<#=counter#>(int x, string y, double? z) => <#=returnCode#>;\n\n<#+\n        counter++;\n    }\n#>\n"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/InProcess.EmitTests.T4/RunnableVoidCaseBenchmark.cs",
    "content": "﻿//------------------------------------------------------------------------------\n// <auto-generated>\n//     This code was generated by a tool.\n//\n//     Changes to this file may cause incorrect behavior and will be lost if\n//     the code is regenerated.\n// </auto-generated>\n//------------------------------------------------------------------------------\n\nusing BenchmarkDotNet.Attributes;\n\nnamespace BenchmarkDotNet.IntegrationTests.InProcess.EmitTests\n{\n    /// <summary>\n    /// Generated class to check emitted msil cases\n    /// </summary>\n    public class RunnableVoidCaseBenchmark\n    {\n        // ---- Begin VoidCase ----\n\n        [Benchmark]\n        public void VoidCase() { }\n\n        [Benchmark, Arguments(1)]\n        public void VoidCase(int x) { }\n\n        [Benchmark, Arguments(1, \"2\", 3.0)]\n        public void VoidCase(int x, ref string y, double? z) { }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/InProcess.EmitTests.T4/RunnableVoidCaseBenchmark.tt",
    "content": "﻿<#@ template debug=\"false\" hostspecific=\"false\" language=\"C#\" #>\n<#@ assembly name=\"System.Core\" #>\n<#@ output extension=\".cs\" #>\n//------------------------------------------------------------------------------\n// <auto-generated>\n//     This code was generated by a tool.\n//\n//     Changes to this file may cause incorrect behavior and will be lost if\n//     the code is regenerated.\n// </auto-generated>\n//------------------------------------------------------------------------------\n\nusing BenchmarkDotNet.Attributes;\n\nnamespace BenchmarkDotNet.IntegrationTests.InProcess.EmitTests\n{\n    /// <summary>\n    /// Generated class to check emitted msil cases\n    /// </summary>\n    public class RunnableVoidCaseBenchmark\n    {\n<#\n    EmitVoidCaseBenchmark();\n#>\n    }\n}<#+\n\n    private void EmitVoidCaseBenchmark()\n    {\n#>\n        // ---- Begin VoidCase ----\n\n        [Benchmark]\n        public void VoidCase() { }\n\n        [Benchmark, Arguments(1)]\n        public void VoidCase(int x) { }\n\n        [Benchmark, Arguments(1, \"2\", 3.0)]\n        public void VoidCase(int x, ref string y, double? z) { }\n<#+\n    }\n#>\n"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/InProcessDiagnoserTests.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Columns;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.IntegrationTests.Diagnosers;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Tests.Loggers;\nusing BenchmarkDotNet.Toolchains.InProcess.Emit;\nusing BenchmarkDotNet.Toolchains.InProcess.NoEmit;\nusing Xunit;\nusing Xunit.Abstractions;\nusing RunMode = BenchmarkDotNet.Diagnosers.RunMode;\n\nnamespace BenchmarkDotNet.IntegrationTests;\n\npublic class InProcessDiagnoserTests(ITestOutputHelper output) : BenchmarkTestExecutor(output)\n{\n    // For test explorer since it doesn't handle interfaces well.\n    public enum ToolchainType\n    {\n        Default,\n        InProcessEmit,\n        InProcessNoEmit,\n    }\n\n    private static IEnumerable<RunMode[]> GetRunModeCombinations(int count)\n    {\n        var runModes = (RunMode[]) Enum.GetValues(typeof(RunMode));\n\n        if (count == 1)\n        {\n            foreach (var runMode in runModes)\n            {\n                yield return [runMode];\n            }\n        }\n        else if (count == 3)\n        {\n            foreach (var runMode1 in runModes)\n            {\n                foreach (var runMode2 in runModes)\n                {\n                    foreach (var runMode3 in runModes)\n                    {\n                        yield return [runMode1, runMode2, runMode3];\n                    }\n                }\n            }\n        }\n    }\n\n    public static IEnumerable<object[]> GetTestCombinations()\n    {\n        var toolchains = (ToolchainType[]) Enum.GetValues(typeof(ToolchainType));\n        var counts = new[] { 1, 3 };\n\n        foreach (var toolchain in toolchains)\n        {\n            foreach (var count in counts)\n            {\n                foreach (var runModes in GetRunModeCombinations(count))\n                {\n                    if (ShouldSkip())\n                    {\n                        continue;\n                    }\n                    yield return [runModes, toolchain];\n\n                    bool ShouldSkip()\n                    {\n                        // Default toolchain is much slower than in-process toolchains, so to prevent CI from taking too much time, we skip combinations with duplicate run modes.\n                        if (toolchain != ToolchainType.Default || runModes.Length != 3)\n                            return false;\n                        if (runModes[0] == runModes[1] || runModes[0] == runModes[2] || runModes[1] == runModes[2])\n                            return true;\n                        // We still want to test some combination of NoOverhead + ExtraIteration, but not excessively.\n                        if (RunsDuringSameLaunch(runModes[0]) && RunsDuringSameLaunch(runModes[2]))\n                            return true;\n                        if (RunsDuringSameLaunch(runModes[1]) && RunsDuringSameLaunch(runModes[2]))\n                            return true;\n                        // Reduce test time by skipping extra None modes.\n                        return runModes[0] == RunMode.None || runModes[2] == RunMode.None;\n                    }\n                }\n            }\n        }\n    }\n\n    private static bool RunsDuringSameLaunch(RunMode runMode)\n        => runMode is RunMode.NoOverhead or RunMode.ExtraIteration;\n\n    private static BaseMockInProcessDiagnoser CreateDiagnoser(RunMode runMode, int index)\n        => index switch\n        {\n            0 => new MockInProcessDiagnoser1(runMode),\n            1 => new MockInProcessDiagnoser2(runMode),\n            2 => new MockInProcessDiagnoser3(runMode),\n            _ => throw new ArgumentException($\"Unsupported index: {index}\")\n        };\n\n    private ManualConfig CreateConfig(ToolchainType toolchain)\n    {\n        var job = toolchain switch\n        {\n            ToolchainType.InProcessEmit => Job.Dry.WithToolchain(InProcessEmitToolchain.Default),\n            ToolchainType.InProcessNoEmit => Job.Dry.WithToolchain(InProcessNoEmitToolchain.Default),\n            _ => Job.Dry\n        };\n\n        return new ManualConfig()\n            .AddLogger(new OutputLogger(Output))\n            .AddColumnProvider(DefaultColumnProviders.Instance)\n            .AddJob(job);\n    }\n\n    [Theory]\n    [MemberData(nameof(GetTestCombinations))]\n    public void MultipleInProcessDiagnosersWork(RunMode[] runModes, ToolchainType toolchain)\n    {\n        try\n        {\n            var diagnosers = runModes.Select(CreateDiagnoser).ToArray();\n            var config = CreateConfig(toolchain);\n\n            foreach (var diagnoser in diagnosers)\n            {\n                config = config.AddDiagnoser(diagnoser);\n            }\n\n            var summary = CanExecute<SimpleBenchmark>(config);\n\n            foreach (var diagnoser in diagnosers)\n            {\n                if (diagnoser.RunMode == RunMode.None)\n                {\n                    Assert.Empty(diagnoser.Results);\n                }\n                else\n                {\n                    Assert.NotEmpty(diagnoser.Results);\n                    Assert.Equal(summary.BenchmarksCases.Length, diagnoser.Results.Count);\n                    Assert.All(diagnoser.Results.Values, result => Assert.Equal(diagnoser.ExpectedResult, result));\n                }\n            }\n            Assert.Equal(\n                diagnosers\n                    .Where(d => d.RunMode != RunMode.None)\n                    .OrderBy(d => d.RunMode switch\n                    {\n                        RunMode.NoOverhead => 0,\n                        RunMode.ExtraIteration => 1,\n                        RunMode.ExtraRun => 2,\n                        RunMode.SeparateLogic => 3,\n                        _ => 4\n                    })\n                    .Select(d => d.ExpectedResult),\n                GetOrderedResults()\n            );\n        }\n        finally\n        {\n            BaseMockInProcessDiagnoser.s_completedResults.Clear();\n        }\n    }\n\n    private static IEnumerable<string> GetOrderedResults()\n    {\n        // RunMode.NoOverhead and RunMode.ExtraIteration run in the same benchmark run,\n        // so we need to re-order the completed results according to the order that they received their signal,\n        // while leaving the other run modes in the same spot.\n        var unorderedResults = new Queue<(int order, string result)>();\n\n        bool wasLastOrdered = true;\n        foreach (var (runMode, order, result) in BaseMockInProcessDiagnoser.s_completedResults)\n        {\n            if (RunsDuringSameLaunch(runMode))\n            {\n                wasLastOrdered = false;\n                unorderedResults.Enqueue((order, result));\n                continue;\n            }\n\n            if (!wasLastOrdered)\n            {\n                wasLastOrdered = true;\n                foreach (var (_, r) in unorderedResults.OrderBy(t => t.order))\n                {\n                    yield return r;\n                }\n                unorderedResults.Clear();\n            }\n            yield return result;\n        }\n\n        foreach (var (_, result) in unorderedResults.OrderBy(t => t.order))\n        {\n            yield return result;\n        }\n    }\n\n    public class SimpleBenchmark\n    {\n        private int counter;\n\n        [Benchmark]\n        public void BenchmarkMethod()\n        {\n            Interlocked.Increment(ref counter);\n        }\n    }\n}\n"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/InProcessEmitTest.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Columns;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.IntegrationTests.Diagnosers;\nusing BenchmarkDotNet.IntegrationTests.InProcess.EmitTests;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Tests.Loggers;\nusing BenchmarkDotNet.Tests.XUnit;\nusing BenchmarkDotNet.Toolchains.InProcess.Emit;\nusing BenchmarkDotNet.Toolchains.Roslyn;\nusing JetBrains.Annotations;\nusing Xunit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.IntegrationTests\n{\n    public class InProcessEmitTest : BenchmarkTestExecutor\n    {\n        public InProcessEmitTest(ITestOutputHelper output) : base(output) { }\n\n        private const decimal DecimalResult = 42;\n        private const string StringResult = \"42\";\n\n        private const int UnrollFactor = 16;\n\n        private IConfig CreateInProcessConfig(OutputLogger? logger)\n        {\n            return new ManualConfig()\n                .AddJob(Job.Dry.WithToolchain(InProcessEmitToolchain.Default).WithInvocationCount(UnrollFactor).WithUnrollFactor(UnrollFactor))\n                .AddLogger(logger ?? (Output != null ? new OutputLogger(Output) : ConsoleLogger.Default))\n                .AddColumnProvider(DefaultColumnProviders.Instance);\n        }\n\n        private IConfig CreateInProcessAndRoslynConfig(OutputLogger logger)\n        {\n            var config = new ManualConfig()\n                .AddColumnProvider(DefaultConfig.Instance.GetColumnProviders().ToArray())\n                .AddAnalyser(DefaultConfig.Instance.GetAnalysers().ToArray())\n                .AddExporter(DefaultConfig.Instance.GetExporters().ToArray())\n                .AddFilter(DefaultConfig.Instance.GetFilters().ToArray())\n                .AddLogger(DefaultConfig.Instance.GetLoggers().ToArray())\n                .AddJob(\n                    Job.Dry\n                        .WithToolchain(InProcessEmitToolchain.Default)\n                        .WithInvocationCount(4)\n                        .WithUnrollFactor(4))\n                .AddJob(\n                    Job.Dry\n                        .WithToolchain(new RoslynToolchain())\n                        .WithInvocationCount(4)\n                        .WithUnrollFactor(4))\n                .WithOptions(ConfigOptions.KeepBenchmarkFiles)\n                .AddLogger(logger ?? (Output != null ? new OutputLogger(Output) : ConsoleLogger.Default));\n\n            return config;\n        }\n\n        private void DiffEmit(Summary summary)\n        {\n            // .Net Core does not support assembly saving so far\n            // SEE https://github.com/dotnet/corefx/issues/4491\n            // TODO: Use new PersistedAssemblyBuilder when BDN and tests are updated to net9.0 or newer.\n            if (!Portability.RuntimeInformation.IsFullFramework)\n                return;\n\n            var benchmarkCase = summary.BenchmarksCases.First();\n            // The benchmark config built jobs with 2 toolchains, 1 InProcessEmit and 1 Roslyn,\n            // so we need to subtract 1 from the partition counter to obtain the emit output.\n            NaiveRunnableEmitDiff.RunDiff(\n                $@\"{BuildPartition.GetProgramName(benchmarkCase, BuildPartition.s_partitionCounter)}.exe\",\n                $@\"{BuildPartition.GetProgramName(benchmarkCase, BuildPartition.s_partitionCounter - 1)}Emitted.dll\",\n                ConsoleLogger.Default);\n        }\n\n        [Fact]\n        public void InProcessBenchmarkSimpleCasesReflectionEmitSupported()\n        {\n            var logger = new OutputLogger(Output);\n            var config = CreateInProcessConfig(logger);\n\n            try\n            {\n                BenchmarkAllCases.Counter = 0;\n\n                var summary = CanExecute<BenchmarkAllCases>(config);\n\n                string testLog = logger.GetLog();\n                Assert.Contains(\"// Benchmark: BenchmarkAllCases.InvokeOnceVoid:\", testLog);\n                Assert.DoesNotContain(\"No benchmarks found\", logger.GetLog());\n\n                // Operations + GlobalSetup + GlobalCleanup\n                long expectedCount = summary.Reports\n                    .SelectMany(r => r.AllMeasurements)\n                    .Where(m => m.IterationStage != IterationStage.Result)\n                    .Sum(m => m.Operations + 2);\n                Assert.Equal(expectedCount, BenchmarkAllCases.Counter);\n            }\n            finally\n            {\n                BenchmarkAllCases.Counter = 0;\n            }\n        }\n\n        [TheoryEnvSpecific(\"We can't use Roslyn toolchain for .NET Core because we don't know which assemblies to reference and .NET Core does not support dynamic assembly saving\", EnvRequirement.FullFrameworkOnly)]\n        [InlineData(typeof(SampleBenchmark))]\n        [InlineData(typeof(RunnableVoidCaseBenchmark))]\n        [InlineData(typeof(RunnableRefStructCaseBenchmark))]\n        [InlineData(typeof(RunnableStructCaseBenchmark))]\n        [InlineData(typeof(RunnableClassCaseBenchmark))]\n        [InlineData(typeof(RunnableManyArgsCaseBenchmark))]\n        [InlineData(typeof(RunnableTaskCaseBenchmark))]\n        public void InProcessBenchmarkEmitsSameIL(Type benchmarkType)\n        {\n            var logger = new OutputLogger(Output);\n            var config = CreateInProcessAndRoslynConfig(logger);\n\n            var summary = CanExecute(benchmarkType, config);\n\n            DiffEmit(summary);\n\n            string testLog = logger.GetLog();\n            Assert.Contains(benchmarkType.Name, testLog);\n            Assert.DoesNotContain(\"No benchmarks found\", logger.GetLog());\n        }\n\n        [UsedImplicitly(ImplicitUseTargetFlags.WithMembers)]\n        public class BenchmarkAllCases\n        {\n            public static int Counter;\n\n            [GlobalSetup]\n            public static void GlobalSetup()\n            {\n                Interlocked.Increment(ref Counter);\n            }\n\n            [GlobalCleanup]\n            public void GlobalCleanup() => Interlocked.Increment(ref Counter);\n\n            [Benchmark]\n            public void InvokeOnceVoid()\n            {\n                Interlocked.Increment(ref Counter);\n            }\n\n            [Benchmark]\n            public async Task InvokeOnceTaskAsync()\n            {\n                await Task.Yield();\n                Interlocked.Increment(ref Counter);\n            }\n\n            [Benchmark]\n            public async ValueTask InvokeOnceValueTaskAsync()\n            {\n                await Task.Yield();\n                Interlocked.Increment(ref Counter);\n            }\n\n            [Benchmark]\n            public string InvokeOnceRefType()\n            {\n                Interlocked.Increment(ref Counter);\n                return StringResult;\n            }\n\n            [Benchmark]\n            public decimal InvokeOnceValueType()\n            {\n                Interlocked.Increment(ref Counter);\n                return DecimalResult;\n            }\n\n            [Benchmark]\n            public async Task<string> InvokeOnceTaskOfTAsync()\n            {\n                await Task.Yield();\n                Interlocked.Increment(ref Counter);\n                return StringResult;\n            }\n\n            [Benchmark]\n            public ValueTask<decimal> InvokeOnceValueTaskOfT()\n            {\n                Interlocked.Increment(ref Counter);\n                return new ValueTask<decimal>(DecimalResult);\n            }\n\n            [Benchmark]\n            public static void InvokeOnceStaticVoid()\n            {\n                Interlocked.Increment(ref Counter);\n            }\n\n            [Benchmark]\n            public static async Task InvokeOnceStaticTaskAsync()\n            {\n                await Task.Yield();\n                Interlocked.Increment(ref Counter);\n            }\n\n            [Benchmark]\n            public static async ValueTask InvokeOnceStaticValueTaskAsync()\n            {\n                await Task.Yield();\n                Interlocked.Increment(ref Counter);\n            }\n\n            [Benchmark]\n            public static string InvokeOnceStaticRefType()\n            {\n                Interlocked.Increment(ref Counter);\n                return StringResult;\n            }\n\n            [Benchmark]\n            public static decimal InvokeOnceStaticValueType()\n            {\n                Interlocked.Increment(ref Counter);\n                return DecimalResult;\n            }\n\n            [Benchmark]\n            public static async Task<string> InvokeOnceStaticTaskOfTAsync()\n            {\n                await Task.Yield();\n                Interlocked.Increment(ref Counter);\n                return StringResult;\n            }\n\n            [Benchmark]\n            public static ValueTask<decimal> InvokeOnceStaticValueTaskOfT()\n            {\n                Interlocked.Increment(ref Counter);\n                return new ValueTask<decimal>(DecimalResult);\n            }\n        }\n\n        [Theory]\n        [InlineData(typeof(IterationSetupCleanup))]\n        [InlineData(typeof(GlobalSetupCleanupTask))]\n        [InlineData(typeof(GlobalSetupCleanupValueTask))]\n        [InlineData(typeof(GlobalSetupCleanupValueTaskSource))]\n        public void InProcessEmitToolchainSupportsSetupAndCleanup(Type benchmarkType)\n        {\n            var logger = new OutputLogger(Output);\n            var config = CreateInProcessConfig(logger);\n\n            Counters.SetupCounter = 0;\n            Counters.BenchmarkCounter = 0;\n            Counters.CleanupCounter = 0;\n\n            var summary = CanExecute(benchmarkType, config);\n\n            Assert.Equal(1, Counters.SetupCounter);\n            Assert.Equal(16, Counters.BenchmarkCounter);\n            Assert.Equal(1, Counters.CleanupCounter);\n        }\n\n        private static class Counters\n        {\n            public static int SetupCounter, BenchmarkCounter, CleanupCounter;\n        }\n\n        public class IterationSetupCleanup\n        {\n            [IterationSetup]\n            public void Setup() => Interlocked.Increment(ref Counters.SetupCounter);\n\n            [Benchmark]\n            public void Benchmark() => Interlocked.Increment(ref Counters.BenchmarkCounter);\n\n            [IterationCleanup]\n            public void Cleanup() => Interlocked.Increment(ref Counters.CleanupCounter);\n        }\n\n        public class GlobalSetupCleanupTask\n        {\n            [GlobalSetup]\n            public static async Task GlobalSetup()\n            {\n                await Task.Yield();\n                Interlocked.Increment(ref Counters.SetupCounter);\n            }\n\n            [GlobalCleanup]\n            public async Task<int> GlobalCleanup()\n            {\n                await Task.Yield();\n                Interlocked.Increment(ref Counters.CleanupCounter);\n                return 42;\n            }\n\n            [Benchmark]\n            public void InvokeOnceVoid()\n            {\n                Interlocked.Increment(ref Counters.BenchmarkCounter);\n            }\n        }\n\n        public class GlobalSetupCleanupValueTask\n        {\n            [GlobalSetup]\n            public static async ValueTask GlobalSetup()\n            {\n                await Task.Yield();\n                Interlocked.Increment(ref Counters.SetupCounter);\n            }\n\n            [GlobalCleanup]\n            public async ValueTask<int> GlobalCleanup()\n            {\n                await Task.Yield();\n                Interlocked.Increment(ref Counters.CleanupCounter);\n                return 42;\n            }\n\n            [Benchmark]\n            public void InvokeOnceVoid()\n            {\n                Interlocked.Increment(ref Counters.BenchmarkCounter);\n            }\n        }\n\n        public class GlobalSetupCleanupValueTaskSource\n        {\n            private readonly static ValueTaskSource<int> valueTaskSource = new();\n\n            [GlobalSetup]\n            public static ValueTask GlobalSetup()\n            {\n                valueTaskSource.Reset();\n                Task.Delay(1).ContinueWith(_ =>\n                {\n                    Interlocked.Increment(ref Counters.SetupCounter);\n                    valueTaskSource.SetResult(42);\n                });\n                return new ValueTask(valueTaskSource, valueTaskSource.Token);\n            }\n\n            [GlobalCleanup]\n            public ValueTask<int> GlobalCleanup()\n            {\n                valueTaskSource.Reset();\n                Task.Delay(1).ContinueWith(_ =>\n                {\n                    Interlocked.Increment(ref Counters.CleanupCounter);\n                    valueTaskSource.SetResult(42);\n                });\n                return new ValueTask<int>(valueTaskSource, valueTaskSource.Token);\n            }\n\n            [Benchmark]\n            public void InvokeOnceVoid()\n            {\n                Interlocked.Increment(ref Counters.BenchmarkCounter);\n            }\n        }\n\n\n#if NET8_0_OR_GREATER\n        [Fact]\n        public void ParamsSupportRequiredProperty()\n        {\n            var config = CreateInProcessConfig(null);\n            CanExecute<ParamsTestRequiredProperty>(config);\n        }\n\n        public class ParamsTestRequiredProperty\n        {\n            private const string Expected = \"a\";\n\n            [Params(Expected)]\n            public required string ParamProperty { get; set; }\n\n            [Benchmark]\n            public void Benchmark() => Assert.Equal(Expected, ParamProperty);\n        }\n#endif\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/InProcessTest.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing System.Linq.Expressions;\nusing System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Columns;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Tests.Loggers;\nusing BenchmarkDotNet.Toolchains.InProcess.NoEmit;\nusing JetBrains.Annotations;\nusing Xunit;\nusing Xunit.Abstractions;\n\n\nnamespace BenchmarkDotNet.IntegrationTests\n{\n    public class InProcessTest : BenchmarkTestExecutor\n    {\n        public InProcessTest(ITestOutputHelper output) : base(output)\n        {\n        }\n\n        private const decimal DecimalResult = 42;\n        private const string StringResult = \"42\";\n\n        private const int UnrollFactor = 16;\n\n        [Fact]\n        public void BenchmarkActionGlobalSetupSupported() => TestInvoke(x => BenchmarkAllCases.GlobalSetup(), UnrollFactor);\n\n        [Fact]\n        public void BenchmarkActionGlobalCleanupSupported() => TestInvoke(x => x.GlobalCleanup(), UnrollFactor);\n\n        [Fact]\n        public void BenchmarkActionVoidSupported() => TestInvoke(x => x.InvokeOnceVoid(), UnrollFactor);\n\n        [Fact]\n        public void BenchmarkActionTaskSupported() => TestInvoke(x => x.InvokeOnceTaskAsync(), UnrollFactor);\n\n        [Fact]\n        public void BenchmarkActionValueTaskSupported() => TestInvoke(x => x.InvokeOnceValueTaskAsync(), UnrollFactor);\n\n        [Fact]\n        public void BenchmarkActionRefTypeSupported() => TestInvoke(x => x.InvokeOnceRefType(), UnrollFactor);\n\n        [Fact]\n        public void BenchmarkActionValueTypeSupported() => TestInvoke(x => x.InvokeOnceValueType(), UnrollFactor);\n\n        [Fact]\n        public void BenchmarkActionTaskOfTSupported() => TestInvoke(x => x.InvokeOnceTaskOfTAsync(), UnrollFactor);\n\n        [Fact]\n        public void BenchmarkActionValueTaskOfTSupported() => TestInvoke(x => x.InvokeOnceValueTaskOfT(), UnrollFactor);\n\n        [Fact]\n        public unsafe void BenchmarkActionVoidPointerSupported() => TestInvoke(x => x.InvokeOnceVoidPointerType(), UnrollFactor);\n\n        // Can't use ref returns in expression, so pass the MethodInfo directly instead.\n        [Fact]\n        public void BenchmarkActionByRefTypeSupported() => TestInvoke(typeof(BenchmarkAllCases).GetMethod(nameof(BenchmarkAllCases.InvokeOnceByRefType))!, UnrollFactor);\n\n        [Fact]\n        public void BenchmarkActionByRefReadonlyValueTypeSupported() => TestInvoke(typeof(BenchmarkAllCases).GetMethod(nameof(BenchmarkAllCases.InvokeOnceByRefReadonlyType))!, UnrollFactor);\n\n        [Fact]\n        public void BenchmarkDifferentPlatformReturnsValidationError()\n        {\n            var otherPlatform = IntPtr.Size == 8\n                ? Platform.X86\n                : Platform.X64;\n\n            var otherPlatformConfig = new ManualConfig()\n                .AddJob(Job.Dry.WithToolchain(InProcessNoEmitToolchain.Default).WithPlatform(otherPlatform))\n                .AddLogger(new OutputLogger(Output))\n                .AddColumnProvider(DefaultColumnProviders.Instance);\n\n            var runInfo = BenchmarkConverter.TypeToBenchmarks(typeof(BenchmarkAllCases), otherPlatformConfig);\n            var summary = BenchmarkRunner.Run(runInfo);\n\n            Assert.NotEmpty(summary.ValidationErrors);\n        }\n\n        [AssertionMethod]\n        private void TestInvoke(Expression<Action<BenchmarkAllCases>> methodCall, int unrollFactor)\n        {\n            var targetMethod = ((MethodCallExpression)methodCall.Body).Method;\n            var descriptor = new Descriptor(typeof(BenchmarkAllCases), targetMethod, targetMethod, targetMethod);\n\n            // Run mode\n            var action = BenchmarkActionFactory.CreateWorkload(descriptor, new BenchmarkAllCases(), unrollFactor);\n            TestInvoke(action, unrollFactor, false);\n\n            // Idle mode\n            action = BenchmarkActionFactory.CreateOverhead(descriptor, new BenchmarkAllCases(), unrollFactor);\n            TestInvoke(action, unrollFactor, true);\n\n            // GlobalSetup/GlobalCleanup\n            action = BenchmarkActionFactory.CreateGlobalSetup(descriptor, new BenchmarkAllCases());\n            TestInvoke(action, 1, false);\n            action = BenchmarkActionFactory.CreateGlobalCleanup(descriptor, new BenchmarkAllCases());\n            TestInvoke(action, 1, false);\n\n            // GlobalSetup/GlobalCleanup (empty)\n            descriptor = new Descriptor(typeof(BenchmarkAllCases), targetMethod);\n            action = BenchmarkActionFactory.CreateGlobalSetup(descriptor, new BenchmarkAllCases());\n            TestInvoke(action, unrollFactor, true);\n            action = BenchmarkActionFactory.CreateGlobalCleanup(descriptor, new BenchmarkAllCases());\n            TestInvoke(action, unrollFactor, true);\n        }\n\n        [AssertionMethod]\n        private void TestInvoke<T>(Expression<Func<BenchmarkAllCases, T>> methodCall, int unrollFactor)\n        {\n            var targetMethod = ((MethodCallExpression)methodCall.Body).Method;\n            TestInvoke(targetMethod, unrollFactor);\n        }\n\n        [AssertionMethod]\n        private void TestInvoke(MethodInfo targetMethod, int unrollFactor)\n        {\n            var descriptor = new Descriptor(typeof(BenchmarkAllCases), targetMethod);\n\n            // Run mode\n            var action = BenchmarkActionFactory.CreateWorkload(descriptor, new BenchmarkAllCases(), unrollFactor);\n            TestInvoke(action, unrollFactor, false);\n\n            // Idle mode\n            action = BenchmarkActionFactory.CreateOverhead(descriptor, new BenchmarkAllCases(), unrollFactor);\n            TestInvoke(action, unrollFactor, true);\n        }\n\n        [AssertionMethod]\n        private void TestInvoke(BenchmarkAction benchmarkAction, int unrollFactor, bool isIdle)\n        {\n            try\n            {\n                BenchmarkAllCases.Counter = 0;\n\n                if (isIdle)\n                {\n                    benchmarkAction.InvokeSingle();\n                    Assert.Equal(0, BenchmarkAllCases.Counter);\n                    benchmarkAction.InvokeUnroll(0);\n                    Assert.Equal(0, BenchmarkAllCases.Counter);\n                    benchmarkAction.InvokeUnroll(11);\n                    Assert.Equal(0, BenchmarkAllCases.Counter);\n                }\n                else\n                {\n                    benchmarkAction.InvokeSingle();\n                    Assert.Equal(1, BenchmarkAllCases.Counter);\n                    benchmarkAction.InvokeUnroll(0);\n                    Assert.Equal(1, BenchmarkAllCases.Counter);\n                    benchmarkAction.InvokeUnroll(11);\n                    Assert.Equal(BenchmarkAllCases.Counter, 1 + unrollFactor * 11);\n                }\n            }\n            finally\n            {\n                BenchmarkAllCases.Counter = 0;\n            }\n        }\n\n        private IConfig CreateInProcessConfig(OutputLogger? logger = null)\n        {\n            return new ManualConfig()\n                .AddJob(Job.Dry.WithToolchain(InProcessNoEmitToolchain.Default).WithInvocationCount(UnrollFactor).WithUnrollFactor(UnrollFactor))\n                .AddLogger(logger ?? (Output != null ? new OutputLogger(Output) : ConsoleLogger.Default))\n                .AddColumnProvider(DefaultColumnProviders.Instance);\n        }\n\n        [Fact]\n        public void InProcessBenchmarkAllCasesSupported()\n        {\n            var logger = new OutputLogger(Output);\n            var config = CreateInProcessConfig(logger);\n\n            try\n            {\n                BenchmarkAllCases.Counter = 0;\n\n                var summary = CanExecute<BenchmarkAllCases>(config);\n\n                var testLog = logger.GetLog();\n                Assert.Contains(\"// Benchmark: BenchmarkAllCases.InvokeOnceVoid:\", testLog);\n                Assert.DoesNotContain(\"No benchmarks found\", logger.GetLog());\n\n                // Operations + GlobalSetup + GlobalCleanup\n                long expectedCount = summary.Reports\n                    .SelectMany(r => r.AllMeasurements)\n                    .Where(m => m.IterationStage != IterationStage.Result)\n                    .Sum(m => m.Operations + 2);\n                Assert.Equal(expectedCount, BenchmarkAllCases.Counter);\n            }\n            finally\n            {\n                BenchmarkAllCases.Counter = 0;\n            }\n        }\n\n        [UsedImplicitly(ImplicitUseTargetFlags.WithMembers)]\n        public class BenchmarkAllCases\n        {\n            public static int Counter;\n\n            [GlobalSetup]\n            public static void GlobalSetup()\n            {\n                Interlocked.Increment(ref Counter);\n            }\n\n            [GlobalCleanup]\n            public void GlobalCleanup() => Interlocked.Increment(ref Counter);\n\n            [Benchmark]\n            public void InvokeOnceVoid()\n            {\n                Interlocked.Increment(ref Counter);\n            }\n\n            [Benchmark]\n            public async Task InvokeOnceTaskAsync()\n            {\n                await Task.Yield();\n                Interlocked.Increment(ref Counter);\n            }\n\n            [Benchmark]\n            public async ValueTask InvokeOnceValueTaskAsync()\n            {\n                await Task.Yield();\n                Interlocked.Increment(ref Counter);\n            }\n\n            [Benchmark]\n            public string InvokeOnceRefType()\n            {\n                Interlocked.Increment(ref Counter);\n                return StringResult;\n            }\n\n            [Benchmark]\n            public decimal InvokeOnceValueType()\n            {\n                Interlocked.Increment(ref Counter);\n                return DecimalResult;\n            }\n\n            [Benchmark]\n            public async Task<string> InvokeOnceTaskOfTAsync()\n            {\n                await Task.Yield();\n                Interlocked.Increment(ref Counter);\n                return StringResult;\n            }\n\n            [Benchmark]\n            public ValueTask<decimal> InvokeOnceValueTaskOfT()\n            {\n                Interlocked.Increment(ref Counter);\n                return new ValueTask<decimal>(DecimalResult);\n            }\n\n            [Benchmark]\n            public ref int InvokeOnceByRefType()\n            {\n                Interlocked.Increment(ref Counter);\n                return ref Counter;\n            }\n\n            [Benchmark]\n            public ref readonly int InvokeOnceByRefReadonlyType()\n            {\n                Interlocked.Increment(ref Counter);\n                return ref Counter;\n            }\n\n            [Benchmark]\n            public unsafe void* InvokeOnceVoidPointerType()\n            {\n                Interlocked.Increment(ref Counter);\n                return default;\n            }\n\n#if NET9_0_OR_GREATER\n            [Benchmark]\n            public Span<int> InvokeOnceRefStruct()\n            {\n                Interlocked.Increment(ref Counter);\n                return default;\n            }\n\n            // This doesn't make much sense in practice, but the type system allows it, so we test it.\n            [Benchmark]\n            public ref Span<int> InvokeOnceByRefRefStruct()\n            {\n                Interlocked.Increment(ref Counter);\n                return ref Unsafe.NullRef<Span<int>>();\n            }\n\n            [Benchmark]\n            public ref readonly Span<int> InvokeOnceByRefReadonlyRefStruct()\n            {\n                Interlocked.Increment(ref Counter);\n                return ref Unsafe.NullRef<Span<int>>();\n            }\n#endif\n        }\n\n\n#if NET8_0_OR_GREATER\n        [Fact]\n        public void ParamsSupportRequiredProperty()\n        {\n            var config = CreateInProcessConfig();\n            CanExecute<ParamsTestRequiredProperty>(config);\n        }\n\n        public class ParamsTestRequiredProperty\n        {\n            private const string Expected = \"a\";\n\n            [Params(Expected)]\n            public required string ParamProperty { get; set; }\n\n            [Benchmark]\n            public void Benchmark() => Assert.Equal(Expected, ParamProperty);\n        }\n#endif\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/IntegrationTestSetupTests.cs",
    "content": "using BenchmarkDotNet.Helpers;\nusing Xunit;\n\nnamespace BenchmarkDotNet.IntegrationTests;\n\npublic class IntegrationTestSetupTests\n{\n    [Fact]\n    public void IntegrationTestsAreDetected() => Assert.True(XUnitHelper.IsIntegrationTest.Value);\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/JitOptimizationsTests.cs",
    "content": "using System;\nusing System.Linq;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Validators;\nusing Xunit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.IntegrationTests\n{\n    public class JitOptimizationsTests\n    {\n        private readonly ITestOutputHelper output;\n\n        public JitOptimizationsTests(ITestOutputHelper output)\n        {\n            this.output = output;\n        }\n\n        [Fact]\n        public void UserGetsWarningWhenNonOptimizedDllIsReferenced()\n        {\n            var benchmarksWithNonOptimizedDll = CreateBenchmarks(typeof(DisabledOptimizations.OptimizationsDisabledInCsproj));\n\n            var warnings = JitOptimizationsValidator.DontFailOnError.Validate(benchmarksWithNonOptimizedDll).ToArray();\n            var criticalErrors = JitOptimizationsValidator.FailOnError.Validate(benchmarksWithNonOptimizedDll).ToArray();\n\n            Assert.NotEmpty(warnings);\n            Assert.True(warnings.All(error => error.IsCritical == false));\n            Assert.NotEmpty(criticalErrors);\n            Assert.True(criticalErrors.All(error => error.IsCritical));\n        }\n\n        [Fact]\n        public void UserGetsNoWarningWhenOnlyOptimizedDllAreReferenced()\n        {\n            var benchmarksWithOptimizedDll = CreateBenchmarks(typeof(EnabledOptimizations.OptimizationsEnabledInCsproj));\n\n            var warnings = JitOptimizationsValidator.DontFailOnError.Validate(benchmarksWithOptimizedDll).ToArray();\n\n            if (warnings.Any())\n            {\n                output.WriteLine(\"*** Warnings ***\");\n                foreach (var warning in warnings)\n                    output.WriteLine(warning.Message);\n            }\n\n#if DEBUG\n            Assert.NotEmpty(warnings);\n#else\n            Assert.Empty(warnings);\n#endif\n        }\n\n        private BenchmarkCase[] CreateBenchmarks(Type targetBenchmarkType)\n        {\n            return BenchmarkConverter.TypeToBenchmarks(targetBenchmarkType).BenchmarksCases;\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/JitRuntimeValidationTest.cs",
    "content": "﻿using BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Columns;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Portability;\nusing BenchmarkDotNet.Tests.Loggers;\nusing BenchmarkDotNet.Tests.XUnit;\nusing System.Collections.Generic;\nusing Xunit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.IntegrationTests\n{\n    public class JitRuntimeValidationTest : BenchmarkTestExecutor\n    {\n        public JitRuntimeValidationTest(ITestOutputHelper output) : base(output) { }\n\n//      private const string LegacyJitNotAvailableForMono = \"// ERROR:  LegacyJIT is requested but it is not available for Mono\";\n        private const string RyuJitNotAvailable = \"// ERROR:  RyuJIT is requested but it is not available in current environment\";\n        private const string ToolchainSupportsOnlyRyuJit = \"Currently dotnet cli toolchain supports only RyuJit\";\n\n        [TheoryEnvSpecific(\"CLR is a valid job only on Windows\", EnvRequirement.WindowsOnly)]\n        [InlineData(Jit.LegacyJit, Platform.X86, null)]\n        [InlineData(Jit.LegacyJit, Platform.X64, null)]\n        [InlineData(Jit.RyuJit, Platform.X86, RyuJitNotAvailable)]\n        [InlineData(Jit.RyuJit, Platform.X64, null)]\n        public void CheckClrOnWindows(Jit jit, Platform platform, string? errorMessage)\n        {\n            Verify(ClrRuntime.Net462, jit, platform, errorMessage);\n        }\n\n//      [TheoryWindowsOnly(\"CLR is a valid job only on Windows\")]\n//      [InlineData(Jit.LegacyJit, Platform.X86, LegacyJitNotAvailableForMono)]\n//      [InlineData(Jit.LegacyJit, Platform.X64, LegacyJitNotAvailableForMono)]\n//      [InlineData(Jit.RyuJit, Platform.X86, RyuJitNotAvailable)]\n//      [InlineData(Jit.RyuJit, Platform.X64, RyuJitNotAvailable)]\n//      public void CheckMono(Jit jit, Platform platform, string errorMessage)\n//      {\n//          Verify(Runtime.Mono, jit, platform, errorMessage);\n//      }\n\n        public static IEnumerable<object[]> CheckCore_Arguments()\n        {\n            yield return new object[] { Jit.LegacyJit, Platform.X86, ToolchainSupportsOnlyRyuJit };\n            yield return new object[] { Jit.LegacyJit, Platform.X64, ToolchainSupportsOnlyRyuJit };\n            yield return new object[] { Jit.RyuJit, RuntimeInformation.GetCurrentPlatform(), null! };\n        }\n\n        [Theory]\n        [MemberData(nameof(CheckCore_Arguments))]\n        public void CheckCore(Jit jit, Platform platform, string errorMessage)\n        {\n            Verify(CoreRuntime.Core80, jit, platform, errorMessage);\n        }\n\n        private void Verify(Runtime runtime, Jit jit, Platform platform, string? errorMessage)\n        {\n            var logger = new OutputLogger(Output);\n            var config = ManualConfig.CreateEmpty()\n                .AddJob(Job.Dry.WithPlatform(platform).WithJit(jit).WithRuntime(runtime))\n                .AddLogger(logger)\n                .AddColumnProvider(DefaultColumnProviders.Instance);\n\n            CanExecute<TestBenchmark>(config, fullValidation: errorMessage is null);\n\n            if (errorMessage is not null)\n            {\n                Assert.Contains(errorMessage, logger.GetLog());\n            }\n        }\n\n        public class TestBenchmark\n        {\n            [Benchmark]\n            public void Benchmark() { }\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/LanguageVersionTests.cs",
    "content": "﻿using BenchmarkDotNet.Attributes;\nusing Xunit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.IntegrationTests\n{\n    public class LanguageVersionTests : BenchmarkTestExecutor\n    {\n        public LanguageVersionTests(ITestOutputHelper output) : base(output) { }\n\n        [Fact]\n        public void WeSupportCsharp72() => CanExecute<UsingCsharp7_2>();\n    }\n\n    public class UsingCsharp7_2\n    {\n        private protected int fieldWithCsharp7_2_access = 7;\n\n        [Benchmark]\n        public ref int Benchmark() => ref fieldWithCsharp7_2_access;\n    }\n}\n"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/LargeAddressAwareTest.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Columns;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Portability;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Tests.Loggers;\nusing BenchmarkDotNet.Tests.XUnit;\nusing Xunit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.IntegrationTests\n{\n    public class LargeAddressAwareTest\n    {\n        private readonly ITestOutputHelper output;\n\n        public LargeAddressAwareTest(ITestOutputHelper outputHelper) => output = outputHelper;\n\n        [Fact]\n        public void BenchmarkCanAllocateMoreThan2Gb_Core()\n        {\n            var platform = RuntimeInformation.GetCurrentPlatform();\n            var config = ManualConfig.CreateEmpty().WithBuildTimeout(TimeSpan.FromSeconds(240));\n            // Running 32-bit benchmarks with .Net Core requires passing the path to 32-bit SDK,\n            // which makes this test more complex than it's worth in CI, so we only test 64-bit.\n            config.AddJob(Job.Dry.WithRuntime(CoreRuntime.Core80).WithPlatform(platform).WithId(platform.ToString()));\n            config.AddColumnProvider(DefaultColumnProviders.Instance)\n                  .AddLogger(new OutputLogger(output));\n\n            var summary = BenchmarkRunner.Run<NeedsMoreThan2GB>(config);\n\n            Assert.True(summary.Reports\n                .All(report => report.ExecuteResults\n                .All(executeResult => executeResult.FoundExecutable)));\n\n            Assert.True(summary.Reports.All(report => report.AllMeasurements.Any()));\n            Assert.True(summary.Reports.All(report => report.ExecuteResults.Any()));\n            Assert.Equal(1, summary.Reports.Count(report => report.BenchmarkCase.Job.Environment.Runtime is CoreRuntime));\n\n            Assert.Contains(\".NET 8.0\", summary.AllRuntimes);\n        }\n\n        [FactEnvSpecific(\"Framework is only on Windows\", EnvRequirement.WindowsOnly)]\n        public void BenchmarkCanAllocateMoreThan2Gb_Framework()\n        {\n            var platform = RuntimeInformation.GetCurrentPlatform();\n            var config = ManualConfig.CreateEmpty();\n            // Net481 officially only supports x86, x64, and Arm64.\n            config.AddJob(Job.Dry.WithRuntime(ClrRuntime.Net481).WithPlatform(platform).WithGcServer(false).WithLargeAddressAware().WithId(platform.ToString()));\n            int jobCount = 1;\n            if (platform == Platform.X64)\n            {\n                ++jobCount;\n                config.AddJob(Job.Dry.WithRuntime(ClrRuntime.Net462).WithPlatform(Platform.X86).WithGcServer(false).WithLargeAddressAware().WithId(\"X86\"));\n            }\n            config.AddColumnProvider(DefaultColumnProviders.Instance)\n                  .AddLogger(new OutputLogger(output));\n\n            var summary = BenchmarkRunner.Run<NeedsMoreThan2GB>(config);\n\n            Assert.True(summary.Reports\n                .All(report => report.ExecuteResults\n                .All(executeResult => executeResult.FoundExecutable)));\n\n            Assert.True(summary.Reports.All(report => report.AllMeasurements.Any()));\n            Assert.True(summary.Reports.All(report => report.ExecuteResults.Any()));\n            Assert.Equal(jobCount, summary.Reports.Count(report => report.BenchmarkCase.Job.Environment.Runtime is ClrRuntime));\n\n            Assert.Contains(\".NET Framework\", summary.AllRuntimes);\n        }\n    }\n\n    public class NeedsMoreThan2GB\n    {\n        [Benchmark]\n        public void AllocateMoreThan2GB()\n        {\n            Console.WriteLine($\"Is64BitProcess = {Environment.Is64BitProcess}\");\n\n            const int oneGB = 1024 * 1024 * 1024;\n            const int halfGB = oneGB / 2;\n            byte[] bytes1 = new byte[oneGB];\n            byte[] bytes2 = new byte[oneGB];\n            byte[] bytes3 = new byte[halfGB];\n            GC.KeepAlive(bytes1);\n            GC.KeepAlive(bytes2);\n            GC.KeepAlive(bytes3);\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/MemoryDiagnoserTests.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Columns;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Detectors;\nusing BenchmarkDotNet.Diagnosers;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.IntegrationTests.Xunit;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Portability;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Tests.Loggers;\nusing BenchmarkDotNet.Tests.XUnit;\nusing BenchmarkDotNet.Toolchains;\nusing BenchmarkDotNet.Toolchains.DotNetCli;\nusing BenchmarkDotNet.Toolchains.InProcess.Emit;\nusing BenchmarkDotNet.Toolchains.Mono;\nusing BenchmarkDotNet.Toolchains.MonoAotLLVM;\nusing BenchmarkDotNet.Toolchains.MonoWasm;\nusing BenchmarkDotNet.Toolchains.NativeAot;\nusing Xunit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.IntegrationTests\n{\n    public class MemoryDiagnoserTests\n    {\n        private readonly ITestOutputHelper output;\n\n        public MemoryDiagnoserTests(ITestOutputHelper outputHelper) => output = outputHelper;\n\n        public static IEnumerable<object[]> GetToolchains()\n        {\n            yield return new object[] { Job.Default.GetToolchain() };\n            // InProcessEmit reports flaky allocations in current .Net 8.\n            if (!RuntimeInformation.IsNetCore)\n            {\n                yield return new object[] { InProcessEmitToolchain.Default };\n            }\n        }\n\n        public class AccurateAllocations\n        {\n            [Benchmark] public byte[] EightBytesArray() => new byte[8];\n            [Benchmark] public byte[] SixtyFourBytesArray() => new byte[64];\n\n            [Benchmark] public Task<int> AllocateTask() => Task.FromResult<int>(-12345);\n        }\n\n        [Theory, MemberData(nameof(GetToolchains), DisableDiscoveryEnumeration = true)]\n        [Trait(Constants.Category, Constants.BackwardCompatibilityCategory)]\n        public void MemoryDiagnoserIsAccurate(IToolchain toolchain)\n        {\n            long objectAllocationOverhead = IntPtr.Size * 2; // pointer to method table + object header word\n            long arraySizeOverhead = IntPtr.Size; // array length\n\n            if (toolchain is MonoToolchain)\n            {\n                objectAllocationOverhead += IntPtr.Size;\n            }\n\n            AssertAllocations(toolchain, typeof(AccurateAllocations), new Dictionary<string, long>\n            {\n                { nameof(AccurateAllocations.EightBytesArray), 8 + objectAllocationOverhead + arraySizeOverhead },\n                { nameof(AccurateAllocations.SixtyFourBytesArray), 64 + objectAllocationOverhead + arraySizeOverhead },\n                { nameof(AccurateAllocations.AllocateTask), CalculateRequiredSpace<Task<int>>() },\n            });\n        }\n\n        [FactEnvSpecific(\"We don't want to test NativeAOT twice (for .NET Framework 4.6.2 and .NET 8.0)\", EnvRequirement.DotNetCoreOnly)]\n        public void MemoryDiagnoserSupportsNativeAOT()\n        {\n            if (OsDetector.IsMacOS())\n                return; // currently not supported\n\n            MemoryDiagnoserIsAccurate(NativeAotToolchain.Net80);\n        }\n\n        [FactEnvSpecific(\"We don't want to test MonoVM twice (for .NET Framework 4.6.2 and .NET 8.0), and it's not supported on Windows+Arm\", [EnvRequirement.DotNetCoreOnly, EnvRequirement.NonWindowsArm])]\n        public void MemoryDiagnoserSupportsModernMono()\n        {\n            MemoryDiagnoserIsAccurate(MonoToolchain.Mono80);\n        }\n\n        [TheoryEnvSpecific(\"JSVU does not support ARM on Windows or Linux\", EnvRequirement.NonWindowsArm, EnvRequirement.NonLinuxArm)]\n        [InlineData(MonoAotCompilerMode.mini)]\n        // BUG: https://github.com/dotnet/BenchmarkDotNet/issues/3036\n        [InlineData(MonoAotCompilerMode.wasm, Skip = \"AOT is broken\")]\n        public void MemoryDiagnoserSupportsMonoWasm(MonoAotCompilerMode aotCompilerMode)\n        {\n            var ptrSize = sizeof(Int32); // We can't rely on IntPtr.Size, since we run on a different platform. Wasm is currently 32bit.\n            var objectAllocationOverhead = ptrSize * 2; // pointer to method table + object header word\n            var arraySizeOverhead = ptrSize * 2; // bounds + max_length\n            var intTaskSize = 40; // We can't use CalculateRequiredSpace for AllocateTask since it calculates the size with IntPtr.Size.\n\n            var netCoreAppSettings = new NetCoreAppSettings(\"net8.0\", runtimeFrameworkVersion: null!, \"Wasm\", aotCompilerMode: aotCompilerMode);\n\n            var runtime = new WasmRuntime(\n                netCoreAppSettings.TargetFrameworkMoniker, RuntimeMoniker.WasmNet80,\n                \"Wasm\", aotCompilerMode == MonoAotCompilerMode.wasm, \"v8\");\n\n            AssertAllocations(WasmToolchain.From(netCoreAppSettings), typeof(AccurateAllocations), new Dictionary<string, long>\n            {\n                { nameof(AccurateAllocations.EightBytesArray), 8 + objectAllocationOverhead + arraySizeOverhead },\n                { nameof(AccurateAllocations.SixtyFourBytesArray), 64 + objectAllocationOverhead + arraySizeOverhead },\n                { nameof(AccurateAllocations.AllocateTask), intTaskSize },\n            }, runtime: runtime);\n        }\n\n        public class AllocatingGlobalSetupAndCleanup\n        {\n            private List<int> list = default!;\n\n            [Benchmark] public void AllocateNothing() { }\n\n            [IterationSetup]\n            [GlobalSetup]\n            public void AllocatingSetUp() => AllocateUntilGcWakesUp();\n\n            [IterationCleanup]\n            [GlobalCleanup]\n            public void AllocatingCleanUp() => AllocateUntilGcWakesUp();\n\n            private void AllocateUntilGcWakesUp()\n            {\n                int initialCollectionCount = GC.CollectionCount(0);\n\n                while (initialCollectionCount == GC.CollectionCount(0))\n                    list = Enumerable.Range(0, 100).ToList();\n            }\n        }\n\n        [Theory, MemberData(nameof(GetToolchains), DisableDiscoveryEnumeration = true)]\n        [Trait(Constants.Category, Constants.BackwardCompatibilityCategory)]\n        public void MemoryDiagnoserDoesNotIncludeAllocationsFromSetupAndCleanup(IToolchain toolchain)\n        {\n            AssertAllocations(toolchain, typeof(AllocatingGlobalSetupAndCleanup), new Dictionary<string, long>\n            {\n                { nameof(AllocatingGlobalSetupAndCleanup.AllocateNothing), 0 }\n            });\n        }\n\n        public class EmptyBenchmark\n        {\n            [Benchmark] public void EmptyMethod() { }\n        }\n\n        [Theory, MemberData(nameof(GetToolchains), DisableDiscoveryEnumeration = true)]\n        [Trait(Constants.Category, Constants.BackwardCompatibilityCategory)]\n        public void EngineShouldNotInterfereAllocationResults(IToolchain toolchain)\n        {\n            AssertAllocations(toolchain, typeof(EmptyBenchmark), new Dictionary<string, long>\n            {\n                { nameof(EmptyBenchmark.EmptyMethod), 0 }\n            });\n        }\n\n        public class TimeConsumingBenchmark\n        {\n            [Benchmark]\n            public ulong TimeConsuming()\n            {\n                var r = 1ul;\n                for (var i = 0; i < 50_000_000; i++)\n                {\n                    r /= 1;\n                }\n                return r;\n            }\n        }\n\n        // #1542\n        [Theory, MemberData(nameof(GetToolchains), DisableDiscoveryEnumeration = true)]\n        [Trait(Constants.Category, Constants.BackwardCompatibilityCategory)]\n        public void TieredJitShouldNotInterfereAllocationResults(IToolchain toolchain)\n        {\n            AssertAllocations(toolchain, typeof(TimeConsumingBenchmark), new Dictionary<string, long>\n            {\n                { nameof(TimeConsumingBenchmark.TimeConsuming), 0 }\n            },\n            disableTieredJit: false, iterationCount: 10); // 1 iteration is not enough to repro the problem\n        }\n\n        public class NoBoxing\n        {\n            [Benchmark] public ValueTuple<int> ReturnsValueType() => new ValueTuple<int>(0);\n        }\n\n        [Theory, MemberData(nameof(GetToolchains), DisableDiscoveryEnumeration = true)]\n        [Trait(Constants.Category, Constants.BackwardCompatibilityCategory)]\n        public void EngineShouldNotIntroduceBoxing(IToolchain toolchain)\n        {\n            AssertAllocations(toolchain, typeof(NoBoxing), new Dictionary<string, long>\n            {\n                { nameof(NoBoxing.ReturnsValueType), 0 }\n            });\n        }\n\n        public class NonAllocatingAsynchronousBenchmarks\n        {\n            private readonly Task<int> completedTaskOfT = Task.FromResult(default(int)); // we store it in the field, because Task<T> is reference type so creating it allocates heap memory\n\n            [Benchmark] public Task CompletedTask() => Task.CompletedTask;\n\n            [Benchmark] public Task<int> CompletedTaskOfT() => completedTaskOfT;\n\n            [Benchmark] public ValueTask<int> CompletedValueTaskOfT() => new ValueTask<int>(default(int));\n        }\n\n        [Theory, MemberData(nameof(GetToolchains), DisableDiscoveryEnumeration = true)]\n        [Trait(Constants.Category, Constants.BackwardCompatibilityCategory)]\n        public void AwaitingTasksShouldNotInterfereAllocationResults(IToolchain toolchain)\n        {\n            AssertAllocations(toolchain, typeof(NonAllocatingAsynchronousBenchmarks), new Dictionary<string, long>\n            {\n                { nameof(NonAllocatingAsynchronousBenchmarks.CompletedTask), 0 },\n                { nameof(NonAllocatingAsynchronousBenchmarks.CompletedTaskOfT), 0 },\n                { nameof(NonAllocatingAsynchronousBenchmarks.CompletedValueTaskOfT), 0 }\n            });\n        }\n\n        public class WithOperationsPerInvokeBenchmarks\n        {\n            [Benchmark(OperationsPerInvoke = 4)]\n            public void WithOperationsPerInvoke()\n            {\n                DoNotInline(new object(), new object());\n                DoNotInline(new object(), new object());\n            }\n\n            [MethodImpl(MethodImplOptions.NoInlining)]\n            private void DoNotInline(object left, object right) { }\n        }\n\n        [Theory, MemberData(nameof(GetToolchains), DisableDiscoveryEnumeration = true)]\n        [Trait(Constants.Category, Constants.BackwardCompatibilityCategory)]\n        public void AllocatedMemoryShouldBeScaledForOperationsPerInvoke(IToolchain toolchain)\n        {\n            long objectAllocationOverhead = IntPtr.Size * 2; // pointer to method table + object header word\n\n            AssertAllocations(toolchain, typeof(WithOperationsPerInvokeBenchmarks), new Dictionary<string, long>\n            {\n                { nameof(WithOperationsPerInvokeBenchmarks.WithOperationsPerInvoke), objectAllocationOverhead + IntPtr.Size }\n            });\n        }\n\n        public class TimeConsuming\n        {\n            [Benchmark]\n            public byte[] SixtyFourBytesArray()\n            {\n                // this benchmark should hit allocation quantum problem\n                // it allocates a little of memory, but it takes a lot of time to execute so we can't run in thousands of times!\n\n                Thread.Sleep(TimeSpan.FromSeconds(0.5));\n\n                return new byte[64];\n            }\n        }\n\n        [TheoryEnvSpecific(\"Full Framework cannot measure precisely enough for low invocation counts.\", EnvRequirement.DotNetCoreOnly)]\n        [MemberData(nameof(GetToolchains), DisableDiscoveryEnumeration = true)]\n        [Trait(Constants.Category, Constants.BackwardCompatibilityCategory)]\n        public void AllocationQuantumIsNotAnIssueForNetCore21Plus(IToolchain toolchain)\n        {\n            // TODO: Skip test on macos. Temporary workaround for https://github.com/dotnet/BenchmarkDotNet/issues/2779\n            if (System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.OSX))\n                return;\n\n            long objectAllocationOverhead = IntPtr.Size * 2; // pointer to method table + object header word\n            long arraySizeOverhead = IntPtr.Size; // array length\n            AssertAllocations(toolchain, typeof(TimeConsuming), new Dictionary<string, long>\n            {\n                { nameof(TimeConsuming.SixtyFourBytesArray), 64 + objectAllocationOverhead + arraySizeOverhead }\n            });\n        }\n\n        public class MultiThreadedAllocation\n        {\n            public const int Size = 1024;\n            public const int ThreadsCount = 10;\n\n            // We cache the threads in GlobalSetup and reuse them for each benchmark invocation\n            // to avoid measuring the cost of thread start and join, which varies across different runtimes.\n            private Thread[] threads = default!;\n            private volatile bool keepRunning = true;\n            private readonly Barrier barrier = new(ThreadsCount + 1);\n            private readonly CountdownEvent countdownEvent = new(ThreadsCount);\n\n            [GlobalSetup]\n            public void Setup()\n            {\n                threads = Enumerable.Range(0, ThreadsCount)\n                    .Select(_ => new Thread(() =>\n                    {\n                        while (keepRunning)\n                        {\n                            barrier.SignalAndWait();\n                            GC.KeepAlive(new byte[Size]);\n                            countdownEvent.Signal();\n                        }\n                    }))\n                    .ToArray();\n                foreach (var thread in threads)\n                {\n                    thread.Start();\n                }\n            }\n\n            [GlobalCleanup]\n            public void Cleanup()\n            {\n                countdownEvent.Reset(ThreadsCount);\n                keepRunning = false;\n                barrier.SignalAndWait();\n                foreach (var thread in threads)\n                {\n                    thread.Join();\n                }\n            }\n\n            [Benchmark]\n            public void Allocate()\n            {\n                countdownEvent.Reset(ThreadsCount);\n                barrier.SignalAndWait();\n                countdownEvent.Wait();\n            }\n        }\n\n        [TheoryEnvSpecific(\"Full Framework cannot measure precisely enough\", EnvRequirement.DotNetCoreOnly)]\n        [MemberData(nameof(GetToolchains), DisableDiscoveryEnumeration = true)]\n        [Trait(Constants.Category, Constants.BackwardCompatibilityCategory)]\n        public void MemoryDiagnoserIsAccurateForMultiThreadedBenchmarks(IToolchain toolchain)\n        {\n            long objectAllocationOverhead = IntPtr.Size * 2; // pointer to method table + object header word\n            long arraySizeOverhead = IntPtr.Size; // array length\n            long memoryAllocatedPerArray = (MultiThreadedAllocation.Size + objectAllocationOverhead + arraySizeOverhead);\n\n            AssertAllocations(toolchain, typeof(MultiThreadedAllocation), new Dictionary<string, long>\n            {\n                { nameof(MultiThreadedAllocation.Allocate), memoryAllocatedPerArray * MultiThreadedAllocation.ThreadsCount }\n            });\n        }\n\n        private void AssertAllocations(IToolchain toolchain, Type benchmarkType, Dictionary<string, long> benchmarksAllocationsValidators,\n            bool disableTieredJit = true, int iterationCount = 1, Runtime? runtime = null)\n        {\n            var config = CreateConfig(toolchain, runtime, disableTieredJit, iterationCount);\n            var benchmarks = BenchmarkConverter.TypeToBenchmarks(benchmarkType, config);\n\n            var summary = BenchmarkRunner.Run(benchmarks);\n            try\n            {\n                summary.CheckPlatformLinkerIssues();\n            }\n            catch (MisconfiguredEnvironmentException e)\n            {\n                if (ContinuousIntegration.IsLocalRun())\n                {\n                    output.WriteLine(e.SkipMessage);\n                    return;\n                }\n                throw;\n            }\n\n            foreach (var benchmarkAllocationsValidator in benchmarksAllocationsValidators)\n            {\n                var allocatingBenchmarks = benchmarks.BenchmarksCases.Where(benchmark => benchmark.DisplayInfo.Contains(benchmarkAllocationsValidator.Key));\n\n                foreach (var benchmark in allocatingBenchmarks)\n                {\n                    var benchmarkReport = summary.Reports.Single(report => report.BenchmarkCase == benchmark);\n\n                    Assert.Equal(benchmarkAllocationsValidator.Value, benchmarkReport.GcStats.GetBytesAllocatedPerOperation(benchmark));\n\n                    if (benchmarkAllocationsValidator.Value == 0)\n                    {\n                        Assert.Equal(0, benchmarkReport.GcStats.GetTotalAllocatedBytes(excludeAllocationQuantumSideEffects: true));\n                    }\n                }\n            }\n        }\n\n        private IConfig CreateConfig(IToolchain toolchain,\n            Runtime? runtime,\n            // Tiered JIT can allocate some memory on a background thread, let's disable it by default to make our tests less flaky (#1542).\n            // This was mostly fixed in net7.0, but tiered jit thread is not guaranteed to not allocate, so we disable it just in case.\n            bool disableTieredJit = true,\n            // Single iteration is enough for most of the tests.\n            int iterationCount = 1,\n            // Don't run warmup by default to save some time for our CI runs\n            int warmupCount = 0)\n        {\n#pragma warning disable CS0618 // WithEvaluateOverhead is obsolete\n            var job = Job.ShortRun\n                .WithEvaluateOverhead(false) // no need to run idle for this test\n                .WithWarmupCount(warmupCount)\n                .WithIterationCount(iterationCount)\n                .WithGcForce(false)\n                .WithGcServer(false)\n                .WithGcConcurrent(false)\n                // To prevent finalizers allocating out of our control, we hang the finalizer thread.\n                // https://github.com/dotnet/runtime/issues/101536#issuecomment-2077647417\n                .WithEnvironmentVariable(Engines.Engine.UnitTestBlockFinalizerEnvKey, Engines.Engine.UnitTestBlockFinalizerEnvValue)\n                .WithToolchain(toolchain);\n#pragma warning restore CS0618 // WithEvaluateOverhead is obsolete\n\n            if (runtime is not null)\n            {\n                job = job.WithRuntime(runtime);\n            }\n\n            return ManualConfig.CreateEmpty()\n                .AddJob(disableTieredJit\n                    ? job.WithEnvironmentVariables(\n                        new EnvironmentVariable(\"DOTNET_TieredCompilation\", \"0\"),\n                        new EnvironmentVariable(\"COMPlus_TieredCompilation\", \"0\")\n                    )\n                    : job)\n                .WithBuildTimeout(TimeSpan.FromSeconds(240)) // Increase timeout for `MemoryDiagnoserSupportsModernMono` test on macos(x64)\n                .AddColumnProvider(DefaultColumnProviders.Instance)\n                .AddDiagnoser(MemoryDiagnoser.Default)\n                .AddLogger(toolchain.IsInProcess ? ConsoleLogger.Default : new OutputLogger(output)); // we can't use OutputLogger for the InProcess toolchains because it allocates memory on the same thread\n        }\n\n        // note: don't copy, never use in production systems (it should work but I am not 100% sure)\n        private int CalculateRequiredSpace<T>()\n        {\n            int total = SizeOfAllFields<T>();\n\n            if (!typeof(T).GetTypeInfo().IsValueType)\n                total += IntPtr.Size * 2; // pointer to method table + object header word\n\n            if (total % IntPtr.Size != 0) // aligning..\n                total += IntPtr.Size - (total % IntPtr.Size);\n\n            return total;\n        }\n\n        // note: don't copy, never use in production systems (it should work but I am not 100% sure)\n        private int SizeOfAllFields<T>()\n        {\n            int GetSize(Type type)\n            {\n                var sizeOf = typeof(Unsafe).GetTypeInfo().GetMethod(nameof(Unsafe.SizeOf))!;\n\n                return (int)sizeOf.MakeGenericMethod(type).Invoke(null, null)!;\n            }\n\n            return typeof(T)\n                .GetAllFields()\n                .Where(field => !field.IsStatic && !field.IsLiteral)\n                .Distinct()\n                .Sum(field => GetSize(field.FieldType));\n        }\n    }\n}\n"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/MonoTests.cs",
    "content": "﻿using System;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Portability;\nusing BenchmarkDotNet.Tests.Loggers;\nusing BenchmarkDotNet.Tests.XUnit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.IntegrationTests\n{\n    public class MonoTests : BenchmarkTestExecutor\n    {\n        public MonoTests(ITestOutputHelper output) : base(output) { }\n\n        [FactEnvSpecific(\"UseMonoRuntime option is available in .NET Core only starting from .NET 6, and it's not supported on Windows+Arm\", [EnvRequirement.DotNetCoreOnly, EnvRequirement.NonWindowsArm])]\n        public void Mono80IsSupported()\n        {\n            var logger = new OutputLogger(Output);\n            var config = ManualConfig.CreateEmpty()\n                .AddLogger(logger)\n                .AddJob(Job.Dry.WithRuntime(MonoRuntime.Mono80))\n                .WithBuildTimeout(TimeSpan.FromSeconds(240));\n            CanExecute<MonoBenchmark>(config);\n        }\n\n        public class MonoBenchmark\n        {\n            [Benchmark]\n            public void Check()\n            {\n                if (Type.GetType(\"Mono.RuntimeStructs\") == null)\n                {\n                    throw new Exception(\"This is not Mono runtime\");\n                }\n\n                if (RuntimeInformation.GetCurrentRuntime() != MonoRuntime.Mono80)\n                {\n                    throw new Exception(\"Incorrect runtime detection\");\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/MultipleRuntimesTest.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Columns;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.IntegrationTests.Xunit;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Portability;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Tests.Loggers;\nusing BenchmarkDotNet.Tests.XUnit;\nusing BenchmarkDotNet.Toolchains;\nusing Xunit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.IntegrationTests\n{\n    public class MultipleRuntimesTest\n    {\n        private readonly ITestOutputHelper output;\n\n        public MultipleRuntimesTest(ITestOutputHelper outputHelper) => output = outputHelper;\n\n        [FactEnvSpecific(\"CLR is a valid job only on Windows\", EnvRequirement.WindowsOnly)]\n        [Trait(Constants.Category, Constants.BackwardCompatibilityCategory)]\n        public void SingleBenchmarkCanBeExecutedForMultipleRuntimes()\n        {\n            var summary = BenchmarkRunner\n                .Run<C>(\n                    ManualConfig.CreateEmpty()\n                        .AddJob(Job.Dry.WithRuntime(CoreRuntime.Core80).WithId(\"Core\"))\n                        .AddJob(Job.Dry.WithRuntime(ClrRuntime.Net462).WithId(\"Framework\"))\n                        .AddColumnProvider(DefaultColumnProviders.Instance)\n                        .AddLogger(new OutputLogger(output)));\n\n            Assert.True(summary.Reports\n                .All(report => report.ExecuteResults\n                .All(executeResult => executeResult.FoundExecutable)));\n\n            Assert.True(summary.Reports.All(report => report.AllMeasurements.Any()));\n\n            Assert.True(summary.Reports\n                .Single(report => report.BenchmarkCase.Job.Environment.Runtime is ClrRuntime)\n                .ExecuteResults\n                .Any());\n\n            Assert.True(summary.Reports\n                .Single(report => report.BenchmarkCase.Job.Environment.Runtime is CoreRuntime)\n                .ExecuteResults\n                .Any());\n\n            Assert.Contains(\".NET Framework\", summary.AllRuntimes);\n            Assert.Contains(\".NET 8.0\", summary.AllRuntimes);\n        }\n    }\n\n    // this test was suffering from too long path ex so I had to rename the class and benchmark method to fit within the limit\n    public class C\n    {\n        [Benchmark]\n        public void B()\n        {\n            Console.WriteLine($\"// {RuntimeInformation.GetCurrentRuntime().GetToolchain()}\");\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/NativeAotTests.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Detectors;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.IntegrationTests.Diagnosers;\nusing BenchmarkDotNet.IntegrationTests.Xunit;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Portability;\nusing BenchmarkDotNet.Tests.XUnit;\nusing BenchmarkDotNet.Toolchains.NativeAot;\nusing Xunit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.IntegrationTests\n{\n    public class NativeAotTests(ITestOutputHelper outputHelper) : BenchmarkTestExecutor(outputHelper)\n    {\n        private bool IsAvx2Supported()\n        {\n#if NET6_0_OR_GREATER\n            return System.Runtime.Intrinsics.X86.Avx2.IsSupported;\n#else\n            return false;\n#endif\n        }\n\n        private ManualConfig GetConfig()\n        {\n            var toolchain = NativeAotToolchain.CreateBuilder().UseNuGet().IlcInstructionSet(IsAvx2Supported() ? \"avx2\" : \"\").ToToolchain();\n\n            return ManualConfig.CreateEmpty()\n                .AddJob(Job.Dry\n                    .WithRuntime(NativeAotRuntime.GetCurrentVersion()) // we test against latest version for current TFM to make sure we avoid issues like #1055\n                    .WithToolchain(toolchain)\n                    .WithEnvironmentVariable(NativeAotBenchmark.EnvVarKey, IsAvx2Supported().ToString().ToLower()));\n        }\n\n        [FactEnvSpecific(\"It's impossible to reliably detect the version of NativeAOT if the process is not a .NET Core or NativeAOT process\", EnvRequirement.DotNetCoreOnly)]\n        public void LatestNativeAotVersionIsSupported()\n        {\n            if (!GetShouldRunTest())\n                return;\n\n            try\n            {\n                CanExecute<NativeAotBenchmark>(GetConfig());\n            }\n            catch (MisconfiguredEnvironmentException e)\n            {\n                if (ContinuousIntegration.IsLocalRun())\n                    Output.WriteLine(e.SkipMessage);\n                else\n                    throw;\n            }\n        }\n\n        [FactEnvSpecific(\"It's impossible to reliably detect the version of NativeAOT if the process is not a .NET Core or NativeAOT process\", EnvRequirement.DotNetCoreOnly)]\n        public void NativeAotSupportsInProcessDiagnosers()\n        {\n            if (!GetShouldRunTest())\n                return;\n\n            try\n            {\n                var diagnoser = new MockInProcessDiagnoser1(BenchmarkDotNet.Diagnosers.RunMode.NoOverhead);\n                var config = GetConfig().AddDiagnoser(diagnoser);\n\n                try\n                {\n                    CanExecute<NativeAotBenchmark>(config);\n                }\n                catch (MisconfiguredEnvironmentException e)\n                {\n                    if (ContinuousIntegration.IsLocalRun())\n                    {\n                        Output.WriteLine(e.SkipMessage);\n                        return;\n                    }\n                    throw;\n                }\n\n                Assert.Equal([diagnoser.ExpectedResult], diagnoser.Results.Values);\n                Assert.Equal([diagnoser.ExpectedResult], BaseMockInProcessDiagnoser.s_completedResults.Select(t => t.result));\n            }\n            finally\n            {\n                BaseMockInProcessDiagnoser.s_completedResults.Clear();\n            }\n        }\n\n        private static bool GetShouldRunTest()\n            => RuntimeInformation.Is64BitPlatform() // NativeAOT does not support 32bit yet\n                && !ContinuousIntegration.IsGitHubActionsOnWindows() // no native dependencies installed\n                && !OsDetector.IsMacOS(); // currently not supported\n    }\n\n    public class NativeAotBenchmark\n    {\n        internal const string EnvVarKey = \"AVX2_IsSupported\";\n\n        [Benchmark]\n        public void Check()\n        {\n            if (!RuntimeInformation.IsNativeAOT)\n                throw new Exception(\"This is NOT NativeAOT\");\n#if NET6_0_OR_GREATER\n            if (System.Runtime.Intrinsics.X86.Avx2.IsSupported != bool.Parse(Environment.GetEnvironmentVariable(EnvVarKey)!))\n                throw new Exception(\"Unexpected Instruction Set\");\n#endif\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/ParamSourceTests.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Code;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Toolchains;\nusing BenchmarkDotNet.Toolchains.InProcess.Emit;\nusing Xunit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.IntegrationTests\n{\n    public class ParamSourceTests : BenchmarkTestExecutor\n    {\n        public ParamSourceTests(ITestOutputHelper output) : base(output) { }\n\n        public static IEnumerable<object[]> GetToolchains()\n            =>\n                [\n                    [Job.Default.GetToolchain()],\n                    [InProcessEmitToolchain.Default],\n                ];\n\n        [Fact]\n        public void ParamSourceCanHandleStringWithSurrogates()\n        {\n            CanExecute<ParamSourceIsStringWithSurrogates>(CreateSimpleConfig());\n        }\n\n        public class ParamSourceIsStringWithSurrogates\n        {\n            public IEnumerable<string> StringValues\n            {\n                get\n                {\n                    yield return \"a\" + string.Join(\"\", Enumerable.Repeat(\"😀\", 40)) + \"a\";\n                    yield return \"a\" + string.Join(\"\", Enumerable.Repeat(\"😀\", 40));\n                    yield return string.Join(\"\", Enumerable.Repeat(\"😀\", 40)) + \"a\";\n                    yield return string.Join(\"\", Enumerable.Repeat(\"😀\", 40));\n                }\n            }\n\n            [ParamsSource(nameof(StringValues))]\n            public required string _ { get; set; }\n\n            [Benchmark]\n            public void Method() { }\n        }\n\n        private Summary CanExecuteWithExtraInfo(Type type, IToolchain toolchain)\n        {\n            IConfig config = CreateSimpleConfig(job: Job.Dry.WithToolchain(toolchain));\n            if (!toolchain.IsInProcess)\n            {\n                // Show the relevant codegen excerpt in test results (the *.notcs is not part of the logs)\n                Output.WriteLine(\"// Benchmarks and CodeGenerator.GetParamsContent()\");\n                BenchmarkRunInfo runInfo = BenchmarkConverter.TypeToBenchmarks(type, config);\n                foreach (BenchmarkCase benchmarkCase in runInfo.BenchmarksCases)\n                {\n                    Output.WriteLine(\"//   \" + benchmarkCase.DisplayInfo);\n                    Output.WriteLine(CodeGenerator.GetParamsContent(benchmarkCase));\n                }\n            }\n            return CanExecute(type, config);\n        }\n\n        public interface ITargetInterface\n        {\n            int Data { get; }\n        }\n\n        private class NonPublicSource : ITargetInterface\n        {\n            public int Data { get; }\n            public NonPublicSource(int data) => Data = data;\n            public override string ToString() => \"src \" + Data.ToString();\n        }\n\n        public class PrivateClassWithPublicInterface\n        {\n            public static IEnumerable<ITargetInterface?> GetSource()\n            {\n                yield return null;\n                yield return new NonPublicSource(1);\n                yield return new NonPublicSource(2);\n            }\n\n            [ParamsSource(nameof(GetSource))]\n            public required ITargetInterface? ParamsTarget { get; set; }\n\n            [Benchmark]\n            public int Benchmark() => ParamsTarget?.Data ?? 0;\n        }\n\n        [Theory, MemberData(nameof(GetToolchains), DisableDiscoveryEnumeration = true)]\n        public void PrivateClassWithPublicInterface_Succeeds(IToolchain toolchain) => CanExecuteWithExtraInfo(typeof(PrivateClassWithPublicInterface), toolchain);\n\n        public class PrivateClassWithPublicInterface_Array\n        {\n            public IEnumerable<ITargetInterface?[]?> GetSource()\n            {\n                yield return null;\n                yield return Array.Empty<NonPublicSource>();\n                yield return new NonPublicSource?[] { null };\n                yield return new[] { new NonPublicSource(1), new NonPublicSource(2) };\n            }\n\n            [ParamsSource(nameof(GetSource))]\n            public required ITargetInterface?[]? ParamsTarget { get; set; }\n\n            [Benchmark]\n            public int Benchmark() => ParamsTarget?.Sum(p => p?.Data ?? 0) ?? 0;\n        }\n\n        [Theory, MemberData(nameof(GetToolchains), DisableDiscoveryEnumeration = true)]\n        public void PrivateClassWithPublicInterface_Array_Succeeds(IToolchain toolchain) => CanExecuteWithExtraInfo(typeof(PrivateClassWithPublicInterface_Array), toolchain);\n\n        public class PrivateClassWithPublicInterface_Enumerable\n        {\n            public IEnumerable<IEnumerable<ITargetInterface?>?> GetSource()\n            {\n                static IEnumerable<ITargetInterface?> YieldNull() { yield return null; }\n                yield return null;\n                yield return Enumerable.Empty<NonPublicSource>();\n                yield return YieldNull();\n                yield return PrivateClassWithPublicInterface.GetSource();\n            }\n\n            [ParamsSource(nameof(GetSource))]\n            public required IEnumerable<ITargetInterface?>? ParamsTarget { get; set; }\n\n            [Benchmark]\n            public int Benchmark() => ParamsTarget?.Sum(p => p?.Data ?? 0) ?? 0;\n        }\n\n        [Theory, MemberData(nameof(GetToolchains), DisableDiscoveryEnumeration = true)]\n        public void PrivateClassWithPublicInterface_Enumerable_Succeeds(IToolchain toolchain) => CanExecuteWithExtraInfo(typeof(PrivateClassWithPublicInterface_Enumerable), toolchain);\n\n        public class PrivateClassWithPublicInterface_AsObject\n        {\n            public static IEnumerable<object?> GetSource()\n            {\n                yield return null;\n                yield return new NonPublicSource(1);\n                yield return new NonPublicSource(2);\n            }\n\n            [ParamsSource(nameof(GetSource))]\n            public required ITargetInterface? ParamsTarget { get; set; }\n\n            [Benchmark]\n            public int Benchmark() => ParamsTarget?.Data ?? 0;\n        }\n\n        [Theory, MemberData(nameof(GetToolchains), DisableDiscoveryEnumeration = true)]\n        public void PrivateClassWithPublicInterface_AsObject_Succeeds(IToolchain toolchain) => CanExecuteWithExtraInfo(typeof(PrivateClassWithPublicInterface_AsObject), toolchain);\n\n        public class PublicSource\n        {\n            public int Data { get; }\n            public PublicSource(int data) => Data = data;\n            // op_Implicit would be meaningless because codegen wouldn't have to do anything.\n            public static explicit operator TargetType?(PublicSource @this) => @this != null ? new TargetType(@this.Data) : null;\n            public override string ToString() => \"src \" + Data.ToString();\n        }\n\n        public class TargetType\n        {\n            public int Data { get; }\n            public TargetType(int data) => Data = data;\n            public override string ToString() => \"target \" + Data.ToString();\n        }\n\n        public class SourceWithExplicitCastToTarget\n        {\n            public static IEnumerable<PublicSource?> GetSource()\n            {\n                yield return null;\n                yield return new PublicSource(1);\n                yield return new PublicSource(2);\n            }\n\n            [ParamsSource(nameof(GetSource))]\n            public required TargetType? ParamsTarget { get; set; }\n\n            [Benchmark]\n            public int Benchmark() => ParamsTarget?.Data ?? 0;\n        }\n\n        [Fact]\n        public void SourceWithExplicitCastToTarget_DefaultToolchain_Succeeds() => CanExecuteWithExtraInfo(typeof(SourceWithExplicitCastToTarget), Job.Default.GetToolchain());\n\n        [Fact]\n        public void SourceWithExplicitCastToTarget_InProcessToolchain_Throws()\n        {\n            // op_Explicit is currently not supported by InProcessEmitToolchain\n            // See TryChangeType() in Toolchains/InProcess.Emit.Implementation/Runnable/RunnableReflectionHelpers.cs\n            // If that changes, this test and the one above should be merged into:\n            //   [Theory, MemberData(nameof(GetToolchains))]\n            //   public void SourceWithExplicitCastToTarget_Succeeds(IToolchain toolchain) => CanExecuteWithExtraInfo(typeof(SourceWithExplicitCastToTarget), toolchain);\n            Assert.ThrowsAny<Exception>(() => CanExecuteWithExtraInfo(typeof(SourceWithExplicitCastToTarget), InProcessEmitToolchain.Default));\n        }\n\n        public abstract class OverridePropertyBase\n        {\n            public abstract int[] GetSourceProperty { get; }\n\n            [ParamsSource(nameof(GetSourceProperty))]\n            public int ParamsTarget { get; set; }\n        }\n\n        public class OverrideProperty : OverridePropertyBase\n        {\n            public override int[] GetSourceProperty => [1, 2, 3];\n\n            [Benchmark]\n            public int Benchmark() => ParamsTarget;\n        }\n\n        [Theory, MemberData(nameof(GetToolchains), DisableDiscoveryEnumeration = true)]\n        public void OverrideProperty_Succeeds(IToolchain toolchain) => CanExecuteWithExtraInfo(typeof(OverrideProperty), toolchain);\n\n        public abstract class OverrideMethodBase\n        {\n            public abstract int[] GetSourceMethod();\n\n            [ParamsSource(nameof(GetSourceMethod))]\n            public int ParamsTarget { get; set; }\n        }\n\n        public class OverrideMethod : OverrideMethodBase\n        {\n            public override int[] GetSourceMethod() => [1, 2, 3];\n\n            [Benchmark]\n            public int Benchmark() => ParamsTarget;\n        }\n\n        [Theory, MemberData(nameof(GetToolchains), DisableDiscoveryEnumeration = true)]\n        public void OverrideMethod_Succeeds(IToolchain toolchain) => CanExecuteWithExtraInfo(typeof(OverrideMethod), toolchain);\n    }\n}\n"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/ParamsTests.cs",
    "content": "﻿using System;\nusing BenchmarkDotNet.Attributes;\nusing Xunit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.IntegrationTests\n{\n    public class ParamsTests : BenchmarkTestExecutor\n    {\n        public ParamsTests(ITestOutputHelper output) : base(output) { }\n\n        [Fact]\n        public void ParamsSupportPropertyWithPublicSetter()\n        {\n            var summary = CanExecute<ParamsTestProperty>();\n            var standardOutput = GetCombinedStandardOutput(summary);\n\n            foreach (var param in new[] { 1, 2 })\n                Assert.Contains($\"// ### New Parameter {param} ###\", standardOutput);\n\n            Assert.DoesNotContain($\"// ### New Parameter {default(int)} ###\", standardOutput);\n        }\n\n        public class ParamsTestProperty\n        {\n            [Params(1, 2)]\n            public int ParamProperty { get; set; }\n\n            [Benchmark]\n            public void Benchmark() => Console.WriteLine($\"// ### New Parameter {ParamProperty} ###\");\n        }\n\n        [Fact]\n        public void ParamsSupportPublicFields()\n        {\n            var summary = CanExecute<ParamsTestField>();\n            var standardOutput = GetCombinedStandardOutput(summary);\n\n            foreach (var param in new[] { 1, 2 })\n                Assert.Contains($\"// ### New Parameter {param} ###\", standardOutput);\n\n            Assert.DoesNotContain($\"// ### New Parameter 0 ###\", standardOutput);\n        }\n\n        public class ParamsTestField\n        {\n            [Params(1, 2)]\n            public int ParamField = 0;\n\n            [Benchmark]\n            public void Benchmark() => Console.WriteLine($\"// ### New Parameter {ParamField} ###\");\n        }\n\n        public enum NestedOne\n        {\n            SampleValue = 1234\n        }\n\n        [Fact]\n        public void NestedEnumsAsParamsAreSupported() => CanExecute<NestedEnumsAsParams>();\n\n        public class NestedEnumsAsParams\n        {\n            [Params(NestedOne.SampleValue)]\n            public NestedOne Field;\n\n            [Benchmark]\n            public NestedOne Benchmark() => Field;\n        }\n\n        [Fact]\n        public void CharactersAsParamsAreSupported() => CanExecute<CharactersAsParams>();\n\n        public class CharactersAsParams\n        {\n            [Params('*')]\n            public char Field;\n\n            [Benchmark]\n            public char Benchmark() => Field;\n        }\n\n        [Fact]\n        public void NullableTypesAsParamsAreSupported() => CanExecute<NullableTypesAsParams>();\n\n        public class NullableTypesAsParams\n        {\n            [Params(null)]\n            public int? Field = 1;\n\n            [Benchmark]\n            public void Benchmark()\n            {\n                if (Field != null) { throw new Exception(\"Field should be initialized in ctor with 1 and then set to null by Engine\"); }\n            }\n        }\n\n        [Fact]\n        public void InvalidFileNamesInParamsAreSupported() => CanExecute<InvalidFileNamesInParams>();\n\n        public class InvalidFileNamesInParams\n        {\n            [Params(\"/\\\\@#$%\")]\n            public required string Field;\n\n            [Benchmark]\n            public void Benchmark() => Console.WriteLine(\"// \" + Field);\n        }\n\n        [Fact]\n        public void SpecialCharactersInStringAreSupported() => CanExecute<CompileSpecialCharactersInString>();\n\n        public class CompileSpecialCharactersInString\n        {\n            [Params(\"\\0\")] public required string Null;\n            [Params(\"\\t\")] public required string Tab;\n            [Params(\"\\n\")] public required string NewLine;\n            [Params(\"\\\\\")] public required string Slash;\n            [Params(\"\\\"\")] public required string Quote;\n            [Params(\"\\u0061\")] public required string Unicode;\n            [Params(\"{\")] public required string Bracket;\n\n            [Params(\"\\n \\0 \\n\")] public required string Combo;\n\n            [Params(\"C:\\\\file1.txt\")] public required string Path1;\n            [Params(@\"C:\\file2.txt\")] public required string Path2;\n\n            [Benchmark]\n            public void Benchmark()\n            {\n                var isPassedAsSingleCharacter =\n                    Null.Length == 1 &&\n                    Tab.Length == 1 &&\n                    NewLine.Length == 1 &&\n                    Slash.Length == 1 &&\n                    Quote.Length == 1 &&\n                    Unicode.Length == 1 &&\n                    Bracket.Length == 1;\n\n                if (!isPassedAsSingleCharacter)\n                    throw new InvalidOperationException(\"Some Param has an invalid escaped string\");\n            }\n        }\n\n        [Fact]\n        public void SpecialCharactersInCharAreSupported() => CanExecute<CompileSpecialCharactersInChar>();\n\n        public class CompileSpecialCharactersInChar\n        {\n            [Params('\\0')] public char Null;\n            [Params('\\t')] public char Tab;\n            [Params('\\n')] public char NewLine;\n            [Params('\\\\')] public char Slash;\n            [Params('\\\"')] public char Quote;\n            [Params('\\u0061')] public char Unicode;\n\n            [Benchmark]\n            public void Benchmark() { }\n        }\n\n        [Fact]\n        public void ParamsMustBeEscapedProperly() => CanExecute<NeedEscaping>();\n\n        public class NeedEscaping\n        {\n            private const string Json = \"{ \\\"message\\\": \\\"Hello, World!\\\" }\";\n\n            [Params(Json)]\n            public required string Field;\n\n            [Benchmark]\n            [Arguments(Json)]\n            public void Benchmark(string argument)\n            {\n                if (Field != Json || argument != Json)\n                    throw new InvalidOperationException(\"Wrong character escaping!\");\n            }\n        }\n\n        [Fact]\n        public void ArrayCanBeUsedAsParameter() => CanExecute<WithArray>();\n\n        public class WithArray\n        {\n            [Params(new[] { 0, 1, 2 })]\n            public required int[] Array;\n\n            [Benchmark]\n            public void AcceptingArray()\n            {\n                if (Array.Length != 3)\n                    throw new InvalidOperationException(\"Incorrect array length\");\n\n                for (int i = 0; i < 3; i++)\n                    if (Array[i] != i)\n                        throw new InvalidOperationException($\"Incorrect array element at index {i}, was {Array[i]} instead of {i}\");\n            }\n        }\n\n        [Fact]\n        public void StaticFieldsAndPropertiesCanBeParams() => CanExecute<WithStaticParams>();\n\n        public class WithStaticParams\n        {\n            [Params(1)]\n            public static int StaticParamField = 0;\n\n            [Params(2)]\n            public static int StaticParamProperty { get; set; } = 0;\n\n            [Benchmark]\n            public void Test()\n            {\n                if (StaticParamField != 1)\n                    throw new ArgumentException($\"{nameof(StaticParamField)} has wrong value: {StaticParamField}!\");\n                if (StaticParamProperty != 2)\n                    throw new ArgumentException($\"{nameof(StaticParamProperty)} has wrong value: {StaticParamProperty}!\");\n            }\n        }\n\n#if NET8_0_OR_GREATER\n        [Fact]\n        public void ParamsSupportRequiredProperty()\n        {\n            var summary = CanExecute<ParamsTestRequiredProperty>();\n            var standardOutput = GetCombinedStandardOutput(summary);\n\n            foreach (var param in new[] { \"a\", \"b\" })\n            {\n                Assert.Contains($\"// ### New Parameter {param} ###\", standardOutput);\n            }\n        }\n\n        public class ParamsTestRequiredProperty\n        {\n            [Params(\"a\", \"b\")]\n            public required string ParamProperty { get; set; }\n\n            [Benchmark]\n            public void Benchmark() => Console.WriteLine($\"// ### New Parameter {ParamProperty} ###\");\n        }\n#endif\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/PathTooLongTests.cs",
    "content": "﻿using BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Tests.XUnit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.IntegrationTests\n{\n    public class PathTooLongTests : BenchmarkTestExecutor\n    {\n        public PathTooLongTests(ITestOutputHelper output) : base(output)\n        {\n        }\n\n        [FactEnvSpecific(\"Testing Windows long path limitation\", EnvRequirement.WindowsOnly)]\n        public void PathTooLongTest() =>\n            CanExecute<\n                VeryLongName012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789>();\n\n        [DryJob]\n        public class\n            VeryLongName012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\n        {\n            [Benchmark]\n            public void Foo() { }\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/PowerManagementApplierTests.cs",
    "content": "﻿using BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Helpers;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Tests.Loggers;\nusing BenchmarkDotNet.Tests.XUnit;\nusing System.Globalization;\nusing Xunit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.IntegrationTests\n{\n    public class PowerManagementApplierTests : BenchmarkTestExecutor\n    {\n        public const string HighPerformancePlanGuid = \"8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c\";\n\n        public PowerManagementApplierTests(ITestOutputHelper output) : base(output) { }\n\n        [FactEnvSpecific(\"Setting high-performance plan is suitable only on Windows\", EnvRequirement.WindowsOnly)]\n        public void TestSettingAndRevertingBackGuid()\n        {\n            var userPlan = PowerManagementHelper.CurrentPlan;\n\n            using var powerManagementApplier = new PowerManagementApplier(new OutputLogger(Output));\n\n            powerManagementApplier.ApplyPerformancePlan(PowerManagementApplier.Map(PowerPlan.HighPerformance));\n\n            Assert.Equal(HighPerformancePlanGuid, PowerManagementHelper.CurrentPlan.ToString());\n\n            if (CultureInfo.CurrentUICulture.Name == \"en-us\")\n                Assert.Equal(\"High performance\", PowerManagementHelper.CurrentPlanFriendlyName);\n\n            Assert.Equal(userPlan, PowerManagementHelper.CurrentPlan);\n        }\n\n        [FactEnvSpecific(\"Setting high-performance plan is suitable only on Windows\", EnvRequirement.WindowsOnly)]\n        public void TestPowerPlanShouldNotChange()\n        {\n            var userPlan = PowerManagementHelper.CurrentPlan;\n            using var powerManagementApplier = new PowerManagementApplier(new OutputLogger(Output));\n\n            powerManagementApplier.ApplyPerformancePlan(PowerManagementApplier.Map(PowerPlan.UserPowerPlan));\n\n            Assert.Equal(userPlan.ToString(), PowerManagementHelper.CurrentPlan.ToString());\n\n            Assert.Equal(userPlan, PowerManagementHelper.CurrentPlan);\n        }\n    }\n}\n"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/PowerRequest.cs",
    "content": "﻿namespace BenchmarkDotNet.IntegrationTests;\n\ninternal class PowerRequest(string requestType, string requesterType, string requesterName, string? reason)\n{\n    public string RequestType { get; } = requestType;\n    public string RequesterType { get; } = requesterType;\n    public string RequesterName { get; } = requesterName;\n    public string? Reason { get; } = reason;\n}\n"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/PowerRequestsParser.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.IO;\n\nnamespace BenchmarkDotNet.IntegrationTests;\n\n/// <summary>\n/// Parses the output of 'powercfg /requests' command into a list of <see cref=\"PowerRequest\"/>s.\n/// </summary>\n/// <remarks>\n/// <para>\n/// Not using <see cref=\"https://github.com/sprache/Sprache\">Sprache</see>. It is superseded by Superpower.\n/// Not using <see cref=\"https://github.com/datalust/superpower\">Superpower</see>. I gained more knowledge\n/// implementing this class from scratch.\n/// </para>\n/// <para>Example input:</para>\n/// <code>\n/// DISPLAY:\n/// [PROCESS] \\Device\\HarddiskVolume3\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe\n/// Video Wake Lock\n///\n/// SYSTEM:\n/// [DRIVER] Realtek High Definition Audio(SST) ...\n/// Er wordt momenteel een audiostream gebruikt.\n/// [PROCESS] \\Device\\HarddiskVolume3\\...\\NoSleep.exe\n/// [PROCESS] \\Device\\HarddiskVolume3\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe\n/// Video Wake Lock\n///\n/// AWAYMODE:\n/// None.\n///\n/// EXECUTION:\n/// [PROCESS] \\Device\\HarddiskVolume3\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe\n/// Playing audio\n///\n/// PERFBOOST:\n/// None.\n///\n/// ACTIVELOCKSCREEN:\n/// None.\n///\n/// </code>\n/// </remarks>\ninternal class PowerRequestsParser\n{\n    /// <summary>\n    /// Parses output of 'powercfg /requests' into a list of <see cref=\"PowerRequest\"/>s.\n    /// </summary>\n    /// <remarks>\n    /// <para>\n    /// This method takes a list of <see cref=\"Token\"/>s. Examines next token and decides how to\n    /// parse.\n    /// </para>\n    /// </remarks>\n    /// <param name=\"input\">Output of 'powercfg /requests'.</param>\n    public static IEnumerable<PowerRequest> Parse(string input)\n    {\n        using TokenStream tokens = new TokenStream(Tokens(input));\n        while (tokens.TryPeek().HasValue)\n        {\n            foreach (PowerRequest item in ParseRequestType(tokens))\n            {\n                yield return item;\n            }\n        }\n    }\n\n    private static IEnumerable<PowerRequest> ParseRequestType(TokenStream tokens)\n    {\n        Token requestType = tokens.Take(TokenType.RequestType);\n        if (tokens.Peek().TokenType == TokenType.RequesterType)\n        {\n            while (tokens.Peek().TokenType == TokenType.RequesterType)\n            {\n                yield return ParseRequesterType(requestType, tokens);\n            }\n        }\n        else\n        {\n            _ = tokens.Take(TokenType.None);\n        }\n        _ = tokens.Take(TokenType.EmptyLine);\n    }\n\n    private static PowerRequest ParseRequesterType(Token requestType, TokenStream tokens)\n    {\n        Token requesterType = tokens.Take(TokenType.RequesterType);\n        Token requesterName = tokens.Take(TokenType.RequesterName);\n        Token? reason = null;\n        if (tokens.Peek().TokenType == TokenType.Reason)\n        {\n            reason = tokens.Take(TokenType.Reason);\n        }\n        return new PowerRequest(requestType.Value, requesterType.Value, requesterName.Value, reason?.Value);\n    }\n\n    /// <summary>\n    /// Converts the input into a list of <see cref=\"Toden\"/>s.\n    /// </summary>\n    /// <remarks>\n    /// <para>\n    /// Looking at above sample, tokenizing is made simple when done line by line. Each line\n    /// contains one or two <see cref=\"Token\"/>s.\n    /// </para>\n    /// </remarks>\n    /// <param name=\"input\">Output of 'powercfg /requests'.</param>\n    private static IEnumerable<Token> Tokens(string input)\n    {\n        // Contrary to calling input.Split('\\r', '\\n'), StringReader's ReadLine method does not\n        // return an empty string when CR is followed by LF.\n        StringReader reader = new StringReader(input);\n        string? line;\n        while ((line = reader.ReadLine()) != null)\n        {\n            if (line.Length == 0)\n            {\n                yield return new Token(TokenType.EmptyLine, \"\");\n            }\n            else if (line[line.Length - 1] == ':')\n            {\n                yield return new Token(TokenType.RequestType, line.Substring(0, line.Length - 1).ToString());\n            }\n            else if (string.Equals(line, \"None.\", StringComparison.InvariantCulture))\n            {\n                yield return new Token(TokenType.None, line);\n            }\n            else if (line[0] == '[')\n            {\n                int pos = line.IndexOf(']');\n                yield return new Token(TokenType.RequesterType, line.Substring(1, pos - 1));\n                yield return new Token(TokenType.RequesterName, line.Substring(pos + 2));\n            }\n            else\n            {\n                yield return new Token(TokenType.Reason, line);\n            }\n        }\n    }\n\n    /// <summary>\n    /// Adds <see cref=\"Peek\"/> and <see cref=\"TryPeek\"/> to an <see cref=\"IEnumerable{T}\"/> of\n    /// <see cref=\"Token\"/>s.\n    /// </summary>\n    /// <param name=\"tokens\"></param>\n    private class TokenStream(IEnumerable<Token> tokens) : IDisposable\n    {\n        private readonly IEnumerator<Token> tokens = tokens.GetEnumerator();\n        private Token? cached;\n\n        public Token? TryPeek() => cached ??= tokens.MoveNext() ? tokens.Current : null;\n\n        public Token Peek() => TryPeek() ?? throw new EndOfStreamException();\n\n        public Token Take(TokenType requestType)\n        {\n            Token peek = Peek();\n            if (peek.TokenType == requestType)\n            {\n                cached = null;\n                return peek;\n            }\n            else\n            {\n                throw new InvalidCastException($\"Unexpected Token of type '{peek.TokenType}'. Expected type '{requestType}'.\");\n            }\n        }\n\n        public void Dispose() => tokens.Dispose();\n    }\n\n    private enum TokenType\n    {\n        EmptyLine,\n        None,\n        Reason,\n        RequesterName,\n        RequesterType,\n        RequestType\n    }\n\n    private readonly struct Token(TokenType tokenType, string value)\n    {\n        public TokenType TokenType { get; } = tokenType;\n\n        public string Value { get; } = value;\n    }\n}\n"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/PriorityTests.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Linq;\nusing BenchmarkDotNet.Attributes;\nusing Xunit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.IntegrationTests\n{\n    public class PriorityTests : BenchmarkTestExecutor\n    {\n        public PriorityTests(ITestOutputHelper output) : base(output) { }\n\n        [Fact]\n        public void ParamsSupportPropertyWithPublicSetter()\n        {\n            var config = CreateSimpleConfig();\n\n            var summary = CanExecute<PriorityBenchmark>(config);\n            var columns = summary.Table.Columns;\n            var aColumn = columns.First(col => col.Header == \"A\");\n            var bColumn = columns.First(col => col.Header == \"b\");\n            var cColumn = columns.First(col => col.Header == \"c\");\n            var dColumn = columns.First(col => col.Header == \"d\");\n            var eColumn = columns.First(col => col.Header == \"E\");\n            var fColumn = columns.First(col => col.Header == \"F\");\n\n            Assert.NotNull(aColumn);\n            Assert.NotNull(bColumn);\n            Assert.NotNull(cColumn);\n            Assert.NotNull(dColumn);\n            Assert.NotNull(eColumn);\n            Assert.NotNull(fColumn);\n\n            Assert.True(aColumn.OriginalColumn.PriorityInCategory == -100);\n            Assert.True(bColumn.OriginalColumn.PriorityInCategory == -10);\n            Assert.True(cColumn.OriginalColumn.PriorityInCategory == 0);\n            Assert.True(dColumn.OriginalColumn.PriorityInCategory == 0);\n            Assert.True(eColumn.OriginalColumn.PriorityInCategory == 10);\n            Assert.True(fColumn.OriginalColumn.PriorityInCategory == 50);\n\n            Assert.True(aColumn.Index < bColumn.Index);\n            Assert.True(bColumn.Index < cColumn.Index);\n            Assert.True(cColumn.Index < dColumn.Index);\n            Assert.True(dColumn.Index < eColumn.Index);\n            Assert.True(eColumn.Index < fColumn.Index);\n        }\n\n        public class PriorityBenchmark\n        {\n            [Params(100, Priority = -100)]\n            public int A { get; set; }\n\n            [ParamsSource(nameof(NumberParams), Priority = 50)]\n            public int F { get; set; }\n\n            [ParamsAllValues(Priority = 10)]\n            public bool E;\n\n            [Arguments(5, Priority = -10)]\n            [Arguments(10)]\n            [Arguments(20)]\n            [Benchmark]\n            public int OneArgument(int b) => E ? A + b : F;\n\n            [Benchmark]\n            [ArgumentsSource(nameof(NumberArguments))]\n            public int ManyArguments(int c, int d) => E ? A + c + d : F;\n\n            public IEnumerable<object[]> NumberArguments()\n            {\n                yield return new object[] { 1, 2 };\n            }\n\n            public IEnumerable<int> NumberParams =>\n            [\n                50\n            ];\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/ProcessPropertiesTests.cs",
    "content": "﻿using System;\nusing System.Diagnostics;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Columns;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Tests.Loggers;\nusing BenchmarkDotNet.Tests.XUnit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.IntegrationTests\n{\n    public class ProcessPropertiesTests : BenchmarkTestExecutor\n    {\n        public ProcessPropertiesTests(ITestOutputHelper output)\n            : base(output)\n        {\n        }\n\n        [FactEnvSpecific(\"Process.set_PriorityClass requires root on Unix\", EnvRequirement.WindowsOnly)]\n        public void HighPriorityIsSet()\n        {\n            CanExecute<HighPriority>();\n        }\n\n        [FactEnvSpecific(\"Process.set_ProcessorAffinity requires root on Unix\", EnvRequirement.WindowsOnly)]\n        public void CustomAffinityCanBeSet()\n        {\n            var config = ManualConfig.CreateEmpty()\n                .AddJob(Job.Dry.WithAffinity(CustomAffinity.Value))\n                .AddColumnProvider(DefaultColumnProviders.Instance)\n                .AddLogger(new OutputLogger(Output));\n\n            CanExecute<CustomAffinity>(config);\n        }\n    }\n\n    public class HighPriority\n    {\n        [Benchmark]\n        public void Ensure()\n        {\n            if (Process.GetCurrentProcess().PriorityClass != ProcessPriorityClass.High)\n            {\n                throw new InvalidOperationException(\"Did not set high priority\");\n            }\n        }\n    }\n\n    public class CustomAffinity\n    {\n        public static readonly IntPtr Value = new IntPtr(2);\n\n        [Benchmark]\n        public void Ensure()\n        {\n#if NET6_0_OR_GREATER\n            if (OperatingSystem.IsWindows())\n#endif\n            {\n                if (Process.GetCurrentProcess().ProcessorAffinity != Value)\n                {\n                    throw new InvalidOperationException($\"Did not set custom affinity {Process.GetCurrentProcess().ProcessorAffinity} != {Value}\");\n                }\n            }\n        }\n    }\n\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/ProcessorArchitectureTest.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Portability;\nusing BenchmarkDotNet.Tests.Loggers;\nusing Xunit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.IntegrationTests\n{\n    public class ProcessorArchitectureTest : BenchmarkTestExecutor\n    {\n        public ProcessorArchitectureTest(ITestOutputHelper outputHelper) : base(outputHelper)\n        {\n        }\n\n        public static IEnumerable<object[]> Arguments()\n        {\n            Platform current = RuntimeInformation.GetCurrentPlatform();\n\n            if (RuntimeInformation.IsFullFramework && current is Platform.X64 or Platform.X86)\n            {\n                // RoslynToolchain (used for Full Framework) supports building and running for different architecture than the host process\n                yield return new object[]\n                {\n                    current is Platform.X64 ? Platform.X86 : Platform.X64,\n                    current is Platform.X64 ? typeof(Benchmark_32bit) : typeof(Benchmark_64bit)\n                };\n            }\n\n            yield return new object[] { current, IntPtr.Size == 8 ? typeof(Benchmark_64bit) : typeof(Benchmark_32bit) };\n            yield return new object[] { Platform.AnyCpu, typeof(AnyCpuBenchmark) };\n        }\n\n        [Theory]\n        [MemberData(nameof(Arguments))]\n        public void SpecifiedProcessorArchitectureMustBeRespected(Platform platform, Type benchmark)\n        {\n            var config = ManualConfig.CreateEmpty()\n                    .AddJob(Job.Dry.WithPlatform(platform))\n                    .AddLogger(new OutputLogger(Output)); // make sure we get an output in the TestRunner log\n\n            // CanExecute ensures that at least one benchmark has executed successfully\n            CanExecute(benchmark, config, fullValidation: true);\n        }\n\n        public class Benchmark_32bit\n        {\n            [Benchmark]\n            public void Verify()\n            {\n                if (IntPtr.Size != 4)\n                {\n                    throw new InvalidOperationException(\"32 bit failed!\");\n                }\n            }\n        }\n\n        public class Benchmark_64bit\n        {\n            [Benchmark]\n            public void Verify()\n            {\n                if (IntPtr.Size != 8)\n                {\n                    throw new InvalidOperationException(\"64 bit failed!\");\n                }\n            }\n        }\n\n        public class AnyCpuBenchmark\n        {\n            [Benchmark]\n            public void AnyCpu()\n            {\n            }\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/Properties/AssemblyInfo.cs",
    "content": "﻿using System.Runtime.InteropServices;\nusing Xunit;\n\n[assembly: Guid(\"74362bb1-9f64-4be5-b079-b4ac19dae5db\")]\n\n[assembly: CollectionBehavior(CollectionBehavior.CollectionPerAssembly, DisableTestParallelization = true)]"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/R2RTests.cs",
    "content": "using System;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.IntegrationTests.Xunit;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Portability;\nusing BenchmarkDotNet.Tests.XUnit;\nusing BenchmarkDotNet.Toolchains.R2R;\nusing BenchmarkDotNet.Toolchains.DotNetCli;\nusing Xunit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.IntegrationTests\n{\n    public class R2RTests : BenchmarkTestExecutor\n    {\n        public R2RTests(ITestOutputHelper output) : base(output) { }\n\n        private ManualConfig GetConfig()\n        {\n            var toolchain = R2RToolchain.From(\n                new NetCoreAppSettings(\n                    targetFrameworkMoniker: GetTargetFrameworkMoniker(),\n                    runtimeFrameworkVersion: null!,\n                    name: \"R2RTest\"));\n\n            return ManualConfig.CreateEmpty()\n                .AddJob(Job.Dry\n                    .WithRuntime(GetCurrentR2RRuntime())\n                    .WithToolchain(toolchain))\n                .WithBuildTimeout(TimeSpan.FromSeconds(240));\n        }\n\n        private static string GetTargetFrameworkMoniker()\n        {\n#if NET10_0_OR_GREATER\n            return \"net10.0\";\n#elif NET9_0_OR_GREATER\n            return \"net9.0\";\n#elif NET8_0_OR_GREATER\n            return \"net8.0\";\n#else\n            throw new NotSupportedException(\"R2R tests require .NET 8.0 or later\");\n#endif\n        }\n\n        private static R2RRuntime GetCurrentR2RRuntime()\n        {\n#if NET10_0_OR_GREATER\n            return R2RRuntime.Net10_0;\n#elif NET9_0_OR_GREATER\n            return R2RRuntime.Net90;\n#elif NET8_0_OR_GREATER\n            return R2RRuntime.Net80;\n#else\n            throw new NotSupportedException(\"R2R tests require .NET 8.0 or later\");\n#endif\n        }\n\n        [FactEnvSpecific(\"R2R requires .NET Core runtime\", EnvRequirement.DotNetCoreOnly)]\n        public void R2RToolchainCanExecuteBenchmarks()\n        {\n            try\n            {\n                var summary = CanExecute<R2RBenchmark>(GetConfig());\n\n                Assert.True(summary.Reports.Length > 0, \"Expected at least one benchmark report\");\n                Assert.True(summary.Reports[0].Success, \"Benchmark should have executed successfully\");\n            }\n            catch (MisconfiguredEnvironmentException e)\n            {\n                if (ContinuousIntegration.IsLocalRun())\n                    Output.WriteLine(e.SkipMessage);\n                else\n                    throw;\n            }\n        }\n    }\n\n    public class R2RBenchmark\n    {\n        [Benchmark]\n        public void SimpleMethod()\n        {\n            // I don't believe there is a simple way to verify at runtime that we are actually running under r2r.\n            // Reading PE format for app assemblies doesn't seem worth it.\n        }\n    }\n}\n"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/ReferencesTests.cs",
    "content": "﻿using Xunit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.IntegrationTests\n{\n    public class ReferencesTests : BenchmarkTestExecutor\n    {\n        public ReferencesTests(ITestOutputHelper output) : base(output) { }\n\n#if NETFRAMEWORK\n        [Fact]\n        public void BenchmarksThatUseTypeFromCustomPathDllAreSupported()\n            => CanExecute<BenchmarkDotNet.IntegrationTests.CustomPaths.BenchmarksThatUseTypeFromCustomPathDll>();\n\n        [Fact]\n        public void BenchmarksThatReturnTypeFromCustomPathDllAreSupported()\n            => CanExecute<BenchmarkDotNet.IntegrationTests.CustomPaths.BenchmarksThatReturnTypeFromCustomPathDll>();\n#endif\n        [Fact]\n        public void FSharpIsSupported() => CanExecute<FSharpBenchmarks.Db>();\n\n        [Fact]\n        public void VisualBasicIsSupported() => CanExecute<VisualBasic.Sample>();\n    }\n}\n"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/RoslynToolchainTest.cs",
    "content": "﻿using System.Globalization;\nusing System.Threading;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Tests.XUnit;\nusing BenchmarkDotNet.Toolchains.Roslyn;\nusing Xunit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.IntegrationTests\n{\n    public class RoslynToolchainTest : BenchmarkTestExecutor\n    {\n        public RoslynToolchainTest(ITestOutputHelper output) : base(output) { }\n\n        /// <summary>Prooftest for #1039.</summary>\n        [TheoryEnvSpecific(\"Roslyn toolchain does not support .NET Core\", EnvRequirement.FullFrameworkOnly)]\n        [InlineData(\"en-US\")]\n        [InlineData(\"fr-FR\")]\n        [InlineData(\"ru-RU\")]\n        [InlineData(\"ja-JP\")]\n        public void CanExecuteWithNonDefaultUiCulture(string culture)\n        {\n            var originCulture = CultureInfo.CurrentCulture;\n            var originUiCulture = CultureInfo.CurrentUICulture;\n            try\n            {\n                var overrideCulture = CultureInfo.GetCultureInfo(culture);\n                Assert.NotNull(overrideCulture);\n                Assert.False(overrideCulture.IsNeutralCulture);\n                CultureInfo.CurrentCulture = overrideCulture;\n                CultureInfo.CurrentUICulture = overrideCulture;\n\n                var miniJob = Job.Dry.WithToolchain(RoslynToolchain.Instance);\n                var config = CreateSimpleConfig(job: miniJob);\n\n                CanExecute<SimpleBenchmarks>(config);\n            }\n            finally\n            {\n                CultureInfo.CurrentCulture = originCulture;\n                CultureInfo.CurrentUICulture = originUiCulture;\n            }\n        }\n\n        public class SimpleBenchmarks\n        {\n            [Benchmark]\n            public void Benchmark() => Thread.Sleep(5);\n        }\n    }\n}\n"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/RunStrategyTests.cs",
    "content": "﻿using System.Linq;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Columns;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Tests.Loggers;\nusing Xunit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.IntegrationTests\n{\n    public class RunStrategyTests : BenchmarkTestExecutor\n    {\n        public RunStrategyTests(ITestOutputHelper output) : base(output) { }\n\n        [Fact]\n        public void RunStrategiesAreSupported()\n        {\n            var config = ManualConfig.CreateEmpty()\n                .AddColumnProvider(DefaultColumnProviders.Instance)\n                .AddLogger(new OutputLogger(Output))\n                .AddJob(new Job(Job.Dry) { Run = { RunStrategy = RunStrategy.ColdStart } })\n                .AddJob(new Job(Job.Dry) { Run = { RunStrategy = RunStrategy.Monitoring } })\n                .AddJob(new Job(Job.Dry) { Run = { RunStrategy = RunStrategy.Throughput } });\n\n            var results = CanExecute<ModeBenchmarks>(config);\n\n            Assert.Equal(6, results.BenchmarksCases.Count());\n\n            Assert.Equal(1, results.BenchmarksCases.Count(b => b.Job.Run.RunStrategy == RunStrategy.ColdStart && b.Descriptor.WorkloadMethod.Name == \"BenchmarkWithVoid\"));\n            Assert.Equal(1, results.BenchmarksCases.Count(b => b.Job.Run.RunStrategy == RunStrategy.ColdStart && b.Descriptor.WorkloadMethod.Name == \"BenchmarkWithReturnValue\"));\n\n            Assert.Equal(1, results.BenchmarksCases.Count(b => b.Job.Run.RunStrategy == RunStrategy.Monitoring && b.Descriptor.WorkloadMethod.Name == \"BenchmarkWithVoid\"));\n            Assert.Equal(1, results.BenchmarksCases.Count(b => b.Job.Run.RunStrategy == RunStrategy.Monitoring && b.Descriptor.WorkloadMethod.Name == \"BenchmarkWithReturnValue\"));\n\n            Assert.Equal(1, results.BenchmarksCases.Count(b => b.Job.Run.RunStrategy == RunStrategy.Throughput && b.Descriptor.WorkloadMethod.Name == \"BenchmarkWithVoid\"));\n            Assert.Equal(1, results.BenchmarksCases.Count(b => b.Job.Run.RunStrategy == RunStrategy.Throughput && b.Descriptor.WorkloadMethod.Name == \"BenchmarkWithReturnValue\"));\n\n            Assert.Equal(6, results.Reports.Length);\n\n            Assert.Single(results.Reports.Where(r => r.BenchmarkCase.Job.Run.RunStrategy == RunStrategy.ColdStart && r.BenchmarkCase.Descriptor.WorkloadMethod.Name == \"BenchmarkWithVoid\"));\n            Assert.Single(results.Reports.Where(r => r.BenchmarkCase.Job.Run.RunStrategy == RunStrategy.ColdStart && r.BenchmarkCase.Descriptor.WorkloadMethod.Name == \"BenchmarkWithReturnValue\"));\n\n            Assert.Single(results.Reports.Where(r => r.BenchmarkCase.Job.Run.RunStrategy == RunStrategy.Monitoring && r.BenchmarkCase.Descriptor.WorkloadMethod.Name == \"BenchmarkWithVoid\"));\n            Assert.Single(results.Reports.Where(r => r.BenchmarkCase.Job.Run.RunStrategy == RunStrategy.Monitoring && r.BenchmarkCase.Descriptor.WorkloadMethod.Name == \"BenchmarkWithReturnValue\"));\n\n            Assert.Single(results.Reports.Where(r => r.BenchmarkCase.Job.Run.RunStrategy == RunStrategy.Throughput && r.BenchmarkCase.Descriptor.WorkloadMethod.Name == \"BenchmarkWithVoid\"));\n            Assert.Single(results.Reports.Where(r => r.BenchmarkCase.Job.Run.RunStrategy == RunStrategy.Throughput && r.BenchmarkCase.Descriptor.WorkloadMethod.Name == \"BenchmarkWithReturnValue\"));\n\n            Assert.True(results.Reports.All(r => r.AllMeasurements.Any()));\n        }\n\n        public class ModeBenchmarks\n        {\n            [Benchmark]\n            public void BenchmarkWithVoid() { }\n\n            [Benchmark]\n            public string BenchmarkWithReturnValue() => \"okay\";\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/RunningEmptyBenchmarkTests.cs",
    "content": "using System;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Running;\nusing Xunit;\nusing System.Reflection;\nusing System.Reflection.Emit;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Columns;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Reports;\nusing System.Runtime.InteropServices;\nusing System.Runtime.CompilerServices;\nusing BenchmarkDotNet.Filters;\n\nnamespace BenchmarkDotNet.IntegrationTests\n{\n    public class RunningEmptyBenchmarkTests\n    {\n        #region BenchmarkRunner Methods Overview\n        /*\n         * Available BenchmarkRunner.Run methods:\n         * 1. Generic Type:\n         *    - BenchmarkRunner.Run<T>(IConfig? config = null, string[]? args = null)\n         * 2. Type-based:\n         *    - BenchmarkRunner.Run(Type type, IConfig? config = null, string[]? args = null)\n         *    - BenchmarkRunner.Run(Type[] types, IConfig? config = null, string[]? args = null)\n         *    - BenchmarkRunner.Run(Type type, MethodInfo[] methods, IConfig? config = null)\n         * 3. Assembly-based:\n         *    - BenchmarkRunner.Run(Assembly assembly, IConfig? config = null, string[]? args = null)\n         * 4. BenchmarkRunInfo-based:\n         *    - BenchmarkRunner.Run(BenchmarkRunInfo benchmarkRunInfo)\n         *    - BenchmarkRunner.Run(BenchmarkRunInfo[] benchmarkRunInfos)\n         * 5. Deprecated methods:\n         *    - BenchmarkRunner.RunUrl(string url, IConfig? config = null)\n         *    - BenchmarkRunner.RunSource(string source, IConfig? config = null)\n         */\n        #endregion\n        #region Generic Type Tests\n\n\n#pragma warning disable BDN1000\n        /// <summary>\n        /// Tests for <see cref=\"BenchmarkRunner.Run{T}\"/> method\n        /// </summary>\n        [Theory]\n        [InlineData(null)]\n        [InlineData([new string[] { \" \" }])]\n        public void GenericTypeWithoutBenchmarkAttribute_ThrowsValidationError_WhenNoBenchmarkAttribute(string[]? args)\n        {\n            GetConfigWithLogger(out var logger, out var config);\n\n            var summary = BenchmarkRunner.Run<EmptyBenchmark>(config, args);\n\n            if (args == null)\n            {\n                Assert.True(summary.HasCriticalValidationErrors);\n                Assert.Contains(summary.ValidationErrors, validationError => validationError.Message == GetValidationErrorForType(typeof(EmptyBenchmark)));\n                Assert.Contains(GetValidationErrorForType(typeof(EmptyBenchmark)), logger.GetLog());\n            }\n            else\n            {\n                // When args is provided and type is invalid, we get a ValidationFailed summary\n                // instead of an unhandled exception (fix for issue #2724)\n                Assert.NotNull(summary);\n                Assert.Contains(\"No benchmarks found\", summary.Title);\n            }\n        }\n#pragma warning restore BDN1000\n\n        [Theory]\n        [InlineData(null)]\n        [InlineData([new string[] { \" \" }])]\n        public void GenericTypeWithBenchmarkAttribute_RunsSuccessfully(string[]? args)\n        {\n            GetConfigWithLogger(out var logger, out var config);\n\n            var summary = BenchmarkRunner.Run<NotEmptyBenchmark>(config, args);\n            Assert.False(summary.HasCriticalValidationErrors);\n            Assert.DoesNotContain(summary.ValidationErrors, validationError => validationError.Message == GetValidationErrorForType(typeof(NotEmptyBenchmark)));\n            Assert.DoesNotContain(GetValidationErrorForType(typeof(NotEmptyBenchmark)), logger.GetLog());\n        }\n        #endregion\n        #region Type-based Tests\n\n#pragma warning disable BDN1000\n        /// <summary>\n        /// Tests for BenchmarkRunner.Run(Type) method\n        /// </summary>\n        [Theory]\n        [InlineData(null)]\n        [InlineData([new string[] { \" \" }])]\n        public void TypeWithoutBenchmarkAttribute_ThrowsValidationError_WhenNoBenchmarkAttribute(string[]? args)\n        {\n            GetConfigWithLogger(out var logger, out var config);\n\n            var summary = BenchmarkRunner.Run(typeof(EmptyBenchmark), config, args);\n\n            if (args == null)\n            {\n                Assert.True(summary.HasCriticalValidationErrors);\n                Assert.Contains(summary.ValidationErrors, validationError => validationError.Message == GetValidationErrorForType(typeof(EmptyBenchmark)));\n                Assert.Contains(GetValidationErrorForType(typeof(EmptyBenchmark)), logger.GetLog());\n            }\n            else\n            {\n                // When args is provided and type is invalid, we get a ValidationFailed summary\n                // instead of an unhandled exception (fix for issue #2724)\n                Assert.NotNull(summary);\n                Assert.Contains(\"No benchmarks found\", summary.Title);\n            }\n        }\n#pragma warning restore BDN1000\n\n        [Theory]\n        [InlineData(null)]\n        [InlineData([new string[] { \" \" }])]\n        public void TypeWithBenchmarkAttribute_RunsSuccessfully(string[]? args)\n        {\n            GetConfigWithLogger(out var logger, out var config);\n\n            var summaries = BenchmarkRunner.Run(typeof(NotEmptyBenchmark), config, args);\n            Assert.False(summaries.HasCriticalValidationErrors);\n            Assert.DoesNotContain(summaries.ValidationErrors, validationError => validationError.Message == GetValidationErrorForType(typeof(NotEmptyBenchmark)));\n            Assert.DoesNotContain(GetValidationErrorForType(typeof(NotEmptyBenchmark)), logger.GetLog());\n        }\n\n        /// <summary>\n        /// Tests for BenchmarkRunner.Run(Type[]) method\n        /// </summary>\n        [Theory]\n        [InlineData(null)]\n        [InlineData([new string[] { \" \" }])]\n        public void TypesWithoutBenchmarkAttribute_ThrowsValidationError_WhenNoBenchmarkAttribute(string[]? args)\n        {\n            GetConfigWithLogger(out var logger, out var config);\n\n            var summaries = BenchmarkRunner.Run([typeof(EmptyBenchmark), typeof(EmptyBenchmark2)], config, args);\n            if (args != null)\n            {\n                Assert.Contains(GetValidationErrorForType(typeof(EmptyBenchmark)), logger.GetLog());\n                Assert.Contains(GetValidationErrorForType(typeof(EmptyBenchmark2)), logger.GetLog());\n            }\n            else\n            {\n                var summary = summaries[0];\n                Assert.True(summary.HasCriticalValidationErrors);\n                Assert.Contains(summary.ValidationErrors, validationError => validationError.Message == GetValidationErrorForType(typeof(EmptyBenchmark)));\n                Assert.Contains(summary.ValidationErrors, validationError => validationError.Message == GetValidationErrorForType(typeof(EmptyBenchmark2)));\n                Assert.Contains(GetValidationErrorForType(typeof(EmptyBenchmark)), logger.GetLog());\n                Assert.Contains(GetValidationErrorForType(typeof(EmptyBenchmark2)), logger.GetLog());\n            }\n\n\n        }\n\n        [Theory]\n        [InlineData(null)]\n        [InlineData([new string[] { \" \" }])]\n        public void TypesWithBenchmarkAttribute_RunsSuccessfully(string[]? args)\n        {\n            GetConfigWithLogger(out var logger, out var config);\n\n            var summaries = BenchmarkRunner.Run([typeof(NotEmptyBenchmark)], config, args);\n            var summary = summaries[0];\n            Assert.False(summary.HasCriticalValidationErrors);\n            Assert.DoesNotContain(summary.ValidationErrors, validationError => validationError.Message == GetValidationErrorForType(typeof(NotEmptyBenchmark)));\n            Assert.DoesNotContain(GetValidationErrorForType(typeof(NotEmptyBenchmark)), logger.GetLog());\n        }\n        #endregion\n        #region BenchmarkRunInfo Tests\n        /// <summary>\n        /// Tests for BenchmarkRunner.Run(BenchmarkRunInfo) method\n        /// </summary>\n        [Fact]\n        public void BenchmarkRunInfoWithoutBenchmarkAttribute_ThrowsValidationError_WhenNoBenchmarkAttribute()\n        {\n            GetConfigWithLogger(out var logger, out var config);\n\n            var summary = BenchmarkRunner.Run(BenchmarkConverter.TypeToBenchmarks(typeof(EmptyBenchmark), config));\n            Assert.True(summary.HasCriticalValidationErrors);\n            Assert.Contains(summary.ValidationErrors, validationError => validationError.Message == GetValidationErrorForType(typeof(EmptyBenchmark)));\n            Assert.Contains(GetValidationErrorForType(typeof(EmptyBenchmark)), logger.GetLog());\n        }\n\n        [Fact]\n        public void BenchmarkRunInfoWithBenchmarkAttribute_RunsSuccessfully()\n        {\n            GetConfigWithLogger(out var logger, out var config);\n\n            var summary = BenchmarkRunner.Run(BenchmarkConverter.TypeToBenchmarks(typeof(NotEmptyBenchmark), config));\n            Assert.False(summary.HasCriticalValidationErrors);\n            Assert.DoesNotContain(summary.ValidationErrors, validationError => validationError.Message == GetValidationErrorForType(typeof(EmptyBenchmark)));\n            Assert.DoesNotContain(GetValidationErrorForType(typeof(NotEmptyBenchmark)), logger.GetLog());\n        }\n\n        /// <summary>\n        /// Tests for BenchmarkRunner.Run(BenchmarkRunInfo[]) method\n        /// </summary>\n        [Fact]\n        public void BenchmarkRunInfosWithoutBenchmarkAttribute_ThrowsValidationError_WhenNoBenchmarkAttribute()\n        {\n            GetConfigWithLogger(out var logger, out var config);\n\n            var summaries = BenchmarkRunner.Run([\n                BenchmarkConverter.TypeToBenchmarks(typeof(EmptyBenchmark), config),\n                BenchmarkConverter.TypeToBenchmarks(typeof(EmptyBenchmark2), config)\n            ]);\n            var summary = summaries[0];\n            Assert.True(summary.HasCriticalValidationErrors);\n            Assert.Contains(summary.ValidationErrors, validationError => validationError.Message == GetValidationErrorForType(typeof(EmptyBenchmark)));\n            Assert.Contains(summary.ValidationErrors, validationError => validationError.Message == GetValidationErrorForType(typeof(EmptyBenchmark2)));\n            Assert.Contains(GetValidationErrorForType(typeof(EmptyBenchmark)), logger.GetLog());\n            Assert.Contains(GetValidationErrorForType(typeof(EmptyBenchmark2)), logger.GetLog());\n        }\n\n        [Fact]\n        public void BenchmarkRunInfosWithBenchmarkAttribute_RunsSuccessfully()\n        {\n            GetConfigWithLogger(out var logger, out var config);\n\n            var summaries = BenchmarkRunner.Run([BenchmarkConverter.TypeToBenchmarks(typeof(NotEmptyBenchmark), config)]);\n            var summary = summaries[0];\n            Assert.False(summary.HasCriticalValidationErrors);\n            Assert.DoesNotContain(summary.ValidationErrors, validationError => validationError.Message == GetValidationErrorForType(typeof(NotEmptyBenchmark)));\n            Assert.DoesNotContain(GetValidationErrorForType(typeof(NotEmptyBenchmark)), logger.GetLog());\n        }\n        #endregion\n        #region Mixed Types Tests\n\n        [Theory]\n        [InlineData(null)]\n        [InlineData([new string[] { \" \" }])]\n        public void MixedTypes_ThrowsValidationError_WhenNoBenchmarkAttribute(string[]? args)\n        {\n            GetConfigWithLogger(out var logger, out var config);\n\n            var summaries = BenchmarkRunner.Run([typeof(EmptyBenchmark), typeof(NotEmptyBenchmark)], config, args);\n            if (args != null)\n            {\n                Assert.Contains(GetExpandedValidationErrorForType(typeof(EmptyBenchmark)), logger.GetLog());\n            }\n            else\n            {\n                var summary = summaries[0];\n                Assert.True(summary.HasCriticalValidationErrors);\n                Assert.Contains(summary.ValidationErrors, validationError => validationError.Message == GetValidationErrorForType(typeof(EmptyBenchmark)));\n                Assert.Contains(GetValidationErrorForType(typeof(EmptyBenchmark)), logger.GetLog());\n            }\n        }\n        #endregion\n        #region Assembly Tests\n        // In this tests there is no config and logger because the logger is initiated at CreateCompositeLogger when the BenchmarkRunInfo[] is empty\n        // those cannot be inserted using config\n\n        [Theory]\n        [InlineData(null)]\n        [InlineData([new string[] { \" \" }])]\n        public void AssemblyWithoutBenchmarks_ThrowsValidationError_WhenNoBenchmarksFound(string[]? args)\n        {\n\n            // Create a mock assembly with no benchmark types\n            var assemblyName = new AssemblyName(\"MockAssembly\");\n            var assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);\n            var moduleBuilder = assemblyBuilder.DefineDynamicModule(\"MockModule\");\n            // Create a simple type in the assembly (no benchmarks)\n            var typeBuilder = moduleBuilder.DefineType(\"MockType\", TypeAttributes.Public);\n            typeBuilder.CreateType();\n\n            if (args != null)\n            {\n                GetConfigWithLogger(out var logger, out var config);\n                var summaries = BenchmarkRunner.Run(assemblyBuilder, config, args);\n                Assert.Contains(GetAssemblylValidationError(assemblyBuilder), logger.GetLog());\n            }\n            else\n            {\n                var summaries = BenchmarkRunner.Run(assemblyBuilder, null, args);\n                var summary = summaries[0];\n                Assert.True(summary.HasCriticalValidationErrors);\n                Assert.Contains(summary.ValidationErrors, validationError => validationError.Message == GetGeneralValidationError());\n            }\n        }\n\n        [Theory]\n        [InlineData(null)]\n        [InlineData([new string[] { \" \" }])]\n        public void AssemblyWithBenchmarks_RunsSuccessfully_WhenBenchmarkAttributePresent(string[]? args)\n        {\n            // Skip test on .NET Framework 4.6.2\n            if (RuntimeInformation.FrameworkDescription.Contains(\".NET Framework 4\"))\n                return;\n\n            // Create a mock assembly with benchmark types\n            var assemblyName = new AssemblyName(\"MockAssemblyWithBenchmarks\");\n            var assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);\n            var moduleBuilder = assemblyBuilder.DefineDynamicModule(\"MockModule\");\n\n            // Create a benchmark type\n            var benchmarkTypeBuilder = moduleBuilder.DefineType(\"MockBenchmark\", TypeAttributes.Public);\n            var benchmarkMethod = benchmarkTypeBuilder.DefineMethod(\"Benchmark\", MethodAttributes.Public, typeof(void), Type.EmptyTypes);\n\n            // Generate method body\n            var ilGenerator = benchmarkMethod.GetILGenerator();\n            ilGenerator.Emit(OpCodes.Ret); // Just return from the method\n\n            benchmarkMethod.SetCustomAttribute(new CustomAttributeBuilder(\n                typeof(BenchmarkAttribute).GetConstructor([typeof(int), typeof(string)])!,\n                [0, \"\"]));\n            // Assembly weaver does not run on assemblies created with AssemblyBuilder, so we need to apply NoInlining manually.\n            benchmarkMethod.SetCustomAttribute(new CustomAttributeBuilder(\n                typeof(MethodImplAttribute).GetConstructor([typeof(MethodImplOptions)])!,\n                [MethodImplOptions.NoInlining]));\n            benchmarkTypeBuilder.CreateType();\n\n            if (args != null)\n            {\n                GetConfigWithLogger(out var logger, out var config);\n                var summaries = BenchmarkRunner.Run(assemblyBuilder, config, args);\n                Assert.DoesNotContain(GetAssemblylValidationError(assemblyBuilder), logger.GetLog());\n            }\n            else\n            {\n                var summaries = BenchmarkRunner.Run(assemblyBuilder);\n                var summary = summaries[0];\n                Assert.False(summary.HasCriticalValidationErrors);\n                Assert.DoesNotContain(summary.ValidationErrors, validationError => validationError.Message == GetGeneralValidationError());\n            }\n        }\n\n        [Fact]\n        public void AssemblyWithBenchmarks_RunsNothing_WhenAllBenchmarksFilteredOutFromOneTypeWithBenchmarkAttributePresent()\n        {\n            // Create a mock assembly with benchmark types\n            var assemblyName = new AssemblyName(\"MockAssemblyWithBenchmarks\");\n            var assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);\n            var moduleBuilder = assemblyBuilder.DefineDynamicModule(\"MockModule\");\n\n            // Create a benchmark type\n            var benchmarkTypeBuilder = moduleBuilder.DefineType(\"MockBenchmark\", TypeAttributes.Public);\n            var benchmarkMethod = benchmarkTypeBuilder.DefineMethod(\"Benchmark\", MethodAttributes.Public, typeof(void), Type.EmptyTypes);\n\n            // Generate method body\n            var ilGenerator = benchmarkMethod.GetILGenerator();\n            ilGenerator.Emit(OpCodes.Ret); // Just return from the method\n\n            var benchmarkAttributeCtor = typeof(BenchmarkAttribute).GetConstructor([typeof(int), typeof(string)]);\n            if (benchmarkAttributeCtor == null)\n                throw new InvalidOperationException(\"Could not find BenchmarkAttribute constructor\");\n            benchmarkMethod.SetCustomAttribute(new CustomAttributeBuilder(\n                benchmarkAttributeCtor,\n                [0, \"\"]));\n            benchmarkTypeBuilder.CreateType();\n\n            GetConfigWithLogger(out var logger, out var config);\n\n            config.AddFilter(new NameFilter(name => name != \"Benchmark\")); // Filter out only benchmark method on MockBenchmark\n\n            var summaries = BenchmarkRunner.Run(assemblyBuilder, config);\n            Assert.DoesNotContain(GetValidationErrorForType(benchmarkTypeBuilder), logger.GetLog());\n            Assert.Contains(GetExporterNoBenchmarksError(), logger.GetLog());\n        }\n\n        #endregion\n        #region Helper Methods\n        private string GetValidationErrorForType(Type type)\n        {\n            return $\"No [Benchmark] attribute found on '{type.Name}' benchmark case.\";\n        }\n\n        private string GetAssemblylValidationError(Assembly assembly)\n        {\n            return $\"No [Benchmark] attribute found on '{assembly.GetName().Name}' assembly.\";\n        }\n\n        private string GetExpandedValidationErrorForType(Type type)\n        {\n            return $\"Type {type} is invalid. Only public, non-generic (closed generic types with public parameterless ctors are supported), non-abstract, non-sealed, non-static types with public instance [Benchmark] method(s) are supported.\";\n        }\n\n        private string GetGeneralValidationError()\n        {\n            return $\"No benchmarks were found.\";\n        }\n\n        private string GetExporterNoBenchmarksError()\n        {\n            return \"There are no benchmarks found\";\n        }\n\n        private void GetConfigWithLogger(out AccumulationLogger logger, out ManualConfig manualConfig)\n        {\n            logger = new AccumulationLogger();\n            manualConfig = ManualConfig.CreateEmpty()\n                .AddLogger(logger)\n                .AddColumnProvider(DefaultColumnProviders.Instance);\n        }\n\n        #endregion\n        #region Test Classes\n        public class EmptyBenchmark\n        {\n        }\n\n        public class EmptyBenchmark2\n        {\n        }\n\n        [SimpleJob(launchCount: 1, warmupCount: 1, iterationCount: 1, invocationCount: 1, id: \"QuickJob\")]\n        public class NotEmptyBenchmark\n        {\n            [Benchmark]\n            public void Benchmark()\n            {\n                var sum = 0;\n                for (int i = 0; i < 1; i++)\n                {\n                    sum += i;\n                }\n            }\n        }\n        #endregion\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/SetupAndCleanupTests.cs",
    "content": "﻿using BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Jobs;\nusing System;\nusing System.Linq;\nusing Xunit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.IntegrationTests\n{\n    public class SetupAndCleanupTests : BenchmarkTestExecutor\n    {\n        private const string FirstPrefix = \"// ### First Called: \";\n        private const string FirstGlobalSetupCalled = FirstPrefix + \"GlobalSetup\";\n        private const string FirstGlobalCleanupCalled = FirstPrefix + \"GlobalCleanup\";\n        private const string FirstIterationSetupCalled = FirstPrefix + \"IterationSetup\";\n        private const string FirstIterationCleanupCalled = FirstPrefix + \"IterationCleanup\";\n        private const string FirstBenchmarkCalled = FirstPrefix + \"Benchmark\";\n\n        private const string SecondPrefix = \"// ### Second Called: \";\n        private const string SecondGlobalSetupCalled = SecondPrefix + \"GlobalSetup\";\n        private const string SecondGlobalCleanupCalled = SecondPrefix + \"GlobalCleanup\";\n        private const string SecondIterationSetupCalled = SecondPrefix + \"IterationSetup\";\n        private const string SecondIterationCleanupCalled = SecondPrefix + \"IterationCleanup\";\n        private const string SecondBenchmarkCalled = SecondPrefix + \"Benchmark\";\n\n        private const string OutputDelimiter = \"===========================================================\";\n\n        private readonly string[] firstExpectedLogLines = [\n            \"// ### First Called: GlobalSetup\",\n\n            \"// ### First Called: IterationSetup (1)\", // MainWarmup1\n            \"// ### First Called: Benchmark\", // MainWarmup1\n            \"// ### First Called: IterationCleanup (1)\", // MainWarmup1\n            \"// ### First Called: IterationSetup (2)\", // MainWarmup2\n            \"// ### First Called: Benchmark\", // MainWarmup2\n            \"// ### First Called: IterationCleanup (2)\", // MainWarmup2\n\n            \"// ### First Called: IterationSetup (3)\", // MainTarget1\n            \"// ### First Called: Benchmark\", // MainTarget1\n            \"// ### First Called: IterationCleanup (3)\", // MainTarget1\n            \"// ### First Called: IterationSetup (4)\", // MainTarget2\n            \"// ### First Called: Benchmark\", // MainTarget2\n            \"// ### First Called: IterationCleanup (4)\", // MainTarget2\n            \"// ### First Called: IterationSetup (5)\", // MainTarget3\n            \"// ### First Called: Benchmark\", // MainTarget3\n            \"// ### First Called: IterationCleanup (5)\", // MainTarget3\n\n            \"// ### First Called: GlobalCleanup\"\n        ];\n\n        private readonly string[] secondExpectedLogLines = [\n            \"// ### Second Called: GlobalSetup\",\n\n            \"// ### Second Called: IterationSetup (1)\", // MainWarmup1\n            \"// ### Second Called: Benchmark\", // MainWarmup1\n            \"// ### Second Called: IterationCleanup (1)\", // MainWarmup1\n            \"// ### Second Called: IterationSetup (2)\", // MainWarmup2\n            \"// ### Second Called: Benchmark\", // MainWarmup2\n            \"// ### Second Called: IterationCleanup (2)\", // MainWarmup2\n\n            \"// ### Second Called: IterationSetup (3)\", // MainTarget1\n            \"// ### Second Called: Benchmark\", // MainTarget1\n            \"// ### Second Called: IterationCleanup (3)\", // MainTarget1\n            \"// ### Second Called: IterationSetup (4)\", // MainTarget2\n            \"// ### Second Called: Benchmark\", // MainTarget2\n            \"// ### Second Called: IterationCleanup (4)\", // MainTarget2\n            \"// ### Second Called: IterationSetup (5)\", // MainTarget3\n            \"// ### Second Called: Benchmark\", // MainTarget3\n            \"// ### Second Called: IterationCleanup (5)\", // MainTarget3\n\n            \"// ### Second Called: GlobalCleanup\"\n        ];\n\n        public SetupAndCleanupTests(ITestOutputHelper output) : base(output) { }\n\n        [Fact]\n        public void AllSetupAndCleanupMethodRunsForSpecificBenchmark()\n        {\n            var miniJob = Job.Default.WithStrategy(RunStrategy.Monitoring).WithWarmupCount(2).WithIterationCount(3).WithInvocationCount(1).WithUnrollFactor(1).WithId(\"MiniJob\");\n            var config = CreateSimpleConfig(job: miniJob);\n\n            var summary = CanExecute<Benchmarks>(config);\n            var standardOutput = GetCombinedStandardOutput(summary);\n            Output.WriteLine(OutputDelimiter);\n            Output.WriteLine(OutputDelimiter);\n            Output.WriteLine(OutputDelimiter);\n\n            var firstActualLogLines = standardOutput.Where(line => line.StartsWith(FirstPrefix)).ToArray();\n            foreach (string line in firstActualLogLines)\n                Output.WriteLine(line);\n            Assert.Equal(firstExpectedLogLines, firstActualLogLines);\n\n            var secondActualLogLines = standardOutput.Where(line => line.StartsWith(SecondPrefix)).ToArray();\n            foreach (string line in secondActualLogLines)\n                Output.WriteLine(line);\n            Assert.Equal(secondExpectedLogLines, secondActualLogLines);\n        }\n\n        public class Benchmarks\n        {\n            private int setupCounter;\n            private int cleanupCounter;\n\n            [IterationSetup(Target = nameof(FirstBenchmark))]\n            public void FirstIterationSetup() => Console.WriteLine(FirstIterationSetupCalled + \" (\" + ++setupCounter + \")\");\n\n            [IterationCleanup(Target = nameof(FirstBenchmark))]\n            public void FirstIterationCleanup() => Console.WriteLine(FirstIterationCleanupCalled + \" (\" + ++cleanupCounter + \")\");\n\n            [GlobalSetup(Target = nameof(FirstBenchmark))]\n            public void FirstGlobalSetup() => Console.WriteLine(FirstGlobalSetupCalled);\n\n            [GlobalCleanup(Target = nameof(FirstBenchmark))]\n            public void FirstGlobalCleanup() => Console.WriteLine(FirstGlobalCleanupCalled);\n\n            [Benchmark]\n            public void FirstBenchmark() => Console.WriteLine(FirstBenchmarkCalled);\n\n\n            [IterationSetup(Target = nameof(SecondBenchmark))]\n            public void SecondIterationSetup() => Console.WriteLine(SecondIterationSetupCalled + \" (\" + ++setupCounter + \")\");\n\n            [IterationCleanup(Target = nameof(SecondBenchmark))]\n            public void SecondIterationCleanup() => Console.WriteLine(SecondIterationCleanupCalled + \" (\" + ++cleanupCounter + \")\");\n\n            [GlobalSetup(Target = nameof(SecondBenchmark))]\n            public void SecondGlobalSetup() => Console.WriteLine(SecondGlobalSetupCalled);\n\n            [GlobalCleanup(Target = nameof(SecondBenchmark))]\n            public void SecondGlobalCleanup() => Console.WriteLine(SecondGlobalCleanupCalled);\n\n            [Benchmark]\n            public void SecondBenchmark() => Console.WriteLine(SecondBenchmarkCalled);\n        }\n    }\n}\n"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/StandardErrorTests.cs",
    "content": "﻿using BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Tests.Loggers;\nusing System;\nusing Xunit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.IntegrationTests\n{\n    public class StandardErrorTests : BenchmarkTestExecutor\n    {\n        private const string ErrorMessage = \"ErrorMessage\";\n\n        public StandardErrorTests(ITestOutputHelper output) : base(output)\n        {\n        }\n\n        [Fact]\n        public void BenchmarkCanWriteToStandardError() => CanExecute<WritingToStandardError>();\n\n        public class WritingToStandardError\n        {\n            [Benchmark]\n            public void Write() => Console.Error.Write(new string('a', 10_000)); // the text needs to be big enough to hit the deadlock\n        }\n\n        [Fact]\n        public void ExceptionMessageIsNotLost()\n        {\n            var logger = new OutputLogger(Output);\n            var config = CreateSimpleConfig(logger);\n\n            CanExecute<ThrowingException>(config, fullValidation: false);\n\n            Assert.Contains(ErrorMessage, logger.GetLog());\n        }\n\n        public class ThrowingException\n        {\n            [Benchmark]\n            public void Write() => throw new Exception(ErrorMessage);\n        }\n    }\n}\n"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/StatResultExtenderTests.cs",
    "content": "﻿using System;\nusing System.Threading;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Columns;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Tests.Loggers;\nusing Perfolizer.Horology;\nusing Xunit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.IntegrationTests\n{\n    public class StatResultExtenderTests : BenchmarkTestExecutor\n    {\n        public StatResultExtenderTests(ITestOutputHelper output) : base(output)\n        {\n        }\n\n        [Fact]\n        public void ExtraColumnsCanBeDefined()\n        {\n            var logger = new OutputLogger(Output);\n            var columns = new[]\n            {\n                StatisticColumn.StdDev,\n                StatisticColumn.Min,\n                StatisticColumn.Q1,\n                StatisticColumn.Median,\n                StatisticColumn.Q3,\n                StatisticColumn.Max,\n                StatisticColumn.OperationsPerSecond,\n                StatisticColumn.P85,\n                StatisticColumn.P95,\n                StatisticColumn.P95\n            };\n            var config = ManualConfig.CreateEmpty().AddJob(CreateJob()).AddLogger(logger).AddColumn(columns);\n            var summary = CanExecute<Benchmarks>(config);\n\n            var table = summary.Table;\n            var headerRow = table.FullHeader;\n            foreach (var column in columns)\n                Assert.Contains(column.ColumnName, headerRow);\n        }\n\n        private static Job CreateJob() =>\n            new Job(\"MainJob\", Job.Dry)\n            {\n                Run = { IterationCount = 10, IterationTime = TimeInterval.Millisecond * 10 }\n            };\n\n        public class Benchmarks\n        {\n            private readonly Random random = new Random(42);\n\n            [Benchmark]\n            public void Sleep5() => Thread.Sleep(5 + random.Next(5));\n\n            [Benchmark]\n            public void Sleep10() => Thread.Sleep(10 + random.Next(5));\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/TailCallDiagnoserTests.cs",
    "content": "﻿#if NETFRAMEWORK\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Columns;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Diagnostics.Windows;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Tests.Loggers;\nusing System.Collections.Generic;\nusing System.Linq;\nusing BenchmarkDotNet.IntegrationTests.Xunit;\nusing BenchmarkDotNet.Tests.XUnit;\nusing Xunit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.IntegrationTests\n{\n    public class TailCallDiagnoserTests : BenchmarkTestExecutor\n    {\n        private const string WindowsOnly = \"Use JIT ETW Tail Call Event (Windows only)\";\n        private const string TAIL_CALL_MARK = \"Tail call type\";\n\n        public TailCallDiagnoserTests(ITestOutputHelper outputHelper) : base(outputHelper)\n        {\n\n        }\n\n        public static IEnumerable<object[]> GetJits()\n            =>\n            [\n                [Jit.LegacyJit, Platform.X64, ClrRuntime.Net462], // 64bit LegacyJit for desktop .NET\n                [Jit.RyuJit, Platform.X64, ClrRuntime.Net462], // RyuJit for desktop .NET\n            ];\n\n        public class TailCallBenchmarks\n        {\n            private long FactorialWithTailing(int pos, int depth)\n                => pos == 0 ? depth : FactorialWithTailing(pos - 1, depth * pos);\n\n            private long FactorialWithTailing(int depth) => FactorialWithTailing(1, depth);\n\n            [Benchmark]\n            public long Factorial() => FactorialWithTailing(7);\n        }\n\n        public class NonTailCallBenchmarks\n        {\n            private long FactorialWithoutTailing(int depth) => depth == 0 ? 1 : depth * FactorialWithoutTailing(depth - 1);\n\n            [Benchmark]\n            public long Factorial() => FactorialWithoutTailing(7);\n        }\n\n        [TheoryEnvSpecific(WindowsOnly, EnvRequirement.WindowsOnly)]\n        [MemberData(nameof(GetJits), DisableDiscoveryEnumeration = true)]\n        [Trait(Constants.Category, Constants.BackwardCompatibilityCategory)]\n        public void TailCallDiagnoserCatchesTailCallEvents(Jit jit, Platform platform, Runtime runtime)\n        {\n            var output = Execute<TailCallBenchmarks>(jit, platform, runtime);\n\n            Assert.Contains(output.CapturedOutput, x => x.Text.Contains(TAIL_CALL_MARK));\n        }\n\n        [TheoryEnvSpecific(WindowsOnly, EnvRequirement.WindowsOnly)]\n        [MemberData(nameof(GetJits), DisableDiscoveryEnumeration = true)]\n        [Trait(Constants.Category, Constants.BackwardCompatibilityCategory)]\n        public void TailCallDiagnoserNotCatchesTailCallEvents(Jit jit, Platform platform, Runtime runtime)\n        {\n            var output = Execute<NonTailCallBenchmarks>(jit, platform, runtime);\n\n            Assert.DoesNotContain(output.CapturedOutput, x => x.Text.Contains(TAIL_CALL_MARK));\n        }\n\n        private LogCapture Execute<T>(Jit jit, Platform platform, Runtime runtime)\n        {\n            var tailCallDiagnoser = new TailCallDiagnoser(false, true);\n\n            CanExecute<T>(CreateConfig(jit, platform, runtime, tailCallDiagnoser));\n\n            return tailCallDiagnoser.Logger;\n        }\n\n        private IConfig CreateConfig(Jit jit, Platform platform, Runtime runtime, TailCallDiagnoser diagnoser) => ManualConfig.CreateEmpty()\n            .AddJob(Job.Dry.WithJit(jit).WithPlatform(platform).WithRuntime(runtime))\n            .AddLogger(DefaultConfig.Instance.GetLoggers().ToArray())\n            .AddColumnProvider(DefaultColumnProviders.Instance)\n            .AddDiagnoser(diagnoser)\n            .AddLogger(new OutputLogger(Output));\n    }\n}\n#endif\n"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/TestConfigs.cs",
    "content": "﻿using BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Jobs;\n\nnamespace BenchmarkDotNet.IntegrationTests\n{\n    public class SingleJobConfig : ManualConfig\n    {\n        public SingleJobConfig(Job job)\n        {\n            AddJob(job);\n        }\n    }\n\n    public class SingleRunFastConfig : ManualConfig\n    {\n        public SingleRunFastConfig()\n        {\n            AddJob(Job.Dry);\n        }\n    }\n\n    public class SingleRunMediumConfig : ManualConfig\n    {\n        public SingleRunMediumConfig()\n        {\n            AddJob(new Job(Job.Dry) { Run = { IterationCount = 5 } });\n        }\n    }\n\n    public class ThroughputFastConfig : ManualConfig\n    {\n        public ThroughputFastConfig()\n        {\n            AddJob(new Job(Job.Dry) { Run = { RunStrategy = RunStrategy.Throughput, IterationCount = 1 } });\n        }\n    }\n\n    public class DiagnoserConfig : ManualConfig\n    {\n        public DiagnoserConfig()\n        {\n            // Diagnosers need enough runs to collects the statistics!\n            AddJob(new Job { Run = { LaunchCount = 1, WarmupCount = 1, IterationCount = 50 } });\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/TestCultureInfo.cs",
    "content": "using System.Globalization;\nusing BenchmarkDotNet.Helpers;\n\nnamespace BenchmarkDotNet.IntegrationTests\n{\n    internal static class TestCultureInfo\n    {\n        public static readonly CultureInfo Instance;\n\n        static TestCultureInfo()\n        {\n            Instance = (CultureInfo) DefaultCultureInfo.Instance.Clone();\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/ThreadingDiagnoserTests.cs",
    "content": "#if !NETFRAMEWORK\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Columns;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Diagnosers;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Tests.Loggers;\nusing BenchmarkDotNet.Toolchains;\nusing BenchmarkDotNet.Toolchains.NativeAot;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading;\nusing BenchmarkDotNet.Detectors;\nusing BenchmarkDotNet.IntegrationTests.Xunit;\nusing BenchmarkDotNet.Portability;\nusing Xunit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.IntegrationTests\n{\n    public class ThreadingDiagnoserTests\n    {\n        private readonly ITestOutputHelper output;\n\n        public ThreadingDiagnoserTests(ITestOutputHelper outputHelper) => output = outputHelper;\n\n        public static IEnumerable<object[]> GetToolchains()\n        {\n            yield return new object[] { Job.Default.GetToolchain() };\n\n            if (!ContinuousIntegration.IsGitHubActionsOnWindows() // no native dependencies\n                && !OsDetector.IsMacOS()) // currently not supported\n            {\n                yield return new object[] { NativeAotToolchain.Net80 };\n            }\n            // TODO: Support InProcessEmitToolchain.Instance\n            // yield return new object[] { InProcessEmitToolchain.Instance };\n        }\n\n        [Theory, MemberData(nameof(GetToolchains), DisableDiscoveryEnumeration = true)]\n        public void CompletedWorkItemCountIsAccurate(IToolchain toolchain)\n        {\n            var config = CreateConfig(toolchain);\n\n            var summary = BenchmarkRunner.Run<CompletedWorkItemCount>(config);\n            try\n            {\n                summary.CheckPlatformLinkerIssues();\n            }\n            catch (MisconfiguredEnvironmentException e)\n            {\n                if (ContinuousIntegration.IsLocalRun())\n                {\n                    output.WriteLine(e.SkipMessage);\n                    return;\n                }\n                throw;\n            }\n\n            AssertStats(summary, new Dictionary<string, (string metricName, double expectedValue)>\n            {\n                { nameof(CompletedWorkItemCount.DoNothing), (\"CompletedWorkItemCount\", 0.0) },\n                { nameof(CompletedWorkItemCount.CompleteOneWorkItem), (\"CompletedWorkItemCount\", 1.0) }\n            });\n        }\n\n        public class CompletedWorkItemCount\n        {\n            [Benchmark]\n            public void CompleteOneWorkItem()\n            {\n                ManualResetEvent done = new ManualResetEvent(false);\n                ThreadPool.QueueUserWorkItem(m => (m as ManualResetEvent)!.Set(), done);\n                done.WaitOne();\n            }\n\n            [Benchmark]\n            public void DoNothing() { }\n        }\n\n        [Theory, MemberData(nameof(GetToolchains), DisableDiscoveryEnumeration = true)]\n        public void LockContentionCountIsAccurate(IToolchain toolchain)\n        {\n            var config = CreateConfig(toolchain);\n\n            var summary = BenchmarkRunner.Run<LockContentionCount>(config);\n            try\n            {\n                summary.CheckPlatformLinkerIssues();\n            }\n            catch (MisconfiguredEnvironmentException e)\n            {\n                if (ContinuousIntegration.IsLocalRun())\n                {\n                    output.WriteLine(e.SkipMessage);\n                    return;\n                }\n                throw;\n            }\n\n            AssertStats(summary, new Dictionary<string, (string metricName, double expectedValue)>\n            {\n                { nameof(LockContentionCount.DoNothing), (\"LockContentionCount\", 0.0) },\n                { nameof(LockContentionCount.RunIntoLockContention), (\"LockContentionCount\", 1.0) }\n            });\n        }\n\n        public class LockContentionCount\n        {\n            private readonly object guard = new object();\n\n            private ManualResetEvent lockTaken = default!;\n            private ManualResetEvent failedToAcquire = default!;\n\n            [Benchmark]\n            public void DoNothing() { }\n\n            [Benchmark]\n            public void RunIntoLockContention()\n            {\n                lockTaken = new ManualResetEvent(false);\n                failedToAcquire = new ManualResetEvent(false);\n\n                Thread first = new Thread(FirstThread);\n                Thread second = new Thread(SecondThread);\n\n                first.Start();\n                second.Start();\n\n                second.Join();\n                first.Join();\n            }\n\n            private void FirstThread()\n            {\n                Monitor.Enter(guard);\n                lockTaken.Set();\n\n                failedToAcquire.WaitOne();\n                Monitor.Exit(guard);\n            }\n\n            private void SecondThread()\n            {\n                lockTaken.WaitOne();\n\n                bool taken = Monitor.TryEnter(guard, TimeSpan.FromMilliseconds(10));\n\n                if (taken)\n                {\n                    throw new InvalidOperationException(\"Impossible!\");\n                }\n\n                failedToAcquire.Set();\n            }\n        }\n\n        private IConfig CreateConfig(IToolchain toolchain)\n#pragma warning disable CS0618 // WithEvaluateOverhead is obsolete\n            => ManualConfig.CreateEmpty()\n                .AddJob(Job.ShortRun\n                    .WithEvaluateOverhead(false) // no need to run idle for this test\n                    .WithWarmupCount(0) // don't run warmup to save some time for our CI runs\n                    .WithIterationCount(1) // single iteration is enough for us\n                    .WithGcForce(false)\n                    .WithToolchain(toolchain))\n                .AddColumnProvider(DefaultColumnProviders.Instance)\n                .AddDiagnoser(ThreadingDiagnoser.Default)\n                .AddLogger(toolchain.IsInProcess\n                    ? ConsoleLogger.Default\n                    : new OutputLogger(output)); // we can't use OutputLogger for the InProcess toolchains because it allocates memory on the same thread\n#pragma warning restore CS0618 // WithEvaluateOverhead is obsolete\n\n        private void AssertStats(Summary summary, Dictionary<string, (string metricName, double expectedValue)> assertions)\n        {\n            foreach (var assertion in assertions)\n            {\n                var selectedReport = summary.Reports.Single(report => report.BenchmarkCase.DisplayInfo.Contains(assertion.Key));\n\n                var metric = selectedReport.Metrics.Single(m => m.Key == assertion.Value.metricName);\n\n                // precision is set to 2 because CoreCLR might schedule some work item on it's own and hence affect the results..\n                // precision = 3 is not enough (e.g., sometimes the actual value may be equal 1.0009765625 while the expected value is 1.0)\n                Assert.Equal(assertion.Value.expectedValue, metric.Value.Value, precision: 2);\n            }\n        }\n    }\n}\n#endif"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/ToolchainTest.cs",
    "content": "﻿using System;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Tests.Loggers;\nusing BenchmarkDotNet.Toolchains;\nusing BenchmarkDotNet.Toolchains.Parameters;\nusing BenchmarkDotNet.Toolchains.Results;\nusing Xunit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.IntegrationTests\n{\n    public class ToolchainTest : BenchmarkTestExecutor\n    {\n        public ToolchainTest(ITestOutputHelper output) : base(output) { }\n\n        private class MyGenerator : IGenerator\n        {\n            public bool Done { get; private set; }\n\n            public GenerateResult GenerateProject(BuildPartition buildPartition, ILogger logger, string rootArtifactsFolderPath)\n            {\n                logger.WriteLine(\"Generating\");\n                Done = true;\n                return new GenerateResult(ArtifactsPaths.Empty, true, null, []);\n            }\n        }\n\n        private class MyBuilder : IBuilder\n        {\n            public bool Done { get; private set; }\n\n            public BuildResult Build(GenerateResult generateResult, BuildPartition buildPartition, ILogger logger)\n            {\n                logger.WriteLine(\"Building\");\n                Done = true;\n                return BuildResult.Success(generateResult);\n            }\n        }\n\n        private class MyExecutor : IExecutor\n        {\n            public bool Done { get; private set; }\n\n            public ExecuteResult Execute(ExecuteParameters executeParameters)\n            {\n                executeParameters.Logger.WriteLine(\"Executing\");\n                Done = true;\n                return new ExecuteResult(true, 0, default, [], [], [], executeParameters.LaunchIndex);\n            }\n        }\n\n        public class ToolchainBenchmark\n        {\n            [Benchmark]\n            public void Benchmark()\n            {\n            }\n        }\n\n        [Fact]\n        public void CustomToolchainsAreSupported()\n        {\n            var logger = new OutputLogger(Output);\n\n            var generator = new MyGenerator();\n            var builder = new MyBuilder();\n            var executor = new MyExecutor();\n            var myToolchain = new Toolchain(\"My\", generator, builder, executor);\n            var job = new Job(Job.Dry) { Infrastructure = { Toolchain = myToolchain} };\n            var config = CreateSimpleConfig(logger).AddJob(job);\n\n            CanExecute<ToolchainBenchmark>(config, fullValidation: false);\n\n            Assert.True(generator.Done);\n            Assert.True(builder.Done);\n            Assert.True(executor.Done);\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/ValidatorsTest.cs",
    "content": "﻿using System.Collections.Generic;\nusing BenchmarkDotNet.Validators;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Exporters;\nusing BenchmarkDotNet.Exporters.Csv;\nusing BenchmarkDotNet.Loggers;\nusing Xunit;\nusing Xunit.Abstractions;\nusing BenchmarkDotNet.Exporters.Json;\nusing BenchmarkDotNet.Exporters.OpenMetrics;\nusing BenchmarkDotNet.Exporters.Xml;\n\nnamespace BenchmarkDotNet.IntegrationTests\n{\n    public class ValidatorsTest : BenchmarkTestExecutor\n    {\n        public ValidatorsTest(ITestOutputHelper output) : base(output) { }\n\n        private readonly IExporter[] AllKnownExportersThatSupportExportToLog =\n            [\n                MarkdownExporter.Atlassian,\n                MarkdownExporter.Console,\n                MarkdownExporter.Default,\n                MarkdownExporter.GitHub,\n                MarkdownExporter.StackOverflow,\n                OpenMetricsExporter.Default,\n                CsvExporter.Default,\n                CsvMeasurementsExporter.Default,\n                HtmlExporter.Default,\n                PlainExporter.Default,\n                JsonExporter.Default,\n                XmlExporter.Default\n            ];\n\n        [Fact]\n        public void BenchmarkRunnerShouldNotFailOnCriticalValidationErrors()\n        {\n            CanExecute<Nothing>(\n                CreateSimpleConfig()\n                        .AddValidator(new FailingValidator())\n                        .AddExporter(AllKnownExportersThatSupportExportToLog),\n                fullValidation: false);\n        }\n\n        [Fact]\n        public void LoggersShouldNotFailOnCriticalValidationErrors()\n        {\n            var summary = CanExecute<Nothing>(CreateSimpleConfig().AddValidator(new FailingValidator()), fullValidation: false);\n\n            foreach (var exporter in AllKnownExportersThatSupportExportToLog)\n            {\n                exporter.ExportToLog(summary, new AccumulationLogger());\n            }\n        }\n\n        private class FailingValidator : IValidator\n        {\n            public bool TreatsWarningsAsErrors => true;\n\n            public IEnumerable<ValidationError> Validate(ValidationParameters input)\n            {\n                yield return new ValidationError(true, \"It just fails\");\n            }\n        }\n\n        public class Nothing\n        {\n            [Benchmark]\n            public void DoNothing() { }\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/ValuesReturnedByBenchmarkTest.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Collections.Immutable;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Toolchains;\nusing BenchmarkDotNet.Toolchains.InProcess.Emit;\nusing Xunit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.IntegrationTests\n{\n    public class ValuesReturnedByBenchmarkTest : BenchmarkTestExecutor\n    {\n        public ValuesReturnedByBenchmarkTest(ITestOutputHelper output) : base(output) { }\n\n        public static IEnumerable<object[]> GetToolchains() =>\n        [\n            [Job.Default.GetToolchain()],\n            [InProcessEmitToolchain.Default],\n        ];\n\n        [Theory, MemberData(nameof(GetToolchains), DisableDiscoveryEnumeration = true)]\n        public void AnyValueCanBeReturned(IToolchain toolchain) => CanExecute<ValuesReturnedByBenchmark>(ManualConfig.CreateEmpty().AddJob(Job.Dry.WithToolchain(toolchain)));\n\n        public class ValuesReturnedByBenchmark\n        {\n#if NETFRAMEWORK\n            [Benchmark]\n            public System.Windows.Point? TypeFromCustomFrameworkAssembly() => new System.Windows.Point();\n\n            [Benchmark]\n            public Diagnostics.Windows.InliningDiagnoser TypeFromCustomDependency() => new Diagnostics.Windows.InliningDiagnoser();\n#endif\n\n            [Benchmark]\n            public object? ReturnNullForReferenceType() => null;\n\n            [Benchmark]\n            public object ReturnNotNullForReferenceType() => new object();\n\n            [Benchmark]\n            public DateTime? ReturnNullForNullableType() => null;\n\n            [Benchmark]\n            public DateTime? ReturnNotNullForNullableType() => DateTime.UtcNow;\n\n            [Benchmark]\n            public DateTime ReturnDefaultValueForValueType() => default;\n\n            [Benchmark]\n            public DateTime ReturnNonDefaultValueForValueType() => DateTime.UtcNow;\n\n            [Benchmark]\n            public Result<DateTime> ReturnGenericValueType() => new Result<DateTime>();\n\n            [Benchmark]\n            public Jit ReturnEnum() => Jit.RyuJit;\n\n            private int intergerField = 123;\n            [Benchmark]\n            public ref int ReturnByRef() => ref intergerField;\n\n            [Benchmark]\n            public ref readonly int ReturnByReadonlyRef() => ref intergerField;\n\n            public readonly struct ReadOnlyStruct { }\n            private ReadOnlyStruct readOnlyStructField;\n\n            [Benchmark]\n            public ReadOnlyStruct ReturnReadOnlyStruct() => new ReadOnlyStruct();\n\n            [Benchmark]\n            public ref ReadOnlyStruct ReturnReadOnlyStructByRef() => ref readOnlyStructField;\n\n            [Benchmark]\n            public ref readonly ReadOnlyStruct ReturnReadOnlyStructByReadonlyRef() => ref readOnlyStructField;\n\n            [Benchmark]\n            public Span<byte> ReturnStackOnlyType() => new Span<byte>([]);\n\n            [Benchmark]\n            public ImmutableArray<int> TypeFromNetStandardNuGetPackage() => [];\n\n            [Benchmark]\n            public ValueTuple<int> TypeInTwoDlls() => new ValueTuple<int>();\n\n            public struct Result<T>\n            {\n                public T Field;\n\n                public Result(T field)\n                {\n                    Field = field;\n                }\n            }\n\n            [Benchmark]\n            public Job TypeCalledJob() => new Job();\n\n            public class Job { }\n\n            [Benchmark]\n            public NoNamespace TypeWithoutNamespace() => new NoNamespace();\n\n            [Benchmark]\n            public unsafe void* PointerToAnything() => System.IntPtr.Zero.ToPointer();\n\n            [Benchmark]\n            public unsafe int* PointerToUnmanagedType() => (int*)System.IntPtr.Zero.ToPointer();\n\n            [Benchmark]\n            public System.IntPtr IntPtr() => System.IntPtr.Zero;\n\n            [Benchmark]\n            public System.UIntPtr UIntPtr() => System.UIntPtr.Zero;\n\n            [Benchmark]\n            public nint NativeSizeInteger() => 0;\n\n            [Benchmark]\n            public nuint UnsignedNativeSizeInteger() => 0;\n\n            [Benchmark]\n            public Tuple<Outer, Outer.Inner> BenchmarkInnerClass() => Tuple.Create(new Outer(), new Outer.Inner());\n\n            [Benchmark]\n            public Tuple<Outer, Outer.InnerGeneric<string>> BenchmarkGenericInnerClass() => Tuple.Create(new Outer(), new Outer.InnerGeneric<string>());\n        }\n\n        public class Outer\n        {\n            public class Inner\n            {\n            }\n\n            public class InnerGeneric<T>\n            {\n            }\n        }\n    }\n}\n\npublic class NoNamespace\n{\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/WakeLockTests.cs",
    "content": "﻿using BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Helpers;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Tests.Loggers;\nusing BenchmarkDotNet.Tests.XUnit;\nusing System;\nusing System.Diagnostics;\nusing System.IO;\nusing System.Linq;\nusing System.Runtime.Versioning;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Xunit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.IntegrationTests;\n\npublic class WakeLockTests : BenchmarkTestExecutor\n{\n    private const string PingEventName = @\"Global\\WakeLockTests-ping\";\n    private const string PongEventName = @\"Global\\WakeLockTests-pong\";\n    private static readonly TimeSpan testTimeout = TimeSpan.FromMinutes(1);\n    private readonly OutputLogger logger;\n\n    public WakeLockTests(ITestOutputHelper output) : base(output)\n    {\n        logger = new OutputLogger(Output);\n    }\n\n    [Fact]\n    public void ConfigurationDefaultValue()\n    {\n        Assert.Equal(WakeLockType.System, DefaultConfig.Instance.WakeLock);\n        Assert.Equal(WakeLockType.None, new DebugBuildConfig().WakeLock);\n        Assert.Equal(WakeLockType.None, new DebugInProcessConfig().WakeLock);\n    }\n\n    [TheoryEnvSpecific(EnvRequirement.NonWindows)]\n    [InlineData(WakeLockType.None)]\n    [InlineData(WakeLockType.System)]\n    [InlineData(WakeLockType.Display)]\n    public void WakeLockIsWindowsOnly(WakeLockType wakeLockType)\n    {\n        using var wakeLock = WakeLock.Request(wakeLockType, \"dummy\", logger);\n        Assert.Null(wakeLock);\n    }\n\n    [FactEnvSpecific(EnvRequirement.WindowsOnly)]\n    public void WakeLockSleepOrDisplayIsAllowed()\n    {\n        using var wakeLock = WakeLock.Request(WakeLockType.None, \"dummy\", logger);\n        Assert.Null(wakeLock);\n    }\n\n    [FactEnvSpecific(EnvRequirement.WindowsOnly, EnvRequirement.NeedsPrivilegedProcess)]\n    public void WakeLockRequireSystem()\n    {\n        using (var wakeLock = WakeLock.Request(WakeLockType.System, \"WakeLockTests\", logger))\n        {\n            Assert.NotNull(wakeLock);\n            Assert.Equal(\"SYSTEM\", GetPowerRequests(\"WakeLockTests\"));\n        }\n        Assert.Equal(\"\", GetPowerRequests());\n    }\n\n    [FactEnvSpecific(EnvRequirement.WindowsOnly, EnvRequirement.NeedsPrivilegedProcess)]\n    public void WakeLockRequireDisplay()\n    {\n        using (var wakeLock = WakeLock.Request(WakeLockType.Display, \"WakeLockTests\", logger))\n        {\n            Assert.NotNull(wakeLock);\n            Assert.Equal(\"DISPLAY, SYSTEM\", GetPowerRequests(\"WakeLockTests\"));\n        }\n        Assert.Equal(\"\", GetPowerRequests());\n    }\n\n    [FactEnvSpecific(EnvRequirement.NonWindows)]\n    public void BenchmarkRunnerIgnoresWakeLock() =>\n        _ = CanExecute<IgnoreWakeLock>(fullValidation: false);\n\n    [WakeLock(WakeLockType.Display)]\n    public class IgnoreWakeLock\n    {\n        [Benchmark] public void Sleep() { }\n    }\n\n    [SupportedOSPlatform(\"windows\")]\n    [TheoryEnvSpecific(EnvRequirement.WindowsOnly, EnvRequirement.NeedsPrivilegedProcess)]\n    [InlineData(typeof(Default), \"SYSTEM\")]\n    [InlineData(typeof(None), \"\")]\n    [InlineData(typeof(RequireSystem), \"SYSTEM\")]\n    [InlineData(typeof(RequireDisplay), \"DISPLAY, SYSTEM\")]\n    public async Task BenchmarkRunnerAcquiresWakeLock(Type type, string expected)\n    {\n        using EventWaitHandle\n            ping = new EventWaitHandle(false, EventResetMode.AutoReset, PingEventName),\n            pong = new EventWaitHandle(false, EventResetMode.AutoReset, PongEventName);\n        string? pwrRequests = null;\n        Task task = WaitForBenchmarkRunningAndGetPowerRequests();\n        _ = CanExecute(type, fullValidation: false);\n        await task;\n\n        Assert.Equal(expected, pwrRequests);\n\n        async Task WaitForBenchmarkRunningAndGetPowerRequests()\n        {\n            await AsTask(ping, testTimeout);\n            pwrRequests = GetPowerRequests(\"BenchmarkDotNet Running Benchmarks\");\n            pong.Set();\n        }\n    }\n\n    public class Default : Base { }\n\n    [WakeLock(WakeLockType.None)] public class None : Base { }\n\n    [WakeLock(WakeLockType.System)] public class RequireSystem : Base { }\n\n    [WakeLock(WakeLockType.Display)] public class RequireDisplay : Base { }\n\n    public class Base\n    {\n        [Benchmark]\n        [SupportedOSPlatform(\"windows\")]\n        public void SignalBenchmarkRunningAndWaitForGetPowerRequests()\n        {\n            using EventWaitHandle\n                ping = EventWaitHandle.OpenExisting(PingEventName),\n                pong = EventWaitHandle.OpenExisting(PongEventName);\n            ping.Set();\n            pong.WaitOne(testTimeout);\n        }\n    }\n\n    private string GetPowerRequests(string? expectedReason = null)\n    {\n        string pwrRequests = ProcessHelper.RunAndReadOutput(\"powercfg\", \"/requests\")!;\n        Output.WriteLine(pwrRequests); // Useful to analyse failing tests.\n        string fileName = Process.GetCurrentProcess()!.MainModule!.FileName;\n        string mustEndWith = fileName.Substring(Path.GetPathRoot(fileName)!.Length);\n\n        return string.Join(\", \",\n            from pr in PowerRequestsParser.Parse(pwrRequests)\n            where\n                pr.RequesterName.EndsWith(mustEndWith, StringComparison.InvariantCulture) &&\n                string.Equals(pr.RequesterType, \"PROCESS\", StringComparison.InvariantCulture) &&\n                (expectedReason == null || string.Equals(pr.Reason, expectedReason, StringComparison.InvariantCulture))\n            select pr.RequestType);\n    }\n\n    private Task AsTask(WaitHandle waitHandle, TimeSpan timeout)\n    {\n        TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();\n        RegisteredWaitHandle? rwh = null;\n        rwh = ThreadPool.RegisterWaitForSingleObject(\n            waitHandle,\n            (object? state, bool timedOut) =>\n            {\n                rwh?.Unregister(null);\n                if (timedOut)\n                {\n                    tcs.SetException(new TimeoutException());\n                }\n                else\n                {\n                    tcs.SetResult(true);\n                }\n            },\n            null,\n            timeout,\n            true);\n        return tcs.Task;\n    }\n}\n"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/WasmTests.cs",
    "content": "﻿using System;\nusing System.IO;\nusing System.Linq;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.IntegrationTests.Diagnosers;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Portability;\nusing BenchmarkDotNet.Tests.Loggers;\nusing BenchmarkDotNet.Tests.XUnit;\nusing BenchmarkDotNet.Toolchains.DotNetCli;\nusing BenchmarkDotNet.Toolchains.MonoAotLLVM;\nusing BenchmarkDotNet.Toolchains.MonoWasm;\nusing Xunit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.IntegrationTests\n{\n    /// <summary>\n    /// In order to run WasmTests locally, the following prerequisites are required:\n    /// * Install wasm-tools workload: `BenchmarkDotNet/build.cmd install-wasm-tools`\n    /// * Install npm\n    /// * Install v8: `npm install jsvu -g && jsvu --os=default --engines=v8`\n    /// * Add `$HOME/.jsvu/bin` to PATH\n    /// * Run tests using .NET SDK from `BenchmarkDotNet/.dotnet/`\n    /// </summary>\n    public class WasmTests(ITestOutputHelper output) : BenchmarkTestExecutor(output)\n    {\n        private const string JsvuSkipReason = \"JSVU does not support ARM on Windows or Linux\";\n\n        [TheoryEnvSpecific(JsvuSkipReason, EnvRequirement.NonWindowsArm, EnvRequirement.NonLinuxArm)]\n        [InlineData(MonoAotCompilerMode.mini)]\n        // BUG: https://github.com/dotnet/BenchmarkDotNet/issues/3036\n        [InlineData(MonoAotCompilerMode.wasm, Skip = \"AOT is broken\")]\n        public void WasmIsSupported(MonoAotCompilerMode aotCompilerMode)\n        {\n            CanExecute<WasmBenchmark>(GetConfig(aotCompilerMode));\n        }\n\n        [TheoryEnvSpecific(JsvuSkipReason, EnvRequirement.NonWindowsArm, EnvRequirement.NonLinuxArm)]\n        [InlineData(MonoAotCompilerMode.mini)]\n        // BUG: https://github.com/dotnet/BenchmarkDotNet/issues/3036\n        [InlineData(MonoAotCompilerMode.wasm, Skip = \"AOT is broken\")]\n        public void WasmSupportsInProcessDiagnosers(MonoAotCompilerMode aotCompilerMode)\n        {\n            try\n            {\n                var diagnoser = new MockInProcessDiagnoser1(BenchmarkDotNet.Diagnosers.RunMode.NoOverhead);\n                var config = GetConfig(aotCompilerMode).AddDiagnoser(diagnoser);\n\n                CanExecute<WasmBenchmark>(config);\n\n                Assert.Equal([diagnoser.ExpectedResult], diagnoser.Results.Values);\n                Assert.Equal([diagnoser.ExpectedResult], BaseMockInProcessDiagnoser.s_completedResults.Select(t => t.result));\n            }\n            finally\n            {\n                BaseMockInProcessDiagnoser.s_completedResults.Clear();\n            }\n        }\n\n        [FactEnvSpecific(JsvuSkipReason, EnvRequirement.NonWindowsArm, EnvRequirement.NonLinuxArm)]\n        public void WasmSupportsCustomMainJs()\n        {\n            var summary = CanExecute<WasmBenchmark>(GetConfig(MonoAotCompilerMode.mini, true, true));\n\n            var artefactsPaths = summary.Reports.Single().GenerateResult.ArtifactsPaths;\n            Assert.Contains(\"custom-template-identifier\", File.ReadAllText(artefactsPaths.ExecutablePath));\n\n            Directory.Delete(Path.GetDirectoryName(artefactsPaths.ProjectFilePath)!, true);\n        }\n\n        [FactEnvSpecific(JsvuSkipReason, EnvRequirement.NonWindowsArm, EnvRequirement.NonLinuxArm)]\n        public void WasmSupportsNode()\n        {\n            CanExecute<WasmBenchmark>(GetConfig(MonoAotCompilerMode.mini, javaScriptEngine: \"node\"));\n        }\n\n        private ManualConfig GetConfig(MonoAotCompilerMode aotCompilerMode, bool useMainJsTemplate = false, bool keepBenchmarkFiles = false, string javaScriptEngine = \"v8\")\n        {\n            var dotnetVersion = \"net8.0\";\n            var logger = new OutputLogger(Output);\n            var netCoreAppSettings = new NetCoreAppSettings(dotnetVersion, runtimeFrameworkVersion: null!, \"Wasm\", aotCompilerMode: aotCompilerMode);\n\n            var mainJsTemplate = useMainJsTemplate ? new FileInfo(Path.Combine(\"wwwroot\", \"custom-main.mjs\")) : null;\n\n            return ManualConfig.CreateEmpty()\n                .AddLogger(logger)\n                .AddJob(Job.Dry\n                    .WithRuntime(new WasmRuntime(dotnetVersion, RuntimeMoniker.WasmNet80, \"wasm\", aotCompilerMode == MonoAotCompilerMode.wasm, javaScriptEngine, mainJsTemplate: mainJsTemplate))\n                    .WithToolchain(WasmToolchain.From(netCoreAppSettings)))\n                .WithBuildTimeout(TimeSpan.FromSeconds(240))\n                .WithOption(ConfigOptions.KeepBenchmarkFiles, keepBenchmarkFiles)\n                .WithOption(ConfigOptions.LogBuildOutput, true)\n                .WithOption(ConfigOptions.GenerateMSBuildBinLog, false);\n        }\n\n        public class WasmBenchmark\n        {\n            [Benchmark]\n            public void Check()\n            {\n                if (!RuntimeInformation.IsWasm)\n                {\n                    throw new Exception(\"Incorrect runtime detection\");\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/Xunit/Constants.cs",
    "content": "﻿namespace BenchmarkDotNet.IntegrationTests.Xunit\n{\n    public class Constants\n    {\n        public const string Category = \"Category\";\n        public const string BackwardCompatibilityCategory = \"BackwardCompatibility\";\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/Xunit/Extensions.cs",
    "content": "﻿using System.Linq;\nusing BenchmarkDotNet.Reports;\n\nnamespace BenchmarkDotNet.IntegrationTests.Xunit\n{\n    public static class Extensions\n    {\n        public static void CheckPlatformLinkerIssues(this Summary summary)\n        {\n            if (summary.Reports.Any(r =>\n                    !r.BuildResult.IsBuildSuccess &&\n                    r.BuildResult.ErrorMessage.Contains(\"Platform linker not found\")))\n                throw new MisconfiguredEnvironmentException(\"Failed to build benchmarks because the platform linker not found\");\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/Xunit/MisconfiguredEnvironmentException.cs",
    "content": "﻿using System;\n\nnamespace BenchmarkDotNet.IntegrationTests.Xunit\n{\n    public class MisconfiguredEnvironmentException : Exception\n    {\n        public MisconfiguredEnvironmentException(string message) : base(message) { }\n\n        public string SkipMessage => $\"Skip this test because the environment is misconfigured ({Message})\";\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/runtimeconfig.template.json",
    "content": "﻿{\n  \"runtimeOptions\": {\n    \"configProperties\": {\n      \"System.Runtime.TieredCompilation\": false\n    }\n  }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/wwwroot/custom-main.mjs",
    "content": "// Licensed to the .NET Foundation under one or more agreements.\n// The .NET Foundation licenses this file to you under the MIT license.\n\n// custom-template-identifier\n\nimport { dotnet } from './_framework/dotnet.js'\n\nawait dotnet\n    .withDiagnosticTracing(false)\n    .withApplicationArguments(...arguments)\n    .run()\n"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests/xunit.runner.json",
    "content": "﻿{\n  \"shadowCopy\": false,\n  \"methodDisplay\": \"method\",\n  \"diagnosticMessages\": true,\n  \"longRunningTestSeconds\": 60,\n  \"parallelizeAssembly\": false,\n  \"parallelizeTestCollections\": false\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests.ConfigPerAssembly/AssemblyConfigAttribute.cs",
    "content": "using System;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Loggers;\n\nnamespace BenchmarkDotNet.IntegrationTests.ConfigPerAssembly\n{\n    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Assembly)]\n    public class AssemblyConfigAttribute : Attribute, IConfigSource\n    {\n        public IConfig Config { get; }\n\n        public static bool IsActivated;\n\n        public AssemblyConfigAttribute()\n        {\n            Config = ManualConfig.CreateEmpty().AddLogger(new Logger());\n        }\n\n        private class Logger : ILogger\n        {\n            public string Id => \"TestLogger\";\n            public int Priority => 0;\n\n            public void Write(LogKind logKind, string text)\n            {\n                IsActivated = true;\n            }\n\n            public void WriteLine()\n            {\n                IsActivated = true;\n            }\n\n            public void WriteLine(LogKind logKind, string text)\n            {\n                IsActivated = true;\n            }\n\n            public void Flush() { }\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests.ConfigPerAssembly/AssemblyConfigBenchmarks.cs",
    "content": "using BenchmarkDotNet.Attributes;\n\nnamespace BenchmarkDotNet.IntegrationTests.ConfigPerAssembly\n{\n    [DryJob]\n    public class AssemblyConfigBenchmarks\n    {\n        [Benchmark]\n        public void Foo()\n        {\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests.ConfigPerAssembly/BenchmarkDotNet.IntegrationTests.ConfigPerAssembly.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\n  <Import Project=\"..\\..\\build\\common.props\" />\n  <PropertyGroup>\n    <AssemblyTitle>BenchmarkDotNet.IntegrationTests.ConfigPerAssembly</AssemblyTitle>\n    <TargetFrameworks>net462;net8.0</TargetFrameworks>\n    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>\n    <AssemblyName>BenchmarkDotNet.IntegrationTests.ConfigPerAssembly</AssemblyName>\n    <PackageId>BenchmarkDotNet.IntegrationTests.ConfigPerAssembly</PackageId>\n    <GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>\n    <GenerateDocumentationFile>false</GenerateDocumentationFile>\n    <PlatformTarget>AnyCPU</PlatformTarget>\n  </PropertyGroup>\n  <ItemGroup>\n    <ProjectReference Include=\"..\\..\\src\\BenchmarkDotNet\\BenchmarkDotNet.csproj\" />\n  </ItemGroup>\n  <ItemGroup Condition=\" '$(TargetFrameworkIdentifier)' == '.NETFramework' \">\n    <PackageReference Include=\"Microsoft.NETCore.Platforms\" Version=\"7.0.4\" />\n    <Reference Include=\"System.Runtime\" />\n  </ItemGroup>\n  <Import Project=\"..\\..\\build\\common.targets\" />\n</Project>"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests.ConfigPerAssembly/Properties/AssemblyInfo.cs",
    "content": "﻿using BenchmarkDotNet.IntegrationTests.ConfigPerAssembly;\n\n[assembly: AssemblyConfig]\n"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests.CustomPaths/BenchmarkDotNet.IntegrationTests.CustomPaths.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\n  <Import Project=\"..\\..\\build\\common.props\" />\n  <PropertyGroup>\n    <AssemblyTitle>BenchmarkDotNet.IntegrationTests.CustomPaths</AssemblyTitle>\n    <TargetFramework>net462</TargetFramework>\n    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>\n    <AssemblyName>BenchmarkDotNet.IntegrationTests.CustomPaths</AssemblyName>\n    <PackageId>BenchmarkDotNet.IntegrationTests.CustomPaths</PackageId>\n    <GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>\n    <GenerateDocumentationFile>false</GenerateDocumentationFile>\n    <PlatformTarget>AnyCPU</PlatformTarget>\n  </PropertyGroup>\n  <ItemGroup>\n    <ProjectReference Include=\"..\\..\\src\\BenchmarkDotNet\\BenchmarkDotNet.csproj\" />\n  </ItemGroup>\n  <ItemGroup Condition=\" '$(TargetFrameworkIdentifier)' == '.NETFramework' \">\n    <PackageReference Include=\"Microsoft.NETCore.Platforms\" Version=\"7.0.4\" />\n    <Reference Include=\"System.Runtime\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <Content Include=\"ShouldGetCopied.xml\">\n      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\n    </Content>\n  </ItemGroup>\n\n  <ItemGroup>\n    <Reference Include=\"VerySimple\">\n      <HintPath>customPath\\VerySimple.dll</HintPath>\n    </Reference>\n  </ItemGroup>\n  <Import Project=\"..\\..\\build\\common.targets\" />\n</Project>"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests.CustomPaths/BenchmarksThatReturnTypeFromCustomPathDll.cs",
    "content": "﻿using BenchmarkDotNet.Attributes;\nusing VerySimple;\n\nnamespace BenchmarkDotNet.IntegrationTests.CustomPaths\n{\n    public class BenchmarksThatReturnTypeFromCustomPathDll\n    {\n        [Benchmark]\n        public SingleClass Benchmark() => new SingleClass();\n    }\n}\n"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests.CustomPaths/BenchmarksThatUseTypeFromCustomPathDll.cs",
    "content": "﻿using BenchmarkDotNet.Attributes;\nusing VerySimple;\n\nnamespace BenchmarkDotNet.IntegrationTests.CustomPaths\n{\n    public class BenchmarksThatUseTypeFromCustomPathDll\n    {\n        [Benchmark]\n        public string Benchmark() => new SingleClass().ToString();\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests.CustomPaths/BenchmarksThatUsesFileFromOutput.cs",
    "content": "﻿using System;\nusing System.IO;\nusing BenchmarkDotNet.Attributes;\n\nnamespace BenchmarkDotNet.IntegrationTests.CustomPaths\n{\n    public class BenchmarksThatUsesFileFromOutput\n    {\n        [Benchmark]\n        public void Verify()\n        {\n            if (!File.Exists(Path.Combine(Directory.GetCurrentDirectory(), \"ShouldGetCopied.xml\")))\n            {\n                throw new InvalidOperationException(\"the file did not get copied\");\n            }\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests.CustomPaths/Properties/AssemblyInfo.cs",
    "content": "﻿using System.Runtime.InteropServices;\n\n[assembly: Guid(\"0031728e-a5d4-47c1-9c1a-6c859a765c9d\")]\n"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests.CustomPaths/ShouldGetCopied.xml",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\" ?> \n<!-- this file should get copied to output, https://github.com/dotnet/BenchmarkDotNet/issues/212 -->\n<bugfix />"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests.DisabledOptimizations/BenchmarkDotNet.IntegrationTests.DisabledOptimizations.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n  <Import Project=\"..\\..\\build\\common.props\" />\n  <PropertyGroup>\n    <AssemblyTitle>BenchmarkDotNet.IntegrationTests.DisabledOptimizations</AssemblyTitle>\n    <TargetFrameworks>net462;net8.0</TargetFrameworks>\n    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>\n    <AssemblyName>BenchmarkDotNet.IntegrationTests.DisabledOptimizations</AssemblyName>\n    <PackageId>BenchmarkDotNet.IntegrationTests.DisabledOptimizations</PackageId>\n    <GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>\n    <GenerateDocumentationFile>false</GenerateDocumentationFile>\n    <PlatformTarget>AnyCPU</PlatformTarget>\n    \n    <Optimize>false</Optimize>\n  </PropertyGroup>\n  <ItemGroup>\n    <ProjectReference Include=\"..\\..\\src\\BenchmarkDotNet\\BenchmarkDotNet.csproj\" />\n  </ItemGroup>\n  <ItemGroup Condition=\" '$(TargetFrameworkIdentifier)' == '.NETFramework' \">\n    <PackageReference Include=\"Microsoft.NETCore.Platforms\" Version=\"7.0.4\" />\n    <Reference Include=\"System.Runtime\" />\n  </ItemGroup>\n  <Import Project=\"..\\..\\build\\common.targets\" />\n</Project>"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests.DisabledOptimizations/OptimizationsDisabledInCsproj.cs",
    "content": "﻿using BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Validators;\n\nnamespace BenchmarkDotNet.IntegrationTests.DisabledOptimizations\n{\n    internal class JitOptimizationsValidatorConfig : ManualConfig\n    {\n        public JitOptimizationsValidatorConfig()\n        {\n            AddJob(Job.Dry);\n            AddLogger(Loggers.ConsoleLogger.Default);\n            AddValidator(JitOptimizationsValidator.DontFailOnError);\n        }\n    }\n\n    [Config(typeof(JitOptimizationsValidatorConfig))]\n    public class OptimizationsDisabledInCsproj\n    {\n        [Benchmark]\n        public string Benchmark()\n        {\n            return \"I have manually checked off 'optimize' in .csproj for RELEASE\";\n        }\n    }\n}\n"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests.DisabledOptimizations/Properties/AssemblyInfo.cs",
    "content": "﻿using System.Runtime.InteropServices;\n\n[assembly: Guid(\"ac2188e5-a140-43e2-8a76-4bdabfe30aba\")]"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests.EnabledOptimizations/BenchmarkDotNet.IntegrationTests.EnabledOptimizations.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\n  <Import Project=\"..\\..\\build\\common.props\" />\n  <PropertyGroup>\n    <AssemblyTitle>BenchmarkDotNet.IntegrationTests.EnabledOptimizations</AssemblyTitle>\n    <TargetFrameworks>net462;net8.0</TargetFrameworks>\n    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>\n    <AssemblyName>BenchmarkDotNet.IntegrationTests.EnabledOptimizations</AssemblyName>\n    <PackageId>BenchmarkDotNet.IntegrationTests.EnabledOptimizations</PackageId>\n    <GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>\n    <GenerateDocumentationFile>false</GenerateDocumentationFile>\n    <PlatformTarget>AnyCPU</PlatformTarget>\n    \n    <Optimize>true</Optimize>\n  </PropertyGroup>\n  <ItemGroup>\n    <ProjectReference Include=\"..\\..\\src\\BenchmarkDotNet\\BenchmarkDotNet.csproj\" />\n  </ItemGroup>\n  <ItemGroup Condition=\" '$(TargetFrameworkIdentifier)' == '.NETFramework' \">\n    <PackageReference Include=\"Microsoft.NETCore.Platforms\" Version=\"7.0.4\" />\n    <Reference Include=\"System.Runtime\" />\n  </ItemGroup>\n  <Import Project=\"..\\..\\build\\common.targets\" />\n</Project>"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests.EnabledOptimizations/OptimizationsEnabledInCsproj.cs",
    "content": "﻿using BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Validators;\n\nnamespace BenchmarkDotNet.IntegrationTests.EnabledOptimizations\n{\n    internal class JitOptimizationsValidatorConfig : ManualConfig\n    {\n        public JitOptimizationsValidatorConfig()\n        {\n            AddJob(Job.Dry);\n            AddLogger(Loggers.ConsoleLogger.Default);\n            AddValidator(JitOptimizationsValidator.DontFailOnError);\n        }\n    }\n\n    [Config(typeof(JitOptimizationsValidatorConfig))]\n    public class OptimizationsEnabledInCsproj\n    {\n        [Benchmark]\n        public string Benchmark()\n        {\n            return \"I have manually checked 'optimize' in .csproj for DEBUG\";\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests.EnabledOptimizations/Properties/AssemblyInfo.cs",
    "content": "﻿using System.Runtime.InteropServices;\n\n[assembly: Guid(\"873581ff-db9d-42e5-8f11-32a4b7bb28ec\")]"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests.FSharp/BenchmarkDotNet.IntegrationTests.FSharp.fsproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\n  <Import Project=\"..\\..\\build\\common.props\" />\n  <PropertyGroup>\n    <TargetFrameworks>net462;net8.0</TargetFrameworks>\n    <PublicSign>false</PublicSign>\n  </PropertyGroup>\n  <ItemGroup>\n    <Compile Include=\"Program.fs\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ProjectReference Include=\"..\\..\\src\\BenchmarkDotNet\\BenchmarkDotNet.csproj\" />\n  </ItemGroup>\n  <ItemGroup>\n    <PackageReference Update=\"FSharp.Core\" Version=\"10.0.103\" />\n    <PackageReference Update=\"System.ValueTuple\" Version=\"4.6.2\" />\n  </ItemGroup>\n  <Import Project=\"..\\..\\build\\common.targets\" />\n</Project>"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests.FSharp/Program.fs",
    "content": "﻿module FSharpBenchmarks\n\nopen System.Threading\nopen System.Collections.Generic\nopen BenchmarkDotNet.Attributes\n\ntype File = \n    { Name : string\n      Path : string\n      Extension : string\n      Length : int }\n\n[<DryJob>]\ntype Db() = \n\n    let createDoc name = \n        { Name = name\n          Path = name\n          Extension = name\n          Length = name.Length }\n\n    [<Benchmark>]\n    member this.Test() = \n        printfn \"// ### F# Benchmark method called ###\"\n        Thread.Sleep(50)\n        createDoc(\"Testing\")\n\ntype TestEnum = | A = 0 | B = 1 | C = 2\n\ntype EnumParamsTest() =\n    [<Params(TestEnum.B)>]\n    member val EnumParamValue = TestEnum.A with get, set\n\n    [<Benchmark>]\n    member this.Benchmark() =\n        if not (this.EnumParamValue = TestEnum.B) then failwith \"Invalid Params value assigned\"\n\ntype AnonymousRecordTest() =\n\n    [<Benchmark>]\n    member _.AnonymousRecord() =\n        let array = Array.init 5 id\n        array |> Array.countBy (fun n -> {| Field = n |})"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests.ManualRunning/BenchmarkDotNet.IntegrationTests.ManualRunning.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\n  <Import Project=\"..\\..\\build\\common.props\" />\n  <PropertyGroup>\n    <AssemblyTitle>BenchmarkDotNet.IntegrationTests.ManualRunning</AssemblyTitle>\n    <TargetFrameworks>net462;net8.0</TargetFrameworks>\n    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>\n    <AssemblyName>BenchmarkDotNet.IntegrationTests.ManualRunning</AssemblyName>\n    <PackageId>BenchmarkDotNet.IntegrationTests.ManualRunning</PackageId>\n    <GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>\n    <GenerateDocumentationFile>false</GenerateDocumentationFile>\n    <PlatformTarget>AnyCPU</PlatformTarget>\n    <DebugSymbols>true</DebugSymbols>\n  </PropertyGroup>\n\n  <PropertyGroup Condition=\"'$(CustomProp)'=='true'\">\n    <DefineConstants>$(DefineConstants);CUSTOM_PROP</DefineConstants>\n  </PropertyGroup>\n  \n  <ItemGroup>\n    <Compile Include=\"..\\BenchmarkDotNet.IntegrationTests\\BenchmarkTestExecutor.cs\" Link=\"BenchmarkTestExecutor.cs\" />\n    <Compile Include=\"..\\BenchmarkDotNet.IntegrationTests\\Xunit\\MisconfiguredEnvironmentException.cs\" Link=\"MisconfiguredEnvironmentException.cs\" />\n    <Compile Include=\"..\\BenchmarkDotNet.IntegrationTests\\Xunit\\Extensions.cs\" Link=\"Extensions.cs\" />\n    <Compile Include=\"..\\BenchmarkDotNet.IntegrationTests\\TestConfigs.cs\" Link=\"TestConfigs.cs\" />\n    <Compile Include=\"..\\BenchmarkDotNet.Tests\\Loggers\\OutputLogger.cs\" Link=\"OutputLogger.cs\" />\n    <Compile Include=\"..\\BenchmarkDotNet.Tests\\XUnit\\*.cs\" />\n  </ItemGroup>\n  <ItemGroup>\n    <Content Include=\"xunit.runner.json\">\n      <CopyToOutputDirectory>Always</CopyToOutputDirectory>\n    </Content>\n  </ItemGroup>\n  <ItemGroup>\n    <ProjectReference Include=\"..\\..\\src\\BenchmarkDotNet\\BenchmarkDotNet.csproj\" />\n    <ProjectReference Include=\"..\\..\\src\\BenchmarkDotNet.Diagnostics.Windows\\BenchmarkDotNet.Diagnostics.Windows.csproj\" />\n    <ProjectReference Include=\"..\\..\\src\\BenchmarkDotNet.Diagnostics.dotTrace\\BenchmarkDotNet.Diagnostics.dotTrace.csproj\" />\n    <ProjectReference Include=\"..\\..\\src\\BenchmarkDotNet.Diagnostics.dotMemory\\BenchmarkDotNet.Diagnostics.dotMemory.csproj\" />\n  </ItemGroup>\n  <ItemGroup>\n    <PackageReference Include=\"Microsoft.NET.Test.Sdk\" Version=\"18.0.1\" />\n    <PackageReference Include=\"xunit\" Version=\"2.9.3\" />\n    <PackageReference Include=\"xunit.runner.visualstudio\" Version=\"[2.8.2]\">\n      <PrivateAssets>all</PrivateAssets>\n      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\n    </PackageReference>\n  </ItemGroup>\n  <Import Project=\"..\\..\\build\\common.targets\" />\n</Project>"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests.ManualRunning/DotMemoryTests.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Detectors;\nusing BenchmarkDotNet.Diagnostics.dotMemory;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Portability;\nusing BenchmarkDotNet.Toolchains.InProcess.Emit;\nusing Xunit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.IntegrationTests.ManualRunning\n{\n    public class DotMemoryTests : BenchmarkTestExecutor\n    {\n        public DotMemoryTests(ITestOutputHelper output) : base(output) { }\n\n        [Fact]\n        public void DotMemorySmokeTest()\n        {\n            if (!OsDetector.IsWindows() && RuntimeInformation.IsMono)\n            {\n                Output.WriteLine(\"Skip Mono on non-Windows\");\n                return;\n            }\n\n            var config = new ManualConfig().AddJob(\n            [\n                Job.Dry.WithId(\"ExternalProcess\"),\n                Job.Dry.WithToolchain(InProcessEmitToolchain.Default).WithId(\"InProcess\"),\n            ]\n            );\n            string snapshotDirectory = Path.Combine(Directory.GetCurrentDirectory(), \"BenchmarkDotNet.Artifacts\", \"snapshots\");\n            if (Directory.Exists(snapshotDirectory))\n                Directory.Delete(snapshotDirectory, true);\n\n            CanExecute<Benchmarks>(config);\n\n            Output.WriteLine(\"---------------------------------------------\");\n            Output.WriteLine(\"SnapshotDirectory:\" + snapshotDirectory);\n            var snapshots = Directory.EnumerateFiles(snapshotDirectory)\n                .Where(filePath => Path.GetExtension(filePath).Equals(\".dmw\", StringComparison.OrdinalIgnoreCase))\n                .Select(Path.GetFileName!)\n                .OrderBy(fileName => fileName)\n                .ToList();\n            Output.WriteLine(\"Snapshots:\");\n            foreach (var snapshot in snapshots)\n                Output.WriteLine(\"* \" + snapshot);\n\n            Assert.Equal(2, snapshots.Count);\n            // Assert.Equal(4, snapshots.Count);\n        }\n\n        [DotMemoryDiagnoser]\n        public class Benchmarks\n        {\n            [Benchmark]\n            public int Foo0()\n            {\n                var list = new List<object>();\n                for (int i = 0; i < 1000; i++)\n                    list.Add(new object());\n                return list.Count;\n            }\n\n            [Benchmark]\n            public int Foo1()\n            {\n                var list = new List<object>();\n                for (int i = 0; i < 1000; i++)\n                    list.Add(new object());\n                return list.Count;\n            }\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests.ManualRunning/DotTraceTests.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Detectors;\nusing BenchmarkDotNet.Diagnostics.dotTrace;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Portability;\nusing BenchmarkDotNet.Toolchains.InProcess.Emit;\nusing Xunit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.IntegrationTests.ManualRunning\n{\n    public class DotTraceTests : BenchmarkTestExecutor\n    {\n        public DotTraceTests(ITestOutputHelper output) : base(output) { }\n\n        [Fact]\n        public void DotTraceSmokeTest()\n        {\n            if (!OsDetector.IsWindows() && RuntimeInformation.IsMono)\n            {\n                Output.WriteLine(\"Skip Mono on non-Windows\");\n                return;\n            }\n\n            var config = new ManualConfig().AddJob(\n            [\n                Job.Dry.WithId(\"ExternalProcess\"),\n                Job.Dry.WithToolchain(InProcessEmitToolchain.Default).WithId(\"InProcess\")\n            ]\n            );\n            string snapshotDirectory = Path.Combine(Directory.GetCurrentDirectory(), \"BenchmarkDotNet.Artifacts\", \"snapshots\");\n            if (Directory.Exists(snapshotDirectory))\n                Directory.Delete(snapshotDirectory, true);\n\n            CanExecute<Benchmarks>(config);\n\n            Output.WriteLine(\"---------------------------------------------\");\n            Output.WriteLine(\"SnapshotDirectory:\" + snapshotDirectory);\n            var snapshots = Directory.EnumerateFiles(snapshotDirectory)\n                .Where(filePath => Path.GetExtension(filePath).Equals(\".dtp\", StringComparison.OrdinalIgnoreCase))\n                .Select(Path.GetFileName!)\n                .OrderBy(fileName => fileName)\n                .ToList();\n            Output.WriteLine(\"Snapshots:\");\n            foreach (var snapshot in snapshots)\n                Output.WriteLine(\"* \" + snapshot);\n\n            Assert.Single(snapshots);\n            // Assert.Equal(2, snapshots.Count);\n        }\n\n        [DotTraceDiagnoser]\n        public class Benchmarks\n        {\n            [Benchmark]\n            public int Foo()\n            {\n                var list = new List<object>();\n                for (int i = 0; i < 1000000; i++)\n                    list.Add(new object());\n                return list.Count;\n            }\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests.ManualRunning/MsBuildArgumentTests.cs",
    "content": "﻿using System;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Jobs;\nusing Xunit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.IntegrationTests.ManualRunning\n{\n    public class MsBuildArgumentTests : BenchmarkTestExecutor\n    {\n        private const string CustomPropEnvVarName = \"CustomPropEnvVarName\";\n\n        public MsBuildArgumentTests(ITestOutputHelper output) : base(output)\n        {\n        }\n\n        [Theory]\n        [InlineData(true)]\n        [InlineData(false)]\n        public void ProcessIsBuiltWithCustomProperty(bool setCustomProperty)\n        {\n            var config = ManualConfig.CreateEmpty()\n                .AddJob(Job.Dry\n                    .WithArguments([new MsBuildArgument($\"/p:CustomProp={setCustomProperty}\")])\n                    .WithEnvironmentVariable(CustomPropEnvVarName, setCustomProperty.ToString())\n                );\n            CanExecute<PropertyDefine>(config);\n        }\n\n        [Fact]\n        public void MultipleProcessesAreBuiltWithCorrectProperties()\n        {\n            var config = ManualConfig.CreateEmpty()\n                .AddJob(Job.Dry\n                    .WithArguments([new MsBuildArgument($\"/p:CustomProp={true}\")])\n                    .WithEnvironmentVariable(CustomPropEnvVarName, true.ToString())\n                )\n                .AddJob(Job.Dry\n                    .WithRuntime(NativeAotRuntime.Net80)\n                    .WithArguments([new MsBuildArgument($\"/p:CustomProp={true}\")])\n                    .WithEnvironmentVariable(CustomPropEnvVarName, true.ToString())\n                )\n                .AddJob(Job.Dry\n                    .WithEnvironmentVariable(CustomPropEnvVarName, false.ToString())\n                );\n            CanExecute<PropertyDefine>(config);\n        }\n\n        public class PropertyDefine\n        {\n            private const bool customPropWasSet =\n#if CUSTOM_PROP\n                true;\n#else\n                false;\n#endif\n\n            [Benchmark]\n            public void ThrowWhenWrong()\n            {\n                if (Environment.GetEnvironmentVariable(CustomPropEnvVarName) != customPropWasSet.ToString())\n                {\n                    throw new InvalidOperationException($\"Custom property was not set properly, the expected value was {Environment.GetEnvironmentVariable(CustomPropEnvVarName)}\");\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests.ManualRunning/xunit.runner.json",
    "content": "﻿{\n  \"shadowCopy\": false,\n  \"methodDisplay\": \"method\",\n  \"diagnosticMessages\": true,\n  \"longRunningTestSeconds\": 30\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests.ManualRunning.MultipleFrameworks/BenchmarkDotNet.IntegrationTests.ManualRunning.MultipleFrameworks.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\n  <Import Project=\"..\\..\\build\\common.props\" />\n  <PropertyGroup>\n    <AssemblyTitle>BenchmarkDotNet.IntegrationTests.ManualRunning.MultipleFrameworks</AssemblyTitle>\n    <TargetFrameworks>net462;net48;net8.0;net10.0</TargetFrameworks>\n    <!-- Suppress warning MSB3277: Found conflicts between different versions of \"System.Buffers\" that could not be resolved. -->\n    <MSBuildWarningsAsMessages>$(MSBuildWarningsAsMessages);MSB3277</MSBuildWarningsAsMessages>\n    <TreatWarningsAsErrors>false</TreatWarningsAsErrors>\n    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>\n    <AssemblyName>BenchmarkDotNet.IntegrationTests.ManualRunning.MultipleFrameworks</AssemblyName>\n    <PackageId>BenchmarkDotNet.IntegrationTests.ManualRunning.MultipleFrameworks</PackageId>\n    <GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>\n    <GenerateDocumentationFile>false</GenerateDocumentationFile>\n    <PlatformTarget>AnyCPU</PlatformTarget>\n    <DebugSymbols>true</DebugSymbols>\n    <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>\n  </PropertyGroup>\n  <ItemGroup>\n    <Compile Include=\"..\\BenchmarkDotNet.IntegrationTests\\BenchmarkTestExecutor.cs\" Link=\"BenchmarkTestExecutor.cs\" />\n    <Compile Include=\"..\\BenchmarkDotNet.IntegrationTests\\Xunit\\MisconfiguredEnvironmentException.cs\" Link=\"MisconfiguredEnvironmentException.cs\" />\n    <Compile Include=\"..\\BenchmarkDotNet.IntegrationTests\\Xunit\\Extensions.cs\" Link=\"Extensions.cs\" />\n    <Compile Include=\"..\\BenchmarkDotNet.IntegrationTests\\TestConfigs.cs\" Link=\"TestConfigs.cs\" />\n    <Compile Include=\"..\\BenchmarkDotNet.Tests\\Loggers\\OutputLogger.cs\" Link=\"OutputLogger.cs\" />\n    <Compile Include=\"..\\BenchmarkDotNet.Tests\\XUnit\\SmartAssert.cs\" Link=\"SmartAssert.cs\" />\n  </ItemGroup>\n  <ItemGroup>\n    <PackageReference Include=\"Microsoft.NETCore.Platforms\" Version=\"7.0.4\" />\n  </ItemGroup>\n  <ItemGroup>\n    <Content Include=\"..\\BenchmarkDotNet.IntegrationTests.ManualRunning\\xunit.runner.json\">\n      <CopyToOutputDirectory>Always</CopyToOutputDirectory>\n    </Content>\n  </ItemGroup>\n  <ItemGroup>\n    <ProjectReference Include=\"..\\..\\src\\BenchmarkDotNet.Annotations\\BenchmarkDotNet.Annotations.csproj\" />\n    <ProjectReference Include=\"..\\..\\src\\BenchmarkDotNet\\BenchmarkDotNet.csproj\" />\n  </ItemGroup>\n  <ItemGroup>\n    <PackageReference Include=\"Microsoft.NET.Test.Sdk\" Version=\"18.0.1\" />\n    <PackageReference Include=\"xunit\" Version=\"2.9.3\" />\n    <PackageReference Include=\"xunit.runner.visualstudio\" Version=\"[2.8.2]\">\n      <PrivateAssets>all</PrivateAssets>\n      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\n    </PackageReference>\n  </ItemGroup>\n  <Import Project=\"..\\..\\build\\common.targets\" />\n</Project>\n"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests.ManualRunning.MultipleFrameworks/MultipleFrameworksTest.cs",
    "content": "﻿using System;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Jobs;\nusing Xunit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.IntegrationTests.ManualRunning\n{\n    public class MultipleFrameworksTest : BenchmarkTestExecutor\n    {\n        private const string TfmEnvVarName = \"TfmEnvVarName\";\n\n        public MultipleFrameworksTest(ITestOutputHelper output) : base(output)\n        {\n        }\n\n        [Theory]\n        [InlineData(RuntimeMoniker.Net461)]\n        [InlineData(RuntimeMoniker.Net48)]\n        [InlineData(RuntimeMoniker.NetCoreApp20)]\n        [InlineData(RuntimeMoniker.Net80)]\n        public void EachFrameworkIsRebuilt(RuntimeMoniker runtime)\n        {\n            var config = ManualConfig.CreateEmpty().AddJob(Job.Dry.WithRuntime(runtime.GetRuntime()).WithEnvironmentVariable(TfmEnvVarName, runtime.ToString()));\n            CanExecute<ValuePerTfm>(config);\n        }\n\n        public class ValuePerTfm\n        {\n            private const RuntimeMoniker moniker =\n#if NET462\n                RuntimeMoniker.Net462;\n#elif NET48\n                RuntimeMoniker.Net48;\n#elif NET8_0\n                RuntimeMoniker.Net80;\n#elif NET10_0\n                RuntimeMoniker.Net10_0;\n#else\n                RuntimeMoniker.NotRecognized;\n#endif\n\n            [Benchmark]\n            public void ThrowWhenWrong()\n            {\n                if (Environment.GetEnvironmentVariable(TfmEnvVarName) != moniker.ToString())\n                {\n                    throw new InvalidOperationException($\"Has not been recompiled, the value was {moniker}, expected {Environment.GetEnvironmentVariable(TfmEnvVarName)}\");\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests.Static/BenchmarkClassWithStaticMethod.cs",
    "content": "using BenchmarkDotNet.Attributes;\n\nnamespace BenchmarkDotNet.IntegrationTests.Static\n{\n    [DryJob]\n    public class BenchmarkClassWithStaticMethodsOnly\n    {\n        [Benchmark]\n        public static void StaticMethod() { }\n    }\n\n    [DryJob]\n    public class BenchmarkClassWithInstanceMethod\n    {\n        [Benchmark]\n        public void NonStaticMethod() { }\n    }\n}\n"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests.Static/BenchmarkDotNet.IntegrationTests.Static.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\n  <Import Project=\"..\\..\\build\\common.props\" />\n  <PropertyGroup>\n    <AssemblyTitle>BenchmarkDotNet.IntegrationTests.Static</AssemblyTitle>\n    <TargetFrameworks>net462;net8.0</TargetFrameworks>\n    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>\n    <AssemblyName>BenchmarkDotNet.IntegrationTests.Static</AssemblyName>\n    <PackageId>BenchmarkDotNet.IntegrationTests.Static</PackageId>\n    <GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>\n    <GenerateDocumentationFile>false</GenerateDocumentationFile>\n    <PlatformTarget>AnyCPU</PlatformTarget>\n  </PropertyGroup>\n  <ItemGroup>\n    <ProjectReference Include=\"..\\..\\src\\BenchmarkDotNet\\BenchmarkDotNet.csproj\" />\n  </ItemGroup>\n  <ItemGroup Condition=\" '$(TargetFrameworkIdentifier)' == '.NETFramework' \">\n    <PackageReference Include=\"Microsoft.NETCore.Platforms\" Version=\"7.0.4\" />\n    <Reference Include=\"System.Runtime\" />\n  </ItemGroup>\n  <Import Project=\"..\\..\\build\\common.targets\" />\n</Project>"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests.VisualBasic/BenchmarkDotNet.IntegrationTests.VisualBasic.vbproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\n  <Import Project=\"..\\..\\build\\common.props\" />\n  <PropertyGroup>\n    <TargetFrameworks>net462;net8.0</TargetFrameworks>\n  </PropertyGroup>\n  <ItemGroup>\n    <ProjectReference Include=\"..\\..\\src\\BenchmarkDotNet\\BenchmarkDotNet.csproj\" />\n  </ItemGroup>\n  <Import Project=\"..\\..\\build\\common.targets\" />\n</Project>"
  },
  {
    "path": "tests/BenchmarkDotNet.IntegrationTests.VisualBasic/Sample.vb",
    "content": "﻿Imports BenchmarkDotNet.Attributes\n\nPublic Class Sample\n    <Params(1, 2)>\n    Public Property A As Integer\n    <Params(3, 4)>\n    Public Property B As Integer\n\n    <Benchmark>\n    Public Function Benchmark() As Integer\n            return A + B\n    End Function\nEnd Class\n"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Analysers/OutliersAnalyserTests.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing BenchmarkDotNet.Analysers;\nusing BenchmarkDotNet.Helpers;\nusing BenchmarkDotNet.Mathematics;\nusing Perfolizer.Horology;\nusing Xunit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.Tests.Analysers\n{\n    public class OutliersAnalyserTests(ITestOutputHelper output)\n    {\n        [Theory]\n        [InlineData(0, 0, \"\")]\n        [InlineData(1, 1, \"1 outlier  was  removed\")]\n        [InlineData(2, 2, \"2 outliers were removed\")]\n        [InlineData(3, 3, \"3 outliers were removed\")]\n        [InlineData(0, 1, \"1 outlier  was  detected\")]\n        [InlineData(0, 2, \"2 outliers were detected\")]\n        [InlineData(0, 3, \"3 outliers were detected\")]\n        [InlineData(1, 2, \"1 outlier  was  removed, 2 outliers were detected\")]\n        [InlineData(2, 3, \"2 outliers were removed, 3 outliers were detected\")]\n        public void SimpleMessageTest(int actualOutliers, int allOutliers, string expectedMessage)\n        {\n            string actualMessage = OutliersAnalyser.GetMessage(\n                new double[actualOutliers], new double[allOutliers], [], [], TestCultureInfo.Instance);\n            Assert.Equal(expectedMessage, actualMessage);\n        }\n\n        [Theory]\n        [InlineData(0, 0, \"\")]\n        [InlineData(0, 1, \"1 outlier  was  removed (2.50 us)\")]\n        [InlineData(0, 2, \"2 outliers were removed (2.50 us, 2.60 us)\")]\n        [InlineData(0, 3, \"3 outliers were removed (2.50 us..2.70 us)\")]\n        [InlineData(1, 0, \"1 outlier  was  removed (1.50 us)\")]\n        [InlineData(1, 1, \"2 outliers were removed (1.50 us, 2.50 us)\")]\n        [InlineData(1, 2, \"3 outliers were removed (1.50 us, 2.50 us, 2.60 us)\")]\n        [InlineData(1, 3, \"4 outliers were removed (1.50 us, 2.50 us..2.70 us)\")]\n        [InlineData(2, 0, \"2 outliers were removed (1.40 us, 1.50 us)\")]\n        [InlineData(2, 1, \"3 outliers were removed (1.40 us, 1.50 us, 2.50 us)\")]\n        [InlineData(2, 2, \"4 outliers were removed (1.40 us, 1.50 us, 2.50 us, 2.60 us)\")]\n        [InlineData(2, 3, \"5 outliers were removed (1.40 us, 1.50 us, 2.50 us..2.70 us)\")]\n        [InlineData(3, 0, \"3 outliers were removed (1.30 us..1.50 us)\")]\n        [InlineData(3, 1, \"4 outliers were removed (1.30 us..1.50 us, 2.50 us)\")]\n        [InlineData(3, 2, \"5 outliers were removed (1.30 us..1.50 us, 2.50 us, 2.60 us)\")]\n        [InlineData(3, 3, \"6 outliers were removed (1.30 us..1.50 us, 2.50 us..2.70 us)\")]\n        public void RangeMessageTest(int lowerOutliers, int upperOutliers, string expectedMessage)\n        {\n            var values = new List<double>();\n            for (int i = 0; i < 1000; i++)\n                values.Add(2000);\n            for (int i = 0; i < lowerOutliers; i++)\n                values.Add(1500 - i * 100);\n            for (int i = 0; i < upperOutliers; i++)\n                values.Add(2500 + i * 100);\n            values.Sort();\n            var s = new Statistics(values);\n            var cultureInfo = TestCultureInfo.Instance;\n            string actualMessage = OutliersAnalyser.GetMessage(s.AllOutliers, s.AllOutliers, s.LowerOutliers, s.UpperOutliers, cultureInfo).ToAscii();\n            output.WriteLine(\"Values   : \" +\n                             string.Join(\", \", values.Take(5).Select(x => TimeInterval.FromNanoseconds(x).ToDefaultString(\"N2\"))) +\n                             \", ..., \" +\n                             string.Join(\", \", values.Skip(values.Count - 5).Select(x => TimeInterval.FromNanoseconds(x).ToDefaultString(\"N2\"))));\n            output.WriteLine(\"Actual   : \" + actualMessage);\n            output.WriteLine(\"Expected : \" + expectedMessage);\n            Assert.Equal(expectedMessage, actualMessage);\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Analysers/ZeroMeasurementHelperTests.cs",
    "content": "using System.Collections.Generic;\nusing BenchmarkDotNet.Analysers;\nusing Perfolizer;\nusing Pragmastat;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests.Analysers\n{\n    public class ZeroMeasurementHelperTests\n    {\n        #region OneSampleTests\n\n        // let processor frequency ~ 3.30 GHz\n        private const double ThresholdMock = 0.2702d / 2;\n\n        /*\n          Test distributions inspired by data from method\n\n          public double Sqrt14()\n               => Math.Sqrt(1) + Math.Sqrt(2) + Math.Sqrt(3) + Math.Sqrt(4) +\n                  Math.Sqrt(5) + Math.Sqrt(6) + Math.Sqrt(7) + Math.Sqrt(8) +\n                  Math.Sqrt(9) + Math.Sqrt(10) + Math.Sqrt(11) + Math.Sqrt(12) +\n                  Math.Sqrt(13) + Math.Sqrt(14);\n\n          with Intel Core i5-2500 CPU 3.30GHz (Sandy Bridge) CPU\n          and RyuJit x64\n        */\n        [Theory]\n        [InlineData(0.27025, 0.27155, 0.27236, 0.27311, 0.27313, 0.27321, 0.27356, 0.27389, 0.27433, 0.27473, 0.27507, 0.27520, 0.27543)]\n        [InlineData(0.27875, 0.27876, 0.27961, 0.28004, 0.28211, 0.28270, 0.28323, 0.28361, 0.28404, 0.28452, 0.28456, 0.28584, 0.28651, 0.29015)]\n        [InlineData(0.27322, 0.27693, 0.27745, 0.27764, 0.27937, 0.27939, 0.28027, 0.28091, 0.28108, 0.28283, 0.28325, 0.28460, 0.28561, 0.28581)]\n        [InlineData(0.27049, 0.27410, 0.27433, 0.27468, 0.27476, 0.27591, 0.27644, 0.27704, 0.27724, 0.27766, 0.27792, 0.27878, 0.28025)]\n        public void OneSample_Around_One_CPU_Cycle_Method(params double[] distribution)\n        {\n            Assert.True(ZeroMeasurementHelper.IsNoticeable(new Sample(distribution), ThresholdMock));\n        }\n\n        [Theory]\n        [InlineData(0.2703, 0.2701, 0.2703, 0.2701, 0.2703, 0.2701, 0.2703, 0.2701, 0.2703, 0.2701, 0.2703, 0.2701)]\n        public void OneSample_Exactly_One_CPU_Cycle_Method(params double[] distribution)\n        {\n            Assert.True(ZeroMeasurementHelper.IsNoticeable(new Sample(distribution), ThresholdMock));\n        }\n\n        /*\n          Data inspired by distribution of benchmark\n\n          [MethodImpl(MethodImplOptions.NoOptimization)]\n          public double Return1()\n          {\n              return 1;\n          }\n\n          with Intel Core i5-2500 CPU 3.30GHz (Sandy Bridge) CPU\n          and RyuJit x64\n        */\n        [Theory]\n        [InlineData(0d, 0d, 0.00191d, 0.00530d, 0.00820d, 0.01383d, 0.01617d, 0.02183d, 0.02421d, 0.03640d, 0.03726d, 0.04894d, 0.05122d, 0.05924d, 0.06183d)]\n        [InlineData(0d, 0d, 0d, 0d, 0d, 0d, 0d, 0.00138d, 0.00482d, 0.00616d, 0.01318d, 0.02266d, 0.03048d, 0.03144d)]\n        [InlineData(0.02203d, 0.02523d, 0.02567d, 0.02706d, 0.03048d, 0.03461d, 0.03953d, 0.04127d, 0.04396d, 0.04939d, 0.05361d, 0.05670d, 0.06394d, 0.06812d,\n            0.06901d)]\n        public void OneSample_Less_Than_One_CPU_Cycle_Method(params double[] distribution)\n        {\n            Assert.True(ZeroMeasurementHelper.IsNegligible(new Sample(distribution), ThresholdMock));\n        }\n\n        /*\n          Sometimes appears distributions with all zero values\n          That's definitely zero measurement\n        */\n        [Theory]\n        [InlineData(0d, 0d, 0d, 0d, 0d, 0d, 0d, 0d, 0d, 0d, 0d, 0d, 0d)]\n        public void OneSample_Exactly_Zero_ns_Method(params double[] distribution)\n        {\n            Assert.True(ZeroMeasurementHelper.IsNegligible(new Sample(distribution), ThresholdMock));\n        }\n\n        /*\n          Test distributions inspired by data from method\n\n          public double Abs() => Math.Abs(A);\n\n          with Intel Core i5-2500 CPU 3.30GHz (Sandy Bridge) CPU\n          and RyuJit x64\n        */\n        [Theory]\n        [InlineData(0.57079d, 0.57469d, 0.57990d, 0.58025d, 0.58532d, 0.59250d, 0.59442d, 0.59487d, 0.59522d, 0.59619d, 0.59756d, 0.59802d, 0.60120d, 0.60813d,\n            0.61592d)]\n        [InlineData(0.57106d, 0.57168d, 0.57326d, 0.57587d, 0.57958d, 0.58982d, 0.59493d, 0.59950d, 0.61413d, 0.62000d, 0.62607d, 0.63209d, 0.63730d, 0.65048d,\n            0.65119d)]\n        [InlineData(0.57347d, 0.57483d, 0.57598d, 0.57681d, 0.57724d, 0.57906d, 0.57944d, 0.58182d, 0.58261d, 0.58300d, 0.58468d, 0.59045d, 0.59217d)]\n        public void OneSample_Around_Two_CPU_Cycle_Method(params double[] distribution)\n        {\n            Assert.True(ZeroMeasurementHelper.IsNoticeable(new Sample(distribution), ThresholdMock));\n        }\n\n        #endregion\n\n        #region TwoSamplesTests\n\n        /*\n          Data inspired by distribution of benchmark (Workload Actual and Overhead Actual measurements)\n\n          [MethodImpl(MethodImplOptions.NoOptimization)]\n          public double Return1()\n          {\n              return 1;\n          }\n\n          with Intel Core i5-2500 CPU 3.30GHz (Sandy Bridge) CPU\n          and RyuJit x64\n        */\n        public static IEnumerable<object[]> LessThanOneCycleTwoSamples\n        {\n            get\n            {\n                return\n                [\n                    [\n                        new[] { 2.0037, 2.0062, 2.0066, 2.0073, 2.0089, 2.0103, 2.013, 2.0169, 2.0197, 2.0224, 2.0243, 2.0271, 2.0281, 2.0514, 2.0517 },\n                        new[] { 2.0426, 2.046, 2.0471, 2.0506, 2.0508, 2.0555, 2.0573, 2.0653, 2.0657, 2.0659, 2.0692, 2.0717, 2.0777, 2.0856, 2.0868 }\n                    ],\n\n                    [\n                        new[] { 2.0186, 2.0196, 2.0207, 2.0208, 2.0208, 2.0211, 2.0213, 2.0215, 2.0288, 2.0315, 2.0326, 2.039, 2.049, 2.055, 2.0598 },\n                        new[] { 2.0151, 2.0192, 2.0226, 2.0248, 2.0271, 2.0276, 2.0298, 2.0339, 2.0411, 2.0429, 2.0458, 2.0501, 2.061, 2.0733, 2.0744 }\n                    ],\n\n                    [\n                        new[] { 2.0049, 2.0141, 2.0194, 2.0253, 2.0264, 2.0296, 2.0333, 2.0422, 2.0438, 2.044, 2.047, 2.048, 2.0494, 2.0549, 2.0675 },\n                        new[] { 1.9963, 2.0037, 2.0037, 2.0046, 2.0051, 2.007, 2.0166, 2.021, 2.0225, 2.0247, 2.0391, 2.0473, 2.0572, 2.0576, 2.0582 }\n                    ]\n                ];\n            }\n        }\n\n        [Theory]\n        [MemberData(nameof(LessThanOneCycleTwoSamples))]\n        public void TwoSamples_Less_Than_One_CPU_Cycle_Method(double[] workload, double[] overhead)\n        {\n            Assert.True(ZeroMeasurementHelper.AreIndistinguishable(new Sample(workload), new Sample(overhead)));\n        }\n\n        /*\n          Test distributions inspired by data (Workload Actual and Overhead Actual) from method\n\n          public double Sqrt14()\n               => Math.Sqrt(1) + Math.Sqrt(2) + Math.Sqrt(3) + Math.Sqrt(4) +\n                  Math.Sqrt(5) + Math.Sqrt(6) + Math.Sqrt(7) + Math.Sqrt(8) +\n                  Math.Sqrt(9) + Math.Sqrt(10) + Math.Sqrt(11) + Math.Sqrt(12) +\n                  Math.Sqrt(13) + Math.Sqrt(14);\n\n          with Intel Core i5-2500 CPU 3.30GHz (Sandy Bridge) CPU\n          and RyuJit x64\n        */\n        public static IEnumerable<object[]> OneCycleTwoSamples\n        {\n            get\n            {\n                return\n                [\n                    [\n                        new[]\n                        {\n                            2.34763, 2.34861, 2.34872, 2.34953, 2.35002, 2.35614, 2.35650, 2.36323, 2.36941, 2.37376, 2.38491, 2.38619, 2.38657, 2.38902,\n                            2.39455\n                        },\n                        new[] { 2.05899, 2.06069, 2.06243, 2.06405, 2.06762, 2.06785, 2.06889, 2.06891, 2.06895, 2.07531, 2.08003, 2.08024, 2.08342, 2.08959 }\n                    ],\n\n                    [\n                        new[]\n                        {\n                            2.36960, 2.37438, 2.37442, 2.38332, 2.38940, 2.39099, 2.39394, 2.39974, 2.40808, 2.41760, 2.41980, 2.42275, 2.42828, 2.42946,\n                            2.43763\n                        },\n                        new[]\n                        {\n                            2.06486, 2.06599, 2.07205, 2.07660, 2.07810, 2.07841, 2.08107, 2.08714, 2.10467, 2.10469, 2.11713, 2.12078, 2.12476, 2.12858,\n                            2.13760\n                        }\n                    ],\n\n                    [\n                        new[]\n                        {\n                            2.35046, 2.35630, 2.35788, 2.35801, 2.36632, 2.36841, 2.36925, 2.36980, 2.36998, 2.37153, 2.37330, 2.38491, 2.38732, 2.38853,\n                            2.41052\n                        },\n                        new[]\n                        {\n                            2.06291, 2.06545, 2.06763, 2.07381, 2.07568, 2.07810, 2.07894, 2.08153, 2.08264, 2.09000, 2.09814, 2.10082, 2.10107, 2.10576,\n                            2.12841\n                        }\n                    ]\n                ];\n            }\n        }\n\n        [Theory]\n        [MemberData(nameof(OneCycleTwoSamples))]\n        public void TwoSamples_Around_One_CPU_Cycle_Method(double[] workload, double[] overhead)\n        {\n            Assert.True(ZeroMeasurementHelper.AreDistinguishable(workload, overhead));\n        }\n\n        /*\n          Test distributions inspired by data (Workload Actual and Overhead Actual) from method\n\n          public double Abs() => Math.Abs(A);\n\n          with Intel Core i5-2500 CPU 3.30GHz (Sandy Bridge) CPU\n          and RyuJit x64\n        */\n        public static IEnumerable<object[]> TwoCycleTwoSamples\n        {\n            get\n            {\n                return\n                [\n                    [\n                        new[] { 2.6561, 2.658, 2.6606, 2.6621, 2.6636, 2.6639, 2.6656, 2.6673, 2.6741, 2.6754, 2.6787, 2.6935, 2.6997, 2.7313, 2.7394 },\n                        new[] { 2.0387, 2.0436, 2.0485, 2.0485, 2.0525, 2.0584, 2.0638, 2.0678, 2.0678, 2.0698, 2.0703, 2.0715, 2.0825, 2.0864 }\n                    ],\n                    [\n                        new[] { 2.6368, 2.6504, 2.652, 2.6541, 2.6607, 2.6642, 2.6698, 2.6749, 2.679, 2.6847, 2.6858, 2.6883, 2.6929, 2.702, 2.7134 },\n                        new[] { 2.04, 2.0461, 2.0481, 2.0485, 2.0502, 2.0523, 2.0547, 2.0602, 2.0613, 2.0677, 2.069, 2.0691, 2.0699, 2.0865 }\n                    ],\n                    [\n                        new[] { 2.6607, 2.6691, 2.67, 2.6741, 2.6753, 2.679, 2.6856, 2.6869, 2.6893, 2.692, 2.6971, 2.7146, 2.7245, 2.7368 },\n                        new[] { 2.0346, 2.054, 2.0655, 2.0673, 2.0718, 2.0748, 2.0766, 2.0839, 2.0856, 2.0869, 2.0924, 2.0968, 2.1129, 2.1148, 2.1328 }\n                    ]\n                ];\n            }\n        }\n\n        [Theory]\n        [MemberData(nameof(TwoCycleTwoSamples))]\n        public void TwoSamples_Around_Two_CPU_Cycle_Method(double[] workload, double[] overhead)\n        {\n            Assert.True(ZeroMeasurementHelper.AreDistinguishable(workload, overhead));\n        }\n\n        #endregion\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/AppConfigGeneratorTests.cs",
    "content": "﻿using BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Toolchains;\nusing System;\nusing System.IO;\nusing System.Text;\nusing BenchmarkDotNet.Characteristics;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Running;\nusing Xunit;\nusing BenchmarkDotNet.Tests.XUnit;\nusing System.Runtime;\n\nnamespace BenchmarkDotNet.Tests\n{\n    public class AppConfigGeneratorTests\n    {\n        private static readonly IResolver Resolver = BenchmarkRunnerClean.DefaultResolver;\n\n        [Fact]\n        public void GeneratesMinimalRequiredAppConfigForEmptySource()\n        {\n            using (var destination = new Utf8StringWriter())\n            {\n                string expectedMinimal =\n                    \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\" +\n                    \"<configuration>\" +\n                    $\"<runtime>{GcSettings}</runtime>\" +\n                    \"</configuration>\";\n\n                AppConfigGenerator.Generate(Job.Default, TextReader.Null, destination, Resolver);\n\n                AssertAreEqualIgnoringWhitespacesAndCase(expectedMinimal, destination.ToString());\n            }\n        }\n\n        [Fact]\n        public void GeneratesMinimalRequiredAppConfigForAlmostEmptySource()\n        {\n            using (var source = new StringReader(\"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\"))\n            using (var destination = new Utf8StringWriter())\n            {\n                string expectedMinimal =\n                    \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\" +\n                    \"<configuration>\" +\n                    $\"<runtime>{GcSettings}</runtime>\" +\n                    \"</configuration>\";\n\n                AppConfigGenerator.Generate(Job.Default, source, destination, Resolver);\n\n                AssertAreEqualIgnoringWhitespacesAndCase(expectedMinimal, destination.ToString());\n            }\n        }\n\n        [Fact]\n        public void RewritesCustomSettings()\n        {\n            string customSettingsWithoutRuntimeNode =\n                \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\" +\n                \"<!--\" +\n                \"commentsAreSupported\" +\n                \"-->\" +\n                \"<configuration>\" +\n                \"<someConfig>withItsValue</someConfig>\" +\n                \"</configuration>\";\n\n            string customSettingsWithRuntimeNode =\n                \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\" +\n                \"<!--\" +\n                \"commentsAreSupported\" +\n                \"-->\" +\n                \"<configuration>\" +\n                \"<someConfig>withItsValue</someConfig>\" +\n                $\"<runtime>{GcSettings}</runtime>\" +\n                \"</configuration>\";\n\n            using (var source = new StringReader(customSettingsWithoutRuntimeNode))\n            using (var destination = new Utf8StringWriter())\n            {\n                AppConfigGenerator.Generate(Job.Default, source, destination, Resolver);\n\n                AssertAreEqualIgnoringWhitespacesAndCase(customSettingsWithRuntimeNode, destination.ToString());\n            }\n        }\n\n        [Fact]\n        public void RewritesCustomRuntimeSettings()\n        {\n            string customSettingsBefore =\n                \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\" +\n                \"<!--\" +\n                \"commentsAreSupported\" +\n                \"-->\" +\n                \"<configuration>\" +\n                \"<someConfig>withItsValue</someConfig>\" +\n                $\"<runtime><AppContextSwitchOverrides value=\\\"Switch.System.IO.UseLegacyPathHandling=false\\\"/></runtime>\" +\n                \"</configuration>\";\n\n            string customSettingsAfter =\n                \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\" +\n                \"<!--\" +\n                \"commentsAreSupported\" +\n                \"-->\" +\n                \"<configuration>\" +\n                \"<someConfig>withItsValue</someConfig>\" +\n                $\"<runtime><AppContextSwitchOverrides value=\\\"Switch.System.IO.UseLegacyPathHandling=false\\\"/>{GcSettings}</runtime>\" +\n                \"</configuration>\";\n\n            using (var source = new StringReader(customSettingsBefore))\n            using (var destination = new Utf8StringWriter())\n            {\n                AppConfigGenerator.Generate(Job.Default, source, destination, Resolver);\n\n                AssertAreEqualIgnoringWhitespacesAndCase(customSettingsAfter, destination.ToString());\n            }\n        }\n\n        [Theory]\n        [InlineData(Jit.LegacyJit, \"<useLegacyJit enabled=\\\"1\\\" />\")]\n        [InlineData(Jit.RyuJit, \"<useLegacyJit enabled=\\\"0\\\" />\")]\n        public void GeneratesRightJitSettings(Jit jit, string expectedRuntimeNode)\n        {\n            const string customSettings =\n                \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\" +\n                \"<configuration>\" +\n                \"<someConfig>withItsValue</someConfig>\" +\n                \"</configuration>\";\n\n            string customSettingsAndJit =\n                \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\" +\n                \"<configuration>\" +\n                \"<someConfig>withItsValue</someConfig>\" +\n                $\"<runtime>{expectedRuntimeNode}{GcSettings}</runtime>\" +\n                \"</configuration>\" + Environment.NewLine;\n\n            using (var source = new StringReader(customSettings))\n            using (var destination = new Utf8StringWriter())\n            {\n                AppConfigGenerator.Generate(new Job { Environment = { Jit = jit } }.Freeze(), source, destination, Resolver);\n\n                AssertAreEqualIgnoringWhitespacesAndCase(customSettingsAndJit, destination.ToString());\n            }\n        }\n\n        [FactEnvSpecific(\"Full Framework is supported only on Windows\", EnvRequirement.WindowsOnly)]\n        public void RemovesStartupSettingsForPrivateBuildsOfClr()\n        {\n            const string input =\n                \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\" +\n                \"<configuration>\" +\n                \"<startup><supportedRuntime version=\\\"v4.0\\\" sku=\\\".NETFramework,Version=v4.6.2\\\" /></startup>\" +\n                \"</configuration>\";\n\n            string withoutStartup =\n                \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\" +\n                \"<configuration>\" +\n                $\"<runtime>{GcSettings}</runtime>\" +\n                \"</configuration>\" + Environment.NewLine;\n\n            using (var source = new StringReader(input))\n            using (var destination = new Utf8StringWriter())\n            {\n                AppConfigGenerator.Generate(new Job { Environment = { Runtime = ClrRuntime.CreateForLocalFullNetFrameworkBuild(version: \"4.0\")} }.Freeze(), source, destination, Resolver);\n\n                AssertAreEqualIgnoringWhitespacesAndCase(withoutStartup, destination.ToString());\n            }\n        }\n\n        [Fact]\n        public void LeavsStartupSettingsIntactForNonPrivateBuildsOfClr()\n        {\n            const string input =\n                \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\" +\n                \"<configuration>\" +\n                \"<startup><supportedRuntime version=\\\"v4.0\\\" sku=\\\".NETFramework,Version=v4.6.2\\\" /></startup>\" +\n                \"</configuration>\";\n\n            string withoutStartup =\n                \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\" +\n                \"<configuration>\" +\n                \"<startup><supportedRuntime version=\\\"v4.0\\\" sku=\\\".NETFramework,Version=v4.6.2\\\" /></startup>\" +\n                $\"<runtime>{GcSettings}</runtime>\" +\n                \"</configuration>\" + Environment.NewLine;\n\n            using (var source = new StringReader(input))\n            using (var destination = new Utf8StringWriter())\n            {\n                AppConfigGenerator.Generate(new Job { Environment = { Runtime = ClrRuntime.Net462 } }.Freeze(), source, destination, Resolver);\n\n                AssertAreEqualIgnoringWhitespacesAndCase(withoutStartup, destination.ToString());\n            }\n        }\n\n        [Fact]\n        public void RewritesCustomAssemblyBindingRedirects()\n        {\n            const string settingsWithBindings =\n                \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\" +\n                \"<configuration>\" +\n                \"<runtime>\" +\n                \"<assemblyBinding xmlns=\\\"urn:schemas-microsoft-com:asm.v1\\\">\" +\n                \"<dependentAssembly>\" +\n                \"<assemblyIdentity name=\\\"System.Runtime\\\" publicKeyToken=\\\"b03f5f7f11d50a3a\\\" culture=\\\"neutral\\\" />\" +\n                \"<bindingRedirect oldVersion=\\\"0.0.0.0-4.0.20.0\\\" newVersion=\\\"4.0.20.0\\\" />\" +\n                \"</dependentAssembly>\" +\n                \"</assemblyBinding>\" +\n                \"</runtime>\" +\n                \"</configuration>\";\n\n            string settingsWithBindingsAndJit =\n                \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\" +\n                \"<configuration>\" +\n                \"<runtime>\" +\n                \"<assemblyBinding xmlns=\\\"urn:schemas-microsoft-com:asm.v1\\\">\" +\n                \"<dependentAssembly>\" +\n                \"<assemblyIdentity name=\\\"System.Runtime\\\" publicKeyToken=\\\"b03f5f7f11d50a3a\\\" culture=\\\"neutral\\\" />\" +\n                \"<bindingRedirect oldVersion=\\\"0.0.0.0-4.0.20.0\\\" newVersion=\\\"4.0.20.0\\\" />\" +\n                \"</dependentAssembly>\" +\n                \"</assemblyBinding>\" +\n                \"<useLegacyJit enabled =\\\"0\\\" />\" +\n                GcSettings +\n                \"</runtime>\" +\n                \"</configuration>\";\n\n            using (var source = new StringReader(settingsWithBindings))\n            using (var destination = new Utf8StringWriter())\n            {\n                AppConfigGenerator.Generate(Job.RyuJitX64, source, destination, Resolver);\n\n                AssertAreEqualIgnoringWhitespacesAndCase(settingsWithBindingsAndJit, destination.ToString());\n            }\n        }\n\n        private static void AssertAreEqualIgnoringWhitespacesAndCase(string expectedXml, string actualXml)\n        {\n            string expected = RemoveWhiteSpaces(expectedXml);\n            string actual = RemoveWhiteSpaces(actualXml);\n\n            Assert.Equal(expected, actual, StringComparer.OrdinalIgnoreCase);\n        }\n\n        private static string RemoveWhiteSpaces(string input)\n        {\n            var buffer = new StringBuilder(input.Length);\n            foreach (char character in input)\n                switch (character)\n                {\n                    case '\\r':\n                    case '\\n':\n                    case '\\t':\n                    case ' ':\n                        continue;\n                    default:\n                        buffer.Append(character);\n                        break;\n                }\n            return buffer.ToString();\n        }\n\n        private static readonly string GcSettings = $\"<gcConcurrentenabled=\\\"{(GCSettings.LatencyMode != GCLatencyMode.Batch).ToLowerCase()}\\\"/><gcServerenabled=\\\"{GCSettings.IsServerGC.ToLowerCase()}\\\"/>\";\n    }\n\n    internal class Utf8StringWriter : StringWriter\n    {\n        public override Encoding Encoding => Encoding.UTF8;\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/ArtifactFileNameHelperTests.cs",
    "content": "﻿using BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Diagnosers;\nusing BenchmarkDotNet.Helpers;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Tests.XUnit;\nusing System.Buffers.Tests;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests\n{\n    public class ArtifactFileNameHelperTests\n    {\n        [FactEnvSpecific(\"ETW Sessions can be created only on Windows\", EnvRequirement.WindowsOnly)]\n        public void OnWindowsWeMustAlwaysUseOldLongPathsLimitForSessionFiles()\n        {\n            var config = DefaultConfig.Instance\n                .WithArtifactsPath(@\"C:\\Projects\\performance\\artifacts\\bin\\MicroBenchmarks\\Release\\netcoreapp5.0\\BenchmarkDotNet.Artifacts\");\n\n            var benchmarkCase = BenchmarkConverter.TypeToBenchmarks(typeof(RentReturnArrayPoolTests<byte>), config).BenchmarksCases.First();\n\n            var parameters = new DiagnoserActionParameters(\n                process: null,\n                benchmarkCase: benchmarkCase,\n                new BenchmarkId(0, benchmarkCase));\n\n            foreach (string fileExtension in new[] { \"etl\", \"kernel.etl\", \"userheap.etl\" })\n            {\n                var traceFilePath = ArtifactFileNameHelper.GetTraceFilePath(parameters, new System.DateTime(2020, 10, 1), fileExtension);\n\n                Assert.InRange(actual: traceFilePath.Length, low: 0, high: 260);\n            }\n        }\n    }\n}\n\nnamespace System.Buffers.Tests\n{\n    [GenericTypeArguments(typeof(byte))] // value type\n    [GenericTypeArguments(typeof(object))] // reference type\n    public class RentReturnArrayPoolTests<T>\n    {\n        private readonly ArrayPool<T> _createdPool = ArrayPool<T>.Create();\n        private const int Iterations = 100_000;\n        [Params(4096)]\n        public int RentalSize;\n\n        [Params(false, true)]\n        public bool ManipulateArray { get; set; }\n\n        [Params(false, true)]\n        public bool Async { get; set; }\n\n        [Params(false, true)]\n        public bool UseSharedPool { get; set; }\n\n        private ArrayPool<T> Pool => UseSharedPool ? ArrayPool<T>.Shared : _createdPool;\n\n        private static void Clear(T[] arr) => arr.AsSpan().Clear();\n\n        private static T IterateAll(T[] arr)\n        {\n            T ret = default!;\n            foreach (T item in arr)\n            {\n                ret = item;\n            }\n            return ret;\n        }\n\n        [Benchmark(OperationsPerInvoke = Iterations)]\n        public async Task SingleSerial()\n        {\n            ArrayPool<T> pool = Pool;\n            for (int i = 0; i < Iterations; i++)\n            {\n                T[] arr = pool.Rent(RentalSize);\n                if (ManipulateArray) Clear(arr);\n                if (Async) await Task.Yield();\n                if (ManipulateArray) IterateAll(arr);\n                pool.Return(arr);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Attributes/MutatorAttributesTests.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing System.Reflection;\nusing BenchmarkDotNet.Attributes;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests.Attributes\n{\n    public class MutatorAttributesTests\n    {\n        [Fact]\n        public void AllMutatorsAttributesCanBeAppliedOnlyOncePerType()\n        {\n            var attributeTypes = typeof(JobMutatorConfigBaseAttribute)\n                .Assembly\n                .GetExportedTypes()\n                .Where(type => type.IsSubclassOf(typeof(JobMutatorConfigBaseAttribute)));\n\n            foreach (var attributeType in attributeTypes)\n            {\n                Assert.Single(\n                    attributeType.GetCustomAttributes().OfType<AttributeUsageAttribute>(),\n                    usageAttribute => usageAttribute.AllowMultiple == false);\n            }\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Attributes/ParamsAllValuesVerifyTests.cs",
    "content": "﻿using System;\nusing System.Diagnostics.CodeAnalysis;\nusing System.Globalization;\nusing System.Linq;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing BenchmarkDotNet.Exporters;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Tests.Mocks;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Tests.Builders;\nusing BenchmarkDotNet.Tests.Infra;\nusing BenchmarkDotNet.Validators;\nusing JetBrains.Annotations;\nusing VerifyXunit;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests.Attributes\n{\n    [Collection(\"VerifyTests\")]\n    public class ParamsAllValuesVerifyTests : IDisposable\n    {\n        private readonly CultureInfo initCulture;\n\n        public ParamsAllValuesVerifyTests() => initCulture = Thread.CurrentThread.CurrentCulture;\n\n        [UsedImplicitly]\n        public static TheoryData<Type> GetBenchmarkTypes()\n        {\n            var data = new TheoryData<Type>();\n            foreach (var type in typeof(Benchmarks).GetNestedTypes())\n                data.Add(type);\n            return data;\n        }\n\n        [Theory]\n        [MemberData(nameof(GetBenchmarkTypes))]\n        public Task BenchmarkShouldProduceSummary(Type benchmarkType)\n        {\n            Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;\n\n            var logger = new AccumulationLogger();\n            logger.WriteLine(\"=== \" + benchmarkType.Name + \" ===\");\n\n            var exporter = MarkdownExporter.Mock;\n            var summary = MockFactory.CreateSummary(benchmarkType);\n            exporter.ExportToLog(summary, logger);\n\n            var validator = ParamsAllValuesValidator.FailOnError;\n            var errors = validator.Validate(new ValidationParameters(summary.BenchmarksCases, summary.BenchmarksCases.First().Config)).ToList();\n            logger.WriteLine();\n            logger.WriteLine(\"Errors: \" + errors.Count);\n            foreach (var error in errors)\n                logger.WriteLineError(\"* \" + error.Message);\n\n            var settings = VerifyHelper.Create();\n            settings.UseTextForParameters(benchmarkType.Name);\n            return Verifier.Verify(logger.GetLog(), settings);\n        }\n\n        public void Dispose() => Thread.CurrentThread.CurrentCulture = initCulture;\n\n        public enum TestEnum\n        {\n            A = 1, B, C\n        }\n\n        [Flags]\n        public enum TestFlagsEnum\n        {\n            A = 0b001,\n            B = 0b010,\n            C = 0b100\n        }\n\n        [SuppressMessage(\"ReSharper\", \"InconsistentNaming\")]\n        public static class Benchmarks\n        {\n            public class WithAllValuesOfBool\n            {\n                [ParamsAllValues]\n                public bool ParamProperty { get; set; }\n\n                [Benchmark]\n                public void Benchmark() { }\n            }\n\n            public class WithAllValuesOfEnum\n            {\n                [ParamsAllValues]\n                public TestEnum ParamProperty { get; set; }\n\n                [Benchmark]\n                public void Benchmark() { }\n            }\n\n            public class WithAllValuesOfNullableBool\n            {\n                [ParamsAllValues]\n                public bool? ParamProperty { get; set; }\n\n                [Benchmark]\n                public void Benchmark() { }\n            }\n\n            public class WithAllValuesOfNullableEnum\n            {\n                [ParamsAllValues]\n                public TestEnum? ParamProperty { get; set; }\n\n                [Benchmark]\n                public void Benchmark() { }\n            }\n\n#pragma warning disable BDN1304\n            public class WithNotAllowedTypeError\n            {\n                [ParamsAllValues]\n                public int ParamProperty { get; set; }\n\n                [Benchmark]\n                public void Benchmark() { }\n            }\n#pragma warning restore BDN1304\n\n#pragma warning disable BDN1304\n            public class WithNotAllowedNullableTypeError\n            {\n                [ParamsAllValues]\n                public int? ParamProperty { get; set; }\n\n                [Benchmark]\n                public void Benchmark() { }\n            }\n#pragma warning restore BDN1304\n\n#pragma warning disable BDN1303\n            public class WithNotAllowedFlagsEnumError\n            {\n                [ParamsAllValues]\n                public TestFlagsEnum ParamProperty { get; set; }\n\n                [Benchmark]\n                public void Benchmark() { }\n            }\r\n#pragma warning restore BDN1303\n        }\n    }\n}\n"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Attributes/VerifiedFiles/ParamsAllValuesVerifyTests.BenchmarkShouldProduceSummary_WithAllValuesOfBool.verified.txt",
    "content": "﻿=== WithAllValuesOfBool ===\n\nBenchmarkDotNet v0.10.x-mock, Microsoft Windows NT 10.0.x.mock (Hyper-V)\nMockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\nFrequency: 2531248 Hz, Resolution: 395.062 ns, Timer: TSC\n  [Host]     : Clr 4.0.x.mock, 64mock RyuJIT-v4.6.x.mock CONFIGURATION\n  DefaultJob : extra output line\n\n\n Method    | ParamProperty | Mean     | Error   | StdDev  |\n---------- |-------------- |---------:|--------:|--------:|\n Benchmark | False         | 114.5 ns | 5.88 ns | 8.80 ns | ^\n Benchmark | True          | 214.5 ns | 5.88 ns | 8.80 ns | ^\n\nErrors: 0\n"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Attributes/VerifiedFiles/ParamsAllValuesVerifyTests.BenchmarkShouldProduceSummary_WithAllValuesOfEnum.verified.txt",
    "content": "﻿=== WithAllValuesOfEnum ===\n\nBenchmarkDotNet v0.10.x-mock, Microsoft Windows NT 10.0.x.mock (Hyper-V)\nMockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\nFrequency: 2531248 Hz, Resolution: 395.062 ns, Timer: TSC\n  [Host]     : Clr 4.0.x.mock, 64mock RyuJIT-v4.6.x.mock CONFIGURATION\n  DefaultJob : extra output line\n\n\n Method    | ParamProperty | Mean     | Error   | StdDev  |\n---------- |-------------- |---------:|--------:|--------:|\n Benchmark | A             | 114.5 ns | 5.88 ns | 8.80 ns | ^\n Benchmark | B             | 214.5 ns | 5.88 ns | 8.80 ns | ^\n Benchmark | C             | 314.5 ns | 5.88 ns | 8.80 ns | ^\n\nErrors: 0\n"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Attributes/VerifiedFiles/ParamsAllValuesVerifyTests.BenchmarkShouldProduceSummary_WithAllValuesOfNullableBool.verified.txt",
    "content": "﻿=== WithAllValuesOfNullableBool ===\n\nBenchmarkDotNet v0.10.x-mock, Microsoft Windows NT 10.0.x.mock (Hyper-V)\nMockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\nFrequency: 2531248 Hz, Resolution: 395.062 ns, Timer: TSC\n  [Host]     : Clr 4.0.x.mock, 64mock RyuJIT-v4.6.x.mock CONFIGURATION\n  DefaultJob : extra output line\n\n\n Method    | ParamProperty | Mean     | Error   | StdDev  |\n---------- |-------------- |---------:|--------:|--------:|\n Benchmark | ?             | 114.5 ns | 5.88 ns | 8.80 ns | ^\n Benchmark | False         | 214.5 ns | 5.88 ns | 8.80 ns | ^\n Benchmark | True          | 314.5 ns | 5.88 ns | 8.80 ns | ^\n\nErrors: 0\n"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Attributes/VerifiedFiles/ParamsAllValuesVerifyTests.BenchmarkShouldProduceSummary_WithAllValuesOfNullableEnum.verified.txt",
    "content": "﻿=== WithAllValuesOfNullableEnum ===\n\nBenchmarkDotNet v0.10.x-mock, Microsoft Windows NT 10.0.x.mock (Hyper-V)\nMockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\nFrequency: 2531248 Hz, Resolution: 395.062 ns, Timer: TSC\n  [Host]     : Clr 4.0.x.mock, 64mock RyuJIT-v4.6.x.mock CONFIGURATION\n  DefaultJob : extra output line\n\n\n Method    | ParamProperty | Mean     | Error   | StdDev  |\n---------- |-------------- |---------:|--------:|--------:|\n Benchmark | ?             | 114.5 ns | 5.88 ns | 8.80 ns | ^\n Benchmark | A             | 214.5 ns | 5.88 ns | 8.80 ns | ^\n Benchmark | B             | 314.5 ns | 5.88 ns | 8.80 ns | ^\n Benchmark | C             | 414.5 ns | 5.88 ns | 8.80 ns | ^\n\nErrors: 0\n"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Attributes/VerifiedFiles/ParamsAllValuesVerifyTests.BenchmarkShouldProduceSummary_WithNotAllowedFlagsEnumError.verified.txt",
    "content": "﻿=== WithNotAllowedFlagsEnumError ===\n\nBenchmarkDotNet v0.10.x-mock, Microsoft Windows NT 10.0.x.mock (Hyper-V)\nMockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\nFrequency: 2531248 Hz, Resolution: 395.062 ns, Timer: TSC\n  [Host]     : Clr 4.0.x.mock, 64mock RyuJIT-v4.6.x.mock CONFIGURATION\n  DefaultJob : extra output line\n\n\n Method    | ParamProperty | Mean     | Error   | StdDev  |\n---------- |-------------- |---------:|--------:|--------:|\n Benchmark | 0             | 114.5 ns | 5.88 ns | 8.80 ns |\n\nErrors: 1\n* Unable to use TestFlagsEnum with [ParamsAllValues], because it's flags enum.\n"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Attributes/VerifiedFiles/ParamsAllValuesVerifyTests.BenchmarkShouldProduceSummary_WithNotAllowedNullableTypeError.verified.txt",
    "content": "﻿=== WithNotAllowedNullableTypeError ===\n\nBenchmarkDotNet v0.10.x-mock, Microsoft Windows NT 10.0.x.mock (Hyper-V)\nMockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\nFrequency: 2531248 Hz, Resolution: 395.062 ns, Timer: TSC\n  [Host]     : Clr 4.0.x.mock, 64mock RyuJIT-v4.6.x.mock CONFIGURATION\n  DefaultJob : extra output line\n\n\n Method    | ParamProperty | Mean     | Error   | StdDev  |\n---------- |-------------- |---------:|--------:|--------:|\n Benchmark | ?             | 114.5 ns | 5.88 ns | 8.80 ns | ^\n Benchmark | 0             | 214.5 ns | 5.88 ns | 8.80 ns | ^\n\nErrors: 1\n* Type Int32 cannot be used with [ParamsAllValues], allowed types are: bool, enum types and nullable type for another allowed type.\n"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Attributes/VerifiedFiles/ParamsAllValuesVerifyTests.BenchmarkShouldProduceSummary_WithNotAllowedTypeError.verified.txt",
    "content": "﻿=== WithNotAllowedTypeError ===\n\nBenchmarkDotNet v0.10.x-mock, Microsoft Windows NT 10.0.x.mock (Hyper-V)\nMockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\nFrequency: 2531248 Hz, Resolution: 395.062 ns, Timer: TSC\n  [Host]     : Clr 4.0.x.mock, 64mock RyuJIT-v4.6.x.mock CONFIGURATION\n  DefaultJob : extra output line\n\n\n Method    | ParamProperty | Mean     | Error   | StdDev  |\n---------- |-------------- |---------:|--------:|--------:|\n Benchmark | 0             | 114.5 ns | 5.88 ns | 8.80 ns |\n\nErrors: 1\n* Type Int32 cannot be used with [ParamsAllValues], allowed types are: bool, enum types and nullable type for another allowed type.\n"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/BenchmarkDotNet.Tests.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\n  <Import Project=\"..\\..\\build\\common.props\" />\n  <PropertyGroup>\n    <AssemblyTitle>BenchmarkDotNet.Tests</AssemblyTitle>\n    <TargetFrameworks>net8.0;net10.0;net462</TargetFrameworks>\n    <AssemblyName>BenchmarkDotNet.Tests</AssemblyName>\n    <PackageId>BenchmarkDotNet.Tests</PackageId>\n    <GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>\n    <GenerateDocumentationFile>false</GenerateDocumentationFile>\n    <NoWarn>$(NoWarn);NU1701;1701;CA1018;CA2007;CA1825</NoWarn>\n  </PropertyGroup>\n  <ItemGroup>\n    <Content Include=\"xunit.runner.json\">\n      <CopyToOutputDirectory>Always</CopyToOutputDirectory>\n    </Content>\n  </ItemGroup>\n  <ItemGroup>\n    <PackageReference Include=\"AwesomeAssertions\" Version=\"9.4.0\" />\n    <PackageReference Include=\"Microsoft.NET.Test.Sdk\" Version=\"18.0.1\"/>\n    <PackageReference Include=\"Verify.Xunit\" Version=\"31.12.5\" />\n    <PackageReference Include=\"xunit\" Version=\"2.9.3\" />\n    <PackageReference Include=\"xunit.runner.visualstudio\" Version=\"[2.8.2]\">\n      <PrivateAssets>all</PrivateAssets>\n      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\n    </PackageReference>\n  </ItemGroup>\n  <ItemGroup Condition=\" '$(TargetFrameworkIdentifier)' == '.NETFramework' \">\n    <ProjectReference Include=\"..\\..\\src\\BenchmarkDotNet.Diagnostics.Windows\\BenchmarkDotNet.Diagnostics.Windows.csproj\" />\n    <PackageReference Include=\"Microsoft.NETCore.Platforms\" Version=\"7.0.4\" />\n    <PackageReference Include=\"System.Runtime.CompilerServices.Unsafe\" Version=\"6.1.2\" />\n    <Reference Include=\"System.Runtime\" />\n    <Reference Include=\"System.Threading.Tasks\" />\n    <Reference Include=\"System\" />\n    <Reference Include=\"Microsoft.CSharp\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ProjectReference Include=\"..\\..\\src\\BenchmarkDotNet.Diagnostics.dotTrace\\BenchmarkDotNet.Diagnostics.dotTrace.csproj\" />\n    <ProjectReference Include=\"..\\..\\src\\BenchmarkDotNet.Diagnostics.dotMemory\\BenchmarkDotNet.Diagnostics.dotMemory.csproj\" />\n    <ProjectReference Include=\"..\\..\\src\\BenchmarkDotNet\\BenchmarkDotNet.csproj\" />\n  </ItemGroup>\n  <ItemGroup>\n    <Service Include=\"{82a7f48d-3b50-4b1e-b82e-3ada8210c358}\" />\n  </ItemGroup>\n  <ItemGroup>\n    <EmbeddedResource Include=\"Detectors\\Cpu\\TestFiles\\*.txt\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Update=\"Detectors\\Cpu\\VerifiedFiles\\CpuInfoFormatterTests.FormatTest.verified.txt\">\n      <ParentFile>CpuInfoFormatterTests</ParentFile>\n      <DependentUpon>CpuInfoFormatterTests.cs</DependentUpon>\n    </None>\n  </ItemGroup>\n  <ItemGroup>\n    <Folder Include=\"Detectors\\\" />\n    <Folder Include=\"Perfonar\\VerifiedFiles\\\" />\n  </ItemGroup>\n  <Import Project=\"..\\..\\build\\common.targets\" />\n</Project>\n"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/BenchmarkDotNetInfoTests.cs",
    "content": "using System;\nusing BenchmarkDotNet.Properties;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests\n{\n    public class BenchmarkDotNetInfoTests\n    {\n        [Theory]\n        [InlineData(\"1.0.0\", \"1.0.0\", false, false, true)]\n        [InlineData(\"1.0.0\", \"1.0.0-develop\", true, false, false)]\n        [InlineData(\"1.0.0\", \"1.0.0-develop123\", true, false, false)]\n        [InlineData(\"1.2.3.4\", \"1.2.3.4\", false, true, false)]\n        public void BenchmarkDotNetInfoTest(string assemblyVersion, string fullVersion, bool expectedIsDevelop, bool expectedIsNightly,\n            bool expectedIsRelease)\n        {\n            var info = new BenchmarkDotNetInfo(Version.Parse(assemblyVersion), fullVersion);\n            Assert.Equal(expectedIsDevelop, info.IsDevelop);\n            Assert.Equal(expectedIsNightly, info.IsNightly);\n            Assert.Equal(expectedIsRelease, info.IsRelease);\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/BuildResultTests.cs",
    "content": "﻿using BenchmarkDotNet.Toolchains;\nusing BenchmarkDotNet.Toolchains.Results;\nusing JetBrains.Annotations;\nusing System;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests\n{\n    public class BuildResultTests\n    {\n        [Fact]\n        public void NotFullyCompatibleMsBuildErrorIsTranslatedToMoreUserFriendlyVersion()\n        {\n            const string msbuildError = @\"C:\\Program Files\\dotnet\\sdk\\3.0.100-preview9-013617\\Microsoft.Common.CurrentVersion.targets(1653,5): warning NU1702: ProjectReference 'C:\\Projects\\BenchmarkDotNet\\tests\\BenchmarkDotNet.IntegrationTests.SingleRuntime.DotNetFramework\\BenchmarkDotNet.IntegrationTests.SingleRuntime.DotNetFramework.csproj' was resolved using '.NETFramework,Version=v4.6.2' instead of the project target framework '.NETCoreApp,Version=v8.0'. This project may not be fully compatible with your project. [C:\\Projects\\BenchmarkDotNet\\tests\\BenchmarkDotNet.IntegrationTests\\bin\\Release\\net462\\Job-VUALUD\\BenchmarkDotNet.Autogenerated.csproj]\";\n\n            string expected = $@\"The project which defines benchmarks does not target 'net8.0'.\" + Environment.NewLine +\n                $\"You need to add 'net8.0' to <TargetFrameworks> in your project file \" +\n                @\"('C:\\Projects\\BenchmarkDotNet\\tests\\BenchmarkDotNet.IntegrationTests.SingleRuntime.DotNetFramework\\BenchmarkDotNet.IntegrationTests.SingleRuntime.DotNetFramework.csproj').\" + Environment.NewLine +\n                \"Example: <TargetFrameworks>net462;net8.0</TargetFrameworks>\";\n            Verify(msbuildError, true, expected);\n        }\n\n        [Fact]\n        public void NotCompatibleMsBuildErrorIsTranslatedToMoreUserFriendlyVersion()\n        {\n            const string msbuildError = @\"error NU1201: Project BenchmarkDotNet.IntegrationTests.SingleRuntime.DotNetCore is not compatible with net462 (.NETFramework,Version=v4.6.2) / win7-x64. Project BenchmarkDotNet.IntegrationTests.SingleRuntime.DotNetCore supports: net8.0 (.NETCoreApp,Version=v8.0)\";\n\n            string expected = $@\"The project which defines benchmarks does not target 'net462'.\" + Environment.NewLine +\n                $\"You need to add 'net462' to <TargetFrameworks> in your project file \" +\n                @\"('BenchmarkDotNet.IntegrationTests.SingleRuntime.DotNetCore').\" + Environment.NewLine +\n                \"Example: <TargetFrameworks>net8.0;net462</TargetFrameworks>\";\n\n            Verify(msbuildError, true, expected);\n        }\n\n        [Fact]\n        public void MissingSdkIsTranslatedToMoreUserFriendlyVersion()\n        {\n            const string msbuildError = @\"C:\\Program Files\\dotnet\\sdk\\3.0.100-preview9-013617\\Sdks\\Microsoft.NET.Sdk\\targets\\Microsoft.NET.TargetFrameworkInference.targets(134,5): error NETSDK1045: The current .NET SDK does not support targeting .NET Core 5.0.  Either target .NET Core 3.0 or lower, or use a version of the .NET SDK that supports .NET Core 5.0. [C:\\Projects\\BenchmarkDotNet\\samples\\BenchmarkDotNet.Samples\\bin\\Release\\net8.0\\bad57fca-694a-41ad-b630-9e5317a782ab\\BenchmarkDotNet.Autogenerated.csproj]\";\n\n            string expected = \"The current .NET SDK does not support targeting .NET Core 5.0. You need to install it or pass the path to dotnet cli via the `--cli` console line argument.\";\n\n            Verify(msbuildError, true, expected);\n        }\n\n        [Fact]\n        public void UnknownMSBuildErrorsAreNotTranslatedToMoreUserFriendlyVersions()\n        {\n            const string msbuildError = \"warning NU1702: something is broken\";\n\n            Verify(msbuildError, false, null);\n        }\n\n        [AssertionMethod]\n        private void Verify(string msbuildError, bool expectedResult, string? expectedReason)\n        {\n            var sut = BuildResult.Failure(GenerateResult.Success(ArtifactsPaths.Empty, []), msbuildError);\n\n            Assert.Equal(expectedResult, sut.TryToExplainFailureReason(out var reason));\n            Assert.Equal(expectedReason, reason);\n        }\n    }\n}\n"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Builders/HostEnvironmentInfoBuilder.cs",
    "content": "﻿using BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Portability;\nusing Perfolizer.Horology;\nusing Perfolizer.Models;\nusing System;\nusing System.Diagnostics.CodeAnalysis;\n\nnamespace BenchmarkDotNet.Tests.Builders\n{\n    [SuppressMessage(\"ReSharper\", \"InconsistentNaming\")]\n    public class HostEnvironmentInfoBuilder\n    {\n        private string architecture = \"64mock\";\n        private string benchmarkDotNetVersion = \"0.10.x-mock\";\n        private Frequency chronometerFrequency = new Frequency(2531248);\n        private string configuration = \"CONFIGURATION\";\n        private string dotNetSdkVersion = \"1.0.x.mock\";\n        private HardwareTimerKind hardwareTimerKind = HardwareTimerKind.Tsc;\n        private bool hasAttachedDebugger = false;\n        private bool hasRyuJit = true;\n        private bool isConcurrentGC = false;\n        private bool isServerGC = false;\n        private string jitInfo = \"RyuJIT-v4.6.x.mock\";\n        private string jitModules = \"clrjit-v4.6.x.mock\";\n        private OsInfo os = new() { Display = \"Microsoft Windows NT 10.0.x.mock\" };\n        private string runtimeVersion = \"Clr 4.0.x.mock\";\n\n        private readonly CpuInfo cpu = new()\n        {\n            ProcessorName = \"MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\",\n            PhysicalProcessorCount = 1,\n            PhysicalCoreCount = 4,\n            LogicalCoreCount = 8,\n            NominalFrequencyHz = Frequency.FromMHz(3100).Hertz.RoundToLong(),\n            MaxFrequencyHz = Frequency.FromMHz(3100).Hertz.RoundToLong()\n        };\n\n        private VirtualMachineHypervisor? virtualMachineHypervisor = HyperV.Default;\n\n        public HostEnvironmentInfoBuilder WithVMHypervisor(VirtualMachineHypervisor hypervisor)\n        {\n            virtualMachineHypervisor = hypervisor;\n            return this;\n        }\n\n        public HostEnvironmentInfoBuilder WithoutVMHypervisor()\n        {\n            virtualMachineHypervisor = null;\n            return this;\n        }\n\n        public HostEnvironmentInfoBuilder WithoutDotNetSdkVersion()\n        {\n            dotNetSdkVersion = \"\";\n            return this;\n        }\n\n        public HostEnvironmentInfo Build()\n        {\n            return new MockHostEnvironmentInfo(architecture, benchmarkDotNetVersion, chronometerFrequency, configuration,\n                dotNetSdkVersion, hardwareTimerKind, hasAttachedDebugger, hasRyuJit, isConcurrentGC, isServerGC,\n                jitInfo, jitModules, os, cpu, runtimeVersion, virtualMachineHypervisor, null);\n        }\n    }\n\n    internal class MockHostEnvironmentInfo : HostEnvironmentInfo\n    {\n        public MockHostEnvironmentInfo(\n            string architecture, string benchmarkDotNetVersion, Frequency chronometerFrequency, string configuration, string dotNetSdkVersion,\n            HardwareTimerKind hardwareTimerKind, bool hasAttachedDebugger, bool hasRyuJit, bool isConcurrentGC, bool isServerGC,\n            string jitInfo, string jitModules, OsInfo os, CpuInfo cpu,\n            string runtimeVersion, VirtualMachineHypervisor? virtualMachineHypervisor, PhysicalMemoryInfo? physicalMemory = null)\n        {\n            Architecture = architecture;\n            BenchmarkDotNetVersion = benchmarkDotNetVersion;\n            ChronometerFrequency = chronometerFrequency;\n            Configuration = configuration;\n            DotNetSdkVersion = new Lazy<string>(() => dotNetSdkVersion);\n            HardwareTimerKind = hardwareTimerKind;\n            HasAttachedDebugger = hasAttachedDebugger;\n            HasRyuJit = hasRyuJit;\n            IsConcurrentGC = isConcurrentGC;\n            IsServerGC = isServerGC;\n            JitInfo = jitInfo;\n            HardwareIntrinsicsShort = \"\";\n            Os = new Lazy<OsInfo>(() => os);\n            Cpu = new Lazy<CpuInfo>(() => cpu);\n            RuntimeVersion = runtimeVersion;\n            VirtualMachineHypervisor = new Lazy<VirtualMachineHypervisor?>(() => virtualMachineHypervisor);\n            PhysicalMemory = new Lazy<PhysicalMemoryInfo?>(() => physicalMemory);\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/CharacteristicPresenterTests.cs",
    "content": "﻿using BenchmarkDotNet.Characteristics;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Jobs;\nusing System;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests\n{\n    public class CharacteristicPresenterTests\n    {\n        [Theory]\n        [InlineData(1, 8, \"00000001\")]\n        [InlineData(8, 8, \"00001000\")]\n        [InlineData(0, 4, \"0000\")]\n        public void ProcessorAffinityIsPrintedAsBitMask(int mask, int processorCount, string expectedResult)\n        {\n            Assert.Equal(expectedResult, ((IntPtr)mask).ToPresentation(processorCount));\n        }\n\n        [Fact]\n        public void PowerPlanModeCharacteristicTest()\n        {\n            // null and Guid.Empty are both resolved as an empty string.\n            Validate(\"\", null);\n            Validate(\"\", Guid.Empty);\n\n            // Other value is resolved to guid text representation.\n            var guid = Guid.NewGuid();\n            Validate(guid.ToString(), guid);\n\n            static void Validate(string expected, Guid? guid)\n            {\n                var result = CharacteristicPresenter.DefaultPresenter.ToPresentation(guid, EnvironmentMode.PowerPlanModeCharacteristic);\n                Assert.Equal(expected, result);\n            }\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/CodeGeneratorTests.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing System.Reflection;\nusing Xunit;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Code;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Parameters;\nusing System.IO;\n\nnamespace BenchmarkDotNet.Tests\n{\n    public class CodeGeneratorTests\n    {\n        public static TheoryData<CodeGenBenchmarkRunCallType> CodeGenBenchmarkRunCallTypes => [.. Enum.GetValues<CodeGenBenchmarkRunCallType>()];\n\n        [Theory]\n        [MemberData(nameof(CodeGenBenchmarkRunCallTypes))]\n        public void AsyncVoidIsNotSupported(CodeGenBenchmarkRunCallType benchmarkRunCallType)\n        {\n            var asyncVoidMethod =\n                typeof(CodeGeneratorTests)\n                    .GetTypeInfo()\n                    .GetMethods()\n                    .Single(method => method.Name == nameof(AsyncVoidMethod));\n\n            var target = new Descriptor(typeof(CodeGeneratorTests), asyncVoidMethod);\n            var benchmark = BenchmarkCase.Create(target, Job.Default, ParameterInstances.Empty, ManualConfig.CreateEmpty().CreateImmutableConfig());\n\n            Assert.Throws<NotSupportedException>(() => CodeGenerator.Generate(new BuildPartition(\n                [new BenchmarkBuildInfo(benchmark, ManualConfig.CreateEmpty().CreateImmutableConfig(), 0, new([]))],\n                BenchmarkRunnerClean.DefaultResolver),\n                benchmarkRunCallType\n            ));\n        }\n\n        [Theory]\n        [MemberData(nameof(CodeGenBenchmarkRunCallTypes))]\n        public void UsingStatementsInTheAutoGeneratedCodeAreProhibited(CodeGenBenchmarkRunCallType benchmarkRunCallType)\n        {\n            var fineMethod =\n                typeof(CodeGeneratorTests)\n                    .GetTypeInfo()\n                    .GetMethods()\n                    .Single(method => method.Name == nameof(FineMethod));\n\n            var target = new Descriptor(typeof(CodeGeneratorTests), fineMethod);\n            var benchmark = BenchmarkCase.Create(target, Job.Default, ParameterInstances.Empty, ManualConfig.CreateEmpty().CreateImmutableConfig());\n\n            var generatedSourceFile = CodeGenerator.Generate(new BuildPartition(\n                [new BenchmarkBuildInfo(benchmark, ManualConfig.CreateEmpty().CreateImmutableConfig(), 0, new([]))],\n                BenchmarkRunnerClean.DefaultResolver),\n                benchmarkRunCallType\n            );\n\n            using (StringReader stringReader = new StringReader(generatedSourceFile))\n            {\n                string? line;\n                while ((line = stringReader.ReadLine()) != null && !line.StartsWith(\"namespace\"))\n                {\n                    Assert.False(line.Trim().StartsWith(\"using\"), line);\n                }\n            }\n        }\n\n#pragma warning disable CS1998\n#pragma warning disable xUnit1013 // Public method should be marked as test\n        [Benchmark]\n        public async void AsyncVoidMethod() { }\n\n        [Benchmark]\n        public void FineMethod() { }\n#pragma warning restore xUnit1013 // Public method should be marked as test\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Columns/MetricColumnTests.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Collections.Immutable;\nusing System.Diagnostics.CodeAnalysis;\nusing System.Globalization;\nusing System.Linq;\nusing BenchmarkDotNet.Columns;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Parameters;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Tests.Mocks;\nusing BenchmarkDotNet.Validators;\nusing Perfolizer.Horology;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests.Columns\n{\n    public class MetricColumnTests\n    {\n        [Theory]\n        [InlineData(false, false, 42_000.0, \"42000\")]\n        [InlineData(true, false, 42_000.0, \"42.0000 μs\")]\n        [InlineData(false, true, 42_000.0, \"42.0000\")]\n        [InlineData(true, true, 42_000.0, \"42.0000 μs\")]\n        public void GetValueTest(bool printUnitsInContent, bool printUnitsInHeader, double metricValue, string expected)\n        {\n            var column = new MetricColumn(LocalMetricDescriptor.TimeInstance);\n            var summary = CreateMockSummary(printUnitsInContent, printUnitsInHeader, TimeUnit.Microsecond, metricValue);\n            string actual = column.GetValue(summary, summary.BenchmarksCases.First(), summary.Style);\n            Assert.Equal(expected, actual);\n        }\n\n        private static Summary CreateMockSummary(bool printUnitsInContent, bool printUnitsInHeader, TimeUnit timeUnit, double metricValue)\n        {\n            var summaryStyle = new SummaryStyle(TestCultureInfo.Instance, printUnitsInHeader, null, timeUnit, printUnitsInContent);\n            var config = new ManualConfig().WithSummaryStyle(summaryStyle);\n            var benchmarkCase = new BenchmarkCase(\n                new Descriptor(MockFactory.MockType, MockFactory.MockMethodInfo),\n                Job.Dry,\n                new ParameterInstances([]),\n                ImmutableConfigBuilder.Create(config));\n            var metric = new Metric(LocalMetricDescriptor.TimeInstance, metricValue);\n            var benchmarkReport = new BenchmarkReport(true, benchmarkCase, null!, null!, null, [metric]);\n\n            return new Summary(\"\", new[] { benchmarkReport }.ToImmutableArray(), HostEnvironmentInfo.GetCurrent(),\n                \"\", \"\", TimeSpan.Zero, CultureInfo.InvariantCulture, [], []);\n        }\n\n        [SuppressMessage(\"ReSharper\", \"UnassignedGetOnlyAutoProperty\")]\n        private sealed class LocalMetricDescriptor : IMetricDescriptor\n        {\n            public static readonly IMetricDescriptor TimeInstance = new LocalMetricDescriptor(UnitType.Time);\n\n            private LocalMetricDescriptor(UnitType unitType)\n            {\n                UnitType = unitType;\n\n                Legend = default!;\n                NumberFormat = default!;\n                Unit = default!;\n            }\n\n            public string Id { get; } = nameof(LocalMetricDescriptor);\n            public string DisplayName => Id;\n            public string Legend { get; }\n            public string NumberFormat { get; }\n            public UnitType UnitType { get; }\n            public string Unit { get; }\n            public bool TheGreaterTheBetter { get; }\n            public int PriorityInCategory => 0;\n            public bool GetIsAvailable(Metric metric) => true;\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Columns/RatioColumnTest.cs",
    "content": "using System;\nusing System.Linq;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Tests.Mocks;\nusing Xunit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.Tests.Columns\n{\n    public class RatioColumnTest\n    {\n        private readonly ITestOutputHelper output;\n\n        public RatioColumnTest(ITestOutputHelper output)\n        {\n            this.output = output;\n        }\n\n        [Fact]\n        public void RatioColumnTest01()\n        {\n            var summary = MockRunner.Run<BenchmarkClass>(output, name => name switch\n            {\n                \"Foo\" => [2, 2, 2],\n                \"Bar\" => [4, 4, 4],\n                _ => throw new InvalidOperationException()\n            });\n\n            var ratioColumn = summary.GetColumns().FirstOrDefault(column => column.ColumnName == \"Ratio\");\n            Assert.NotNull(ratioColumn);\n\n            var fooCase = summary.BenchmarksCases.First(c => c.Descriptor.WorkloadMethod.Name == \"Foo\");\n            var barCase = summary.BenchmarksCases.First(c => c.Descriptor.WorkloadMethod.Name == \"Bar\");\n            Assert.Equal(\"1.00\", ratioColumn.GetValue(summary, fooCase));\n            Assert.Equal(\"2.00\", ratioColumn.GetValue(summary, barCase));\n        }\n\n        public class BenchmarkClass\n        {\n            [Benchmark(Baseline = true)]\n            public void Foo() { }\n\n            [Benchmark]\n            public void Bar() { }\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Columns/StatisticalTestColumnTests.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Linq;\nusing BenchmarkDotNet.Columns;\nusing BenchmarkDotNet.Mathematics;\nusing BenchmarkDotNet.Reports;\nusing Perfolizer.Mathematics.Distributions.ContinuousDistributions;\nusing Perfolizer.Metrology;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests.Columns\n{\n    public class StatisticalTestColumnTests\n    {\n        [Theory]\n        [InlineData(\"5%\")]\n        [InlineData(\"10ms\")]\n        public void NoDifferenceIfValuesAreTheSame(string threshold)\n        {\n            double[] values = Enumerable.Repeat(100.0, 20).ToArray();\n            Compare(threshold, values, values, \"Baseline\");\n        }\n\n        [Theory]\n        [InlineData(\"2%\")]\n        public void RegressionsAreDetected(string threshold)\n        {\n            double[]? baseline = [10.0, 10.01, 10.02, 10.0, 10.03, 10.02, 9.99, 9.98, 10.0, 10.02];\n            double[]? current = baseline.Select(value => value * 1.03).ToArray();\n\n            Compare(threshold, baseline, current, \"Slower\");\n        }\n\n        [Theory]\n        [InlineData(\"2%\")]\n        public void CanCompareDifferentSampleSizes(string threshold)\n        {\n            double[] baseline = new NormalDistribution(10, 0.01).Random(1729).Next(30);\n            double[] current = baseline\n                .Skip(1) // we skip one element to make sure the sample size is different\n                .Select(value => value * 1.03).ToArray();\n\n            Compare(threshold, baseline, current, \"Slower\");\n        }\n\n        [Theory]\n        [InlineData(\"2%\")]\n        public void ImprovementsDetected(string threshold)\n        {\n            var baseline = new[] { 10.0, 10.01, 10.02, 10.0, 10.03, 10.02, 9.99, 9.98, 10.0, 10.02 };\n            var current = baseline.Select(value => value * 0.97).ToArray();\n\n            Compare(threshold, baseline, current, \"Faster\");\n        }\n\n        private static void Compare(string threshold, double[] baseline, double[] current, string expectedResult)\n        {\n            var sut = new StatisticalTestColumn(Threshold.Parse(threshold));\n\n            var emptyMetrics = new Dictionary<string, Metric>();\n\n            Assert.Equal(expectedResult,\n                sut.GetValue(null!, null!, new Statistics(baseline), emptyMetrics, new Statistics(current), emptyMetrics, isBaseline: true));\n            Assert.Equal(expectedResult,\n                sut.GetValue(null!, null!, new Statistics(baseline), emptyMetrics, new Statistics(current), emptyMetrics, isBaseline: false));\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Columns/TagColumnTests.cs",
    "content": "using BenchmarkDotNet.Columns;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests.Columns\n{\n    public class TagColumnTests\n    {\n        [Fact]\n        public void TagColumnsHasDifferentIds() // #1146\n        {\n            var column1 = new TagColumn(\"A\", _ => _);\n            var column2 = new TagColumn(\"B\", _ => _);\n            Assert.NotEqual(column1.Id, column2.Id);\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Common/AbsoluteEqualityComparer.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace BenchmarkDotNet.Tests.Common;\n\npublic class AbsoluteEqualityComparer(double eps) : IEqualityComparer<double>\n{\n    public static readonly IEqualityComparer<double> E4 = new AbsoluteEqualityComparer(1e-4);\n    public static readonly IEqualityComparer<double> E5 = new AbsoluteEqualityComparer(1e-5);\n    public static readonly IEqualityComparer<double> E9 = new AbsoluteEqualityComparer(1e-9);\n\n    public bool Equals(double x, double y)\n    {\n        if (double.IsPositiveInfinity(x) && double.IsPositiveInfinity(y))\n            return true;\n        if (double.IsNegativeInfinity(x) && double.IsNegativeInfinity(y))\n            return true;\n        if (double.IsNaN(x) && double.IsNaN(y))\n            return true;\n        return Math.Abs(x - y) < eps;\n    }\n\n    public int GetHashCode(double x) => x.GetHashCode();\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/ConfigParserTests.cs",
    "content": "﻿using System.IO;\nusing System.Linq;\nusing System.Reflection;\nusing AwesomeAssertions;\nusing BenchmarkDotNet.Columns;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.ConsoleArguments;\nusing BenchmarkDotNet.Diagnosers;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Exporters;\nusing BenchmarkDotNet.Exporters.Csv;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Portability;\nusing BenchmarkDotNet.Tests.Loggers;\nusing BenchmarkDotNet.Tests.Mocks;\nusing BenchmarkDotNet.Tests.XUnit;\nusing BenchmarkDotNet.Toolchains;\nusing BenchmarkDotNet.Toolchains.CoreRun;\nusing BenchmarkDotNet.Toolchains.CsProj;\nusing BenchmarkDotNet.Toolchains.DotNetCli;\nusing BenchmarkDotNet.Toolchains.InProcess.Emit;\nusing BenchmarkDotNet.Toolchains.NativeAot;\nusing Perfolizer.Horology;\nusing Xunit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.Tests\n{\n    public class ConfigParserTests\n    {\n        public ITestOutputHelper Output { get; }\n\n        public ConfigParserTests(ITestOutputHelper output) => Output = output;\n\n        [Theory]\n        [InlineData(\"--job=dry\", \"--exporters\", \"html\", \"rplot\")]\n        [InlineData(\"--JOB=dry\", \"--EXPORTERS\", \"html\", \"rplot\")] // case insensitive\n        [InlineData(\"-j\", \"dry\", \"-e\", \"html\", \"rplot\")] // alias\n        public void SimpleConfigParsedCorrectly(params string[] args)\n        {\n            var config = ConfigParser.Parse(args, new OutputLogger(Output)).config;\n\n            Assert.NotNull(config);\n            Assert.Single(config.GetJobs());\n            Assert.Contains(Job.Dry, config.GetJobs());\n\n            Assert.Equal(3, config.GetExporters().Count()); // rplot must come together with CsvMeasurementsExporter\n            Assert.Contains(HtmlExporter.Default, config.GetExporters());\n            Assert.Contains(RPlotExporter.Default, config.GetExporters());\n            Assert.Contains(CsvMeasurementsExporter.Default, config.GetExporters());\n\n            Assert.Empty(config.GetColumnProviders());\n            Assert.Empty(config.GetDiagnosers());\n            Assert.Empty(config.GetAnalysers());\n            Assert.Empty(config.GetLoggers());\n        }\n\n        [Fact]\n        public void SimpleConfigAlternativeVersionParsedCorrectly()\n        {\n            var config = ConfigParser.Parse([\"--job=Dry\"], new OutputLogger(Output)).config;\n\n            Assert.NotNull(config);\n            Assert.Single(config.GetJobs());\n            Assert.Contains(Job.Dry, config.GetJobs());\n        }\n\n        [Fact]\n        public void UserCanSpecifyHowManyTimesTheBenchmarkShouldBeExecuted()\n        {\n            const int launchCount = 4;\n            const int warmupCount = 1;\n            const int iterationTime = 250;\n            const int iterationCount = 20;\n\n            var config = ConfigParser.Parse(\n            [\n                \"--LaunchCount\", launchCount.ToString(),\n                \"--warmupCount\", warmupCount.ToString(),\n                \"--iterationTime\", iterationTime.ToString(),\n                \"--iterationCount\", iterationCount.ToString()\n            ], new OutputLogger(Output)).config;\n\n            Assert.NotNull(config);\n            var job = config.GetJobs().Single();\n\n            Assert.Equal(launchCount, job.Run.LaunchCount);\n            Assert.Equal(warmupCount, job.Run.WarmupCount);\n            Assert.Equal(TimeInterval.FromMilliseconds(iterationTime), job.Run.IterationTime);\n            Assert.Equal(iterationCount, job.Run.IterationCount);\n        }\n\n        [Fact]\n        public void UserCanEasilyRequestToRunTheBenchmarkOncePerIteration()\n        {\n            var configEasy = ConfigParser.Parse([\"--runOncePerIteration\"], new OutputLogger(Output)).config;\n\n            Assert.NotNull(configEasy);\n            var easyJob = configEasy.GetJobs().Single();\n\n            Assert.Equal(1, easyJob.Run.UnrollFactor);\n            Assert.Equal(1, easyJob.Run.InvocationCount);\n        }\n\n        [Fact]\n        public void UserCanChooseStrategy()\n        {\n            var configEasy = ConfigParser.Parse([\"--strategy\", \"ColdStart\"], new OutputLogger(Output)).config;\n\n            Assert.NotNull(configEasy);\n            var job = configEasy.GetJobs().Single();\n\n            Assert.Equal(RunStrategy.ColdStart, job.Run.RunStrategy);\n        }\n\n        [Fact]\n        public void UserCanChooseInProcessAndStrategyMonitoring()\n        {\n            var configEasy = ConfigParser.Parse([\"--inProcess\", \"--strategy\", \"Monitoring\"], new OutputLogger(Output)).config;\n\n            Assert.NotNull(configEasy);\n            var job = configEasy.GetJobs().Single();\n\n            job.GetToolchain().Should().BeOfType<InProcessEmitToolchain>();\n            job.Run.RunStrategy.Should().Be(RunStrategy.Monitoring);\n        }\n\n        [FactEnvSpecific(\n            \"When CommandLineParser wants to display help, it tries to get the Title of the Entry Assembly which is an xunit runner, which has no Title and fails..\",\n            EnvRequirement.DotNetCoreOnly)]\n        public void UnknownConfigMeansFailure()\n        {\n            Assert.False(ConfigParser.Parse([\"--unknown\"], new OutputLogger(Output)).isSuccess);\n        }\n\n        [Fact]\n        public void EmptyArgsMeansConfigWithoutJobs()\n        {\n            var config = ConfigParser.Parse([], new OutputLogger(Output)).config;\n\n            Assert.NotNull(config);\n            Assert.Empty(config.GetJobs());\n        }\n\n        [Fact]\n        public void NonExistingPathMeansFailure()\n        {\n            string nonExistingFile = Path.Combine(Path.GetTempPath(), \"veryUniqueFileName.exe\");\n\n            Assert.False(ConfigParser.Parse([\"--cli\", nonExistingFile], new OutputLogger(Output)).isSuccess);\n            Assert.False(ConfigParser.Parse([\"--coreRun\", nonExistingFile], new OutputLogger(Output)).isSuccess);\n        }\n\n        [FactEnvSpecific(\"Detecting current version of .NET Core works only for .NET Core processes\", EnvRequirement.DotNetCoreOnly)]\n        public void CoreRunConfigParsedCorrectlyWhenRuntimeNotSpecified()\n        {\n            var fakeDotnetCliPath = typeof(object).Assembly.Location;\n            var fakeCoreRunPath = typeof(ConfigParserTests).Assembly.Location;\n            var fakeRestorePackages = Path.GetTempPath();\n            var config = ConfigParser.Parse([\"--job=Dry\", \"--coreRun\", fakeCoreRunPath, \"--cli\", fakeDotnetCliPath, \"--packages\", fakeRestorePackages],\n                new OutputLogger(Output)).config;\n\n            Assert.NotNull(config);\n            Assert.Single(config.GetJobs());\n            CoreRunToolchain? toolchain = config.GetJobs().Single().GetToolchain() as CoreRunToolchain;\n            Assert.NotNull(toolchain);\n            Assert.Equal(RuntimeInformation.GetCurrentRuntime().MsBuildMoniker,\n                ((DotNetCliGenerator)toolchain.Generator).TargetFrameworkMoniker); // runtime was not specified so the current was used\n            Assert.Equal(fakeCoreRunPath, toolchain.SourceCoreRun.FullName);\n            Assert.Equal(fakeDotnetCliPath, toolchain.CustomDotNetCliPath?.FullName);\n            Assert.Equal(fakeRestorePackages, toolchain.RestorePath?.FullName);\n        }\n\n        [FactEnvSpecific(\"It's impossible to determine TFM for CoreRunToolchain if host process is not .NET (Core) process\", EnvRequirement.FullFrameworkOnly)]\n        public void SpecifyingCoreRunWithFullFrameworkTargetsMostRecentTfm()\n        {\n            var fakePath = typeof(object).Assembly.Location;\n            var config = ConfigParser.Parse([\"--corerun\", fakePath], new OutputLogger(Output)).config;\n\n            Assert.NotNull(config);\n            Job coreRunJob = config.GetJobs().Single();\n\n            CoreRunToolchain coreRunToolchain = (CoreRunToolchain)coreRunJob.GetToolchain();\n            DotNetCliGenerator generator = (DotNetCliGenerator)coreRunToolchain.Generator;\n            Assert.Equal(\"net11.0\", generator.TargetFrameworkMoniker);\n        }\n\n        [FactEnvSpecific(\"It's impossible to determine TFM for CoreRunToolchain if host process is not .NET (Core) process\", EnvRequirement.DotNetCoreOnly)]\n        public void SpecifyingCoreRunAndRuntimeCreatesTwoJobs()\n        {\n            const string runtime = \"net8.0\";\n            var fakeDotnetCliPath = typeof(object).Assembly.Location;\n            var fakeCoreRunPath = typeof(ConfigParserTests).Assembly.Location;\n            var fakeRestorePackages = Path.GetTempPath();\n            var config = ConfigParser\n                .Parse([\"--job=Dry\", \"--coreRun\", fakeCoreRunPath, \"--cli\", fakeDotnetCliPath, \"--packages\", fakeRestorePackages, \"-r\", runtime],\n                    new OutputLogger(Output)).config;\n\n            Assert.NotNull(config);\n            Assert.Equal(2, config.GetJobs().Count());\n\n            Job coreRunJob = config.GetJobs().Single(job => job.GetToolchain() is CoreRunToolchain);\n            Job runtimeJob = config.GetJobs().Single(job => job.GetToolchain() is CsProjCoreToolchain);\n\n            CoreRunToolchain coreRunToolchain = (CoreRunToolchain)coreRunJob.GetToolchain();\n            DotNetCliGenerator generator = (DotNetCliGenerator)coreRunToolchain.Generator;\n            Assert.Equal(RuntimeInformation.GetCurrentRuntime().MsBuildMoniker, generator.TargetFrameworkMoniker);\n            Assert.Equal(fakeCoreRunPath, coreRunToolchain.SourceCoreRun.FullName);\n            Assert.Equal(fakeDotnetCliPath, coreRunToolchain.CustomDotNetCliPath?.FullName);\n            Assert.Equal(fakeRestorePackages, coreRunToolchain.RestorePath?.FullName);\n\n            CsProjCoreToolchain coreToolchain = (CsProjCoreToolchain)runtimeJob.GetToolchain();\n            generator = (DotNetCliGenerator)coreToolchain.Generator;\n            Assert.Equal(runtime, ((DotNetCliGenerator)coreToolchain.Generator).TargetFrameworkMoniker);\n            Assert.Equal(fakeDotnetCliPath, coreToolchain.CustomDotNetCliPath);\n            Assert.Equal(fakeRestorePackages, generator.PackagesPath);\n        }\n\n        [FactEnvSpecific(\"It's impossible to determine TFM for CoreRunToolchain if host process is not .NET (Core) process\", EnvRequirement.DotNetCoreOnly)]\n        public void FirstJobIsBaseline_RuntimesCoreRun()\n        {\n            const string runtime1 = \"net5.0\";\n            const string runtime2 = \"net6.0\";\n            string fakePath = typeof(object).Assembly.Location;\n            var config = ConfigParser.Parse([\"--runtimes\", runtime1, runtime2, \"--coreRun\", fakePath], new OutputLogger(Output)).config;\n\n            Assert.NotNull(config);\n            Assert.Equal(3, config.GetJobs().Count());\n            Job baselineJob = config.GetJobs().Single(job => job.Meta.Baseline == true);\n            Assert.False(baselineJob.GetToolchain() is CoreRunToolchain);\n            Assert.Equal(runtime1, ((DotNetCliGenerator)baselineJob.GetToolchain().Generator).TargetFrameworkMoniker);\n        }\n\n        [FactEnvSpecific(\"It's impossible to determine TFM for CoreRunToolchain if host process is not .NET (Core) process\", EnvRequirement.DotNetCoreOnly)]\n        public void FirstJobIsBaseline_CoreRunsRuntimes()\n        {\n            const string runtime1 = \"net5.0\";\n            const string runtime2 = \"net6.0\";\n            string fakePath1 = typeof(object).Assembly.Location;\n            string fakePath2 = typeof(FactAttribute).Assembly.Location;\n            var config = ConfigParser.Parse([\"--coreRun\", fakePath1, fakePath2, \"--runtimes\", runtime1, runtime2], new OutputLogger(Output)).config;\n\n            Assert.NotNull(config);\n            Assert.Equal(4, config.GetJobs().Count());\n            Job baselineJob = config.GetJobs().Single(job => job.Meta.Baseline == true);\n            Assert.Equal(fakePath1, ((CoreRunToolchain)baselineJob.GetToolchain()).SourceCoreRun.FullName);\n        }\n\n        [FactEnvSpecific(\"It's impossible to determine TFM for CoreRunToolchain if host process is not .NET (Core) process\", EnvRequirement.DotNetCoreOnly)]\n        public void UserCanSpecifyMultipleCoreRunPaths()\n        {\n            var fakeCoreRunPath_1 = typeof(object).Assembly.Location;\n            var fakeCoreRunPath_2 = typeof(ConfigParserTests).Assembly.Location;\n\n            var config = ConfigParser.Parse([\"--job=Dry\", \"--coreRun\", fakeCoreRunPath_1, fakeCoreRunPath_2], new OutputLogger(Output)).config;\n\n            Assert.NotNull(config);\n            var jobs = config.GetJobs().ToArray();\n            Assert.Equal(2, jobs.Length);\n            Assert.Single(jobs, job => job.GetToolchain() is CoreRunToolchain toolchain && toolchain.SourceCoreRun.FullName == fakeCoreRunPath_1);\n            Assert.Single(jobs, job => job.GetToolchain() is CoreRunToolchain toolchain && toolchain.SourceCoreRun.FullName == fakeCoreRunPath_2);\n        }\n\n        [Fact]\n        public void MonoPathParsedCorrectly()\n        {\n            var fakeMonoPath = typeof(object).Assembly.Location;\n            var config = ConfigParser.Parse([\"-r\", \"mono\", \"--monoPath\", fakeMonoPath], new OutputLogger(Output)).config;\n\n            Assert.NotNull(config);\n            Assert.Single(config.GetJobs());\n            Assert.Single(config.GetJobs(), job => job.Environment.Runtime is MonoRuntime mono && mono.CustomPath == fakeMonoPath);\n        }\n\n        [FactEnvSpecific(\"Testing local builds of Full .NET Framework is supported only on Windows\", EnvRequirement.WindowsOnly)]\n        public void ClrVersionParsedCorrectly()\n        {\n            const string clrVersion = \"secret\";\n            var config = ConfigParser.Parse([\"--clrVersion\", clrVersion], new OutputLogger(Output)).config;\n\n            Assert.NotNull(config);\n            Assert.Single(config.GetJobs());\n            Assert.Single(config.GetJobs(), job => job.Environment.Runtime is ClrRuntime clr && clr.Version == clrVersion);\n        }\n\n        [Fact]\n        public void IlCompilerPathParsedCorrectly()\n        {\n            var fakePath = new FileInfo(typeof(ConfigParserTests).Assembly.Location).Directory!;\n            var config = ConfigParser.Parse([\"-r\", \"nativeaot60\", \"--ilcPackages\", fakePath.FullName], new OutputLogger(Output)).config;\n\n            Assert.NotNull(config);\n            Assert.Single(config.GetJobs());\n            NativeAotToolchain? toolchain = config.GetJobs().Single().GetToolchain() as NativeAotToolchain;\n            Assert.NotNull(toolchain);\n            Generator generator = (Generator)toolchain.Generator;\n            Assert.Equal(fakePath.FullName, generator.Feeds[\"local\"]);\n        }\n\n        [Theory]\n        [InlineData(\"netcoreapp2.0\", true)]\n        [InlineData(\"netcoreapp2.1\", true)]\n        [InlineData(\"netcoreapp2.2\", true)]\n        [InlineData(\"netcoreapp3.0\", true)]\n        [InlineData(\"netcoreapp3.1\", true)]\n        [InlineData(\"net5.0\", true)]\n        [InlineData(\"net6.0\", true)]\n        [InlineData(\"net7.0\", true)]\n        [InlineData(\"net8.0\", true)]\n        [InlineData(\"net9.0\", true)]\n        [InlineData(\"net462\", false)]\n        [InlineData(\"net48\", false)]\n        public void DotNetCliParsedCorrectly(string tfm, bool isCore)\n        {\n            var fakeDotnetCliPath = typeof(object).Assembly.Location;\n            var config = ConfigParser.Parse([\"-r\", tfm, \"--cli\", fakeDotnetCliPath], new OutputLogger(Output)).config;\n\n            Assert.NotNull(config);\n            Assert.Single(config.GetJobs());\n            var toolchain = config.GetJobs().Single().GetToolchain();\n            if (isCore)\n            {\n                Assert.True(toolchain is CsProjCoreToolchain);\n                Assert.Equal(fakeDotnetCliPath, ((CsProjCoreToolchain)toolchain).CustomDotNetCliPath);\n            }\n            else\n            {\n                Assert.True(toolchain is CsProjClassicNetToolchain);\n                Assert.Equal(fakeDotnetCliPath, ((CsProjClassicNetToolchain)toolchain).CustomDotNetCliPath);\n            }\n            Assert.Equal(tfm, ((DotNetCliGenerator)toolchain.Generator).TargetFrameworkMoniker);\n        }\n\n        [Theory]\n        [InlineData(ConfigOptions.JoinSummary, \"--join\")]\n        [InlineData(ConfigOptions.KeepBenchmarkFiles, \"--keepFiles\")]\n        [InlineData(ConfigOptions.DontOverwriteResults, \"--noOverwrite\")]\n        [InlineData(ConfigOptions.StopOnFirstError, \"--stopOnFirstError\")]\n        [InlineData(ConfigOptions.DisableLogFile, \"--disableLogFile\")]\n        [InlineData(ConfigOptions.LogBuildOutput, \"--logBuildOutput\")]\n        [InlineData(ConfigOptions.GenerateMSBuildBinLog | ConfigOptions.KeepBenchmarkFiles, \"--generateBinLog\")]\n        [InlineData(\n            ConfigOptions.JoinSummary |\n            ConfigOptions.KeepBenchmarkFiles |\n            ConfigOptions.DontOverwriteResults |\n            ConfigOptions.StopOnFirstError |\n            ConfigOptions.DisableLogFile, \"--join\", \"--keepFiles\", \"--noOverwrite\", \"--stopOnFirstError\", \"--disableLogFile\")]\n        [InlineData(\n            ConfigOptions.JoinSummary |\n            ConfigOptions.KeepBenchmarkFiles |\n            ConfigOptions.StopOnFirstError, \"--join\", \"--keepFiles\", \"--stopOnFirstError\")]\n        public void ConfigOptionsParsedCorrectly(ConfigOptions expectedConfigOption, params string[] configOptionArgs)\n        {\n            var config = ConfigParser.Parse(configOptionArgs, new OutputLogger(Output)).config;\n\n            Assert.NotNull(config);\n            Assert.Equal(expectedConfigOption, config.Options);\n            Assert.NotEqual(ConfigOptions.Default, config.Options);\n        }\n\n        [Fact]\n        public void WhenConfigOptionsFlagsAreNotSpecifiedTheyAreNotSet()\n        {\n            var config = ConfigParser.Parse([], new OutputLogger(Output)).config;\n\n            Assert.NotNull(config);\n            Assert.Equal(ConfigOptions.Default, config.Options);\n        }\n\n        [Fact]\n        public void PackagesPathParsedCorrectly()\n        {\n            var fakeRestoreDirectory = new FileInfo(typeof(object).Assembly.Location).Directory!.FullName;\n            var config = ConfigParser.Parse([\"-r\", \"netcoreapp3.1\", \"--packages\", fakeRestoreDirectory], new OutputLogger(Output)).config;\n\n            Assert.NotNull(config);\n            Assert.Single(config.GetJobs());\n            var toolchain = config.GetJobs().Single().GetToolchain() as CsProjCoreToolchain;\n            Assert.NotNull(toolchain);\n            Assert.Equal(fakeRestoreDirectory, ((DotNetCliGenerator)toolchain.Generator).PackagesPath);\n        }\n\n        [Fact]\n        public void UserCanSpecifyBuildTimeout()\n        {\n            const int timeoutInSeconds = 10;\n            var config = ConfigParser.Parse([\"-r\", \"netcoreapp3.1\", \"--buildTimeout\", timeoutInSeconds.ToString()], new OutputLogger(Output)).config;\n\n            Assert.NotNull(config);\n            Assert.Single(config.GetJobs());\n            var toolchain = config.GetJobs().Single().GetToolchain() as CsProjCoreToolchain;\n            Assert.NotNull(toolchain);\n            Assert.Equal(timeoutInSeconds, config.BuildTimeout.TotalSeconds);\n        }\n\n        [Fact]\n        public void WhenUserDoesNotSpecifyTimeoutTheDefaultValueIsUsed()\n        {\n            var config = ConfigParser.Parse([\"-r\", \"netcoreapp3.1\"], new OutputLogger(Output)).config;\n\n            Assert.NotNull(config);\n            Assert.Single(config.GetJobs());\n            var toolchain = config.GetJobs().Single().GetToolchain() as CsProjCoreToolchain;\n            Assert.NotNull(toolchain);\n            Assert.Equal(DefaultConfig.Instance.BuildTimeout, config.BuildTimeout);\n        }\n\n        [Fact]\n        public void UserCanSpecifyWakeLock()\n        {\n            var config = ConfigParser.Parse([\"--wakeLock\", \"Display\"], new OutputLogger(Output)).config;\n\n            Assert.NotNull(config);\n            Assert.Equal(WakeLockType.Display, config.WakeLock);\n        }\n\n        [Fact]\n        public void WhenUserDoesNotSpecifyWakeLockTheDefaultValueIsUsed()\n        {\n            var config = ConfigParser.Parse([], new OutputLogger(Output)).config;\n\n            Assert.NotNull(config);\n            Assert.Equal(DefaultConfig.Instance.WakeLock, config.WakeLock);\n        }\n\n        [Theory]\n        [InlineData(\"net461\")]\n        [InlineData(\"net462\")]\n        [InlineData(\"net47\")]\n        [InlineData(\"net471\")]\n        [InlineData(\"net472\")]\n        [InlineData(\"net48\")]\n        [InlineData(\"net481\")]\n        public void NetFrameworkMonikerParsedCorrectly(string tfm)\n        {\n            var config = ConfigParser.Parse([\"-r\", tfm], new OutputLogger(Output)).config;\n\n            Assert.NotNull(config);\n            Assert.Single(config.GetJobs());\n            CsProjClassicNetToolchain? toolchain = config.GetJobs().Single().GetToolchain() as CsProjClassicNetToolchain;\n            Assert.NotNull(toolchain);\n            Assert.Equal(tfm, ((DotNetCliGenerator)toolchain.Generator).TargetFrameworkMoniker);\n        }\n\n        [Theory]\n        [InlineData(\"net50\")]\n        [InlineData(\"net5.0\")]\n        [InlineData(\"net60\")]\n        [InlineData(\"net6.0\")]\n        [InlineData(\"net70\")]\n        [InlineData(\"net7.0\")]\n        [InlineData(\"net80\")]\n        [InlineData(\"net8.0\")]\n        [InlineData(\"net90\")]\n        [InlineData(\"net9.0\")]\n        [InlineData(\"net10_0\")]\n        [InlineData(\"net10.0\")]\n        [InlineData(\"net11_0\")]\n        [InlineData(\"net11.0\")]\n        public void NetMonikersAreRecognizedAsNetCoreMonikers(string tfm)\n        {\n            var config = ConfigParser.Parse([\"-r\", tfm], new OutputLogger(Output)).config;\n\n            Assert.NotNull(config);\n            Assert.Single(config.GetJobs());\n            var toolchain = config.GetJobs().Single().GetToolchain() as CsProjCoreToolchain;\n            Assert.NotNull(toolchain);\n            Assert.Equal(tfm, ((DotNetCliGenerator)toolchain.Generator).TargetFrameworkMoniker);\n        }\n\n        [Theory]\n        [InlineData(\"net5.0-windows\")]\n        [InlineData(\"net5.0-ios\")]\n        public void PlatformSpecificMonikersAreSupported(string msBuildMoniker)\n        {\n            var config = ConfigParser.Parse([\"-r\", msBuildMoniker], new OutputLogger(Output)).config;\n\n            Assert.NotNull(config);\n            Assert.Single(config.GetJobs());\n            var toolchain = config.GetJobs().Single().GetToolchain() as CsProjCoreToolchain;\n            Assert.NotNull(toolchain);\n            Assert.Equal(msBuildMoniker, ((DotNetCliGenerator)toolchain.Generator).TargetFrameworkMoniker);\n        }\n\n        [Fact]\n        public void CanCompareFewDifferentRuntimes()\n        {\n            var config = ConfigParser.Parse([\"--runtimes\", \"net462\", \"MONO\", \"netcoreapp2.0\", \"nativeaot6.0\", \"nativeAOT7.0\", \"nativeAOT8.0\"],\n                new OutputLogger(Output)).config;\n\n            Assert.NotNull(config);\n            Assert.True(config.GetJobs().First().Meta.Baseline); // when the user provides multiple runtimes the first one should be marked as baseline\n            Assert.Single(config.GetJobs(), job => job.Environment.Runtime is ClrRuntime clrRuntime && clrRuntime.MsBuildMoniker == \"net462\");\n            Assert.Single(config.GetJobs(), job => job.Environment.Runtime is MonoRuntime);\n            Assert.Single(config.GetJobs(), job =>\n                job.Environment.Runtime is CoreRuntime coreRuntime && coreRuntime.MsBuildMoniker == \"netcoreapp2.0\" &&\n                coreRuntime.RuntimeMoniker == RuntimeMoniker.NetCoreApp20);\n            Assert.Single(config.GetJobs(), job =>\n                job.Environment.Runtime is NativeAotRuntime nativeAot && nativeAot.MsBuildMoniker == \"net6.0\" &&\n                nativeAot.RuntimeMoniker == RuntimeMoniker.NativeAot60);\n            Assert.Single(config.GetJobs(), job =>\n                job.Environment.Runtime is NativeAotRuntime nativeAot && nativeAot.MsBuildMoniker == \"net7.0\" &&\n                nativeAot.RuntimeMoniker == RuntimeMoniker.NativeAot70);\n            Assert.Single(config.GetJobs(), job =>\n                job.Environment.Runtime is NativeAotRuntime nativeAot && nativeAot.MsBuildMoniker == \"net8.0\" &&\n                nativeAot.RuntimeMoniker == RuntimeMoniker.NativeAot80);\n        }\n\n        [Theory]\n        [InlineData(\"5%\")]\n        [InlineData(\"10ms\")]\n        public void CanUseStatisticalTestsToCompareFewDifferentRuntimes(string threshold)\n        {\n            string[] arguments = [\"--runtimes\", \"net6.0\", \"net8.0\", \"--statisticalTest\", threshold];\n            var config = ConfigParser.Parse(arguments, new OutputLogger(Output)).config;\n            Assert.NotNull(config);\n\n            var mockSummary = MockFactory.CreateSummary(config);\n\n            Assert.True(config.GetJobs().First().Meta.Baseline); // when the user provides multiple runtimes the first one should be marked as baseline\n            Assert.False(config.GetJobs().Last().Meta.Baseline);\n\n            var statisticalTestColumn = config.GetColumnProviders().SelectMany(columnProvider => columnProvider.GetColumns(mockSummary))\n                .OfType<StatisticalTestColumn>().Single();\n\n            Assert.Equal(threshold, statisticalTestColumn.Threshold.ToString());\n        }\n\n        [Fact]\n        public void SpecifyingInvalidStatisticalTestsThresholdMeansFailure()\n        {\n            Assert.False(ConfigParser.Parse([\"--statisticalTest\", \"not a number\"], new OutputLogger(Output)).isSuccess);\n            Assert.False(ConfigParser.Parse([\"--statisticalTest\", \"1unknownUnit\"], new OutputLogger(Output)).isSuccess);\n            Assert.False(ConfigParser.Parse([\"--statisticalTest\", \"1 unknownUnit\"], new OutputLogger(Output)).isSuccess);\n            Assert.False(ConfigParser.Parse([\"--statisticalTest\", \"%1\"], new OutputLogger(Output)).isSuccess); // reverse order - a typo\n        }\n\n        [Fact]\n        public void CanParseHardwareCounters()\n        {\n            var config = ConfigParser.Parse([\"--counters\", $\"{nameof(HardwareCounter.CacheMisses)}+{nameof(HardwareCounter.InstructionRetired)}\"],\n                new OutputLogger(Output)).config;\n\n            Assert.NotNull(config);\n            Assert.Equal(2, config.GetHardwareCounters().Count());\n            Assert.Single(config.GetHardwareCounters(), counter => counter == HardwareCounter.CacheMisses);\n            Assert.Single(config.GetHardwareCounters(), counter => counter == HardwareCounter.InstructionRetired);\n        }\n\n        [Fact]\n        public void InvalidHardwareCounterNameMeansFailure()\n        {\n            Assert.False(ConfigParser.Parse([\"--counters\", \"WRONG_NAME\"], new OutputLogger(Output)).isSuccess);\n        }\n\n        [Fact]\n        public void TooManyHardwareCounterNameMeansFailure()\n        {\n            Assert.False(ConfigParser.Parse([\"--counters\", \"Timer+TotalIssues+BranchInstructions+CacheMisses\"], new OutputLogger(Output)).isSuccess);\n        }\n\n        [Fact]\n        public void CanParseDisassemblerWithCustomRecursiveDepth()\n        {\n            const int depth = 123;\n\n            var config = ConfigParser.Parse([\"--disasm\", \"--disasmDepth\", depth.ToString()], new OutputLogger(Output)).config;\n            Assert.NotNull(config);\n\n            var diagnoser = config.GetDiagnosers().OfType<DisassemblyDiagnoser>().Single();\n\n            Assert.Equal(depth, diagnoser.Config.MaxDepth);\n        }\n\n        [Fact]\n        public void WhenCustomDisassemblerSettingsAreProvidedItsEnabledByDefault()\n        {\n            Verify([\"--disasmDepth\", \"2\"]);\n            Verify([\"--disasmFilter\", \"*\"]);\n\n            void Verify(string[] args)\n            {\n                var config = ConfigParser.Parse(args, new OutputLogger(Output)).config;\n                Assert.NotNull(config);\n                Assert.Single(config.GetDiagnosers().OfType<DisassemblyDiagnoser>());\n            }\n        }\n\n        [Fact]\n        public void CanParseInfo()\n        {\n            var config = ConfigParser.Parse([\"--info\"], new OutputLogger(Output)).options;\n\n            Assert.NotNull(config);\n            Assert.True(config.PrintInformation);\n        }\n\n        [Fact]\n        public void UserCanSpecifyCustomDefaultJobAndOverwriteItsSettingsViaConsoleArgs()\n        {\n            var globalConfig = DefaultConfig.Instance\n                .AddJob(Job.Default\n                    .WithWarmupCount(1)\n                    .AsDefault());\n\n            var parsedConfig = ConfigParser.Parse([\"--warmupCount\", \"2\"], new OutputLogger(Output), globalConfig).config;\n\n            Assert.NotNull(parsedConfig);\n            Assert.Equal(2, parsedConfig.GetJobs().Single().Run.WarmupCount);\n            Assert.False(parsedConfig.GetJobs().Single().Meta.IsDefault); // after the merge the job is not \"default\" anymore\n        }\n\n        [Fact]\n        public void UserCanSpecifyCustomMaxParameterColumnWidth()\n        {\n            const int customValue = 1234;\n\n            var globalConfig = DefaultConfig.Instance;\n\n            Assert.NotNull(globalConfig);\n            Assert.NotNull(globalConfig.SummaryStyle);\n            Assert.NotEqual(customValue, globalConfig.SummaryStyle.MaxParameterColumnWidth);\n\n            var parsedConfig = ConfigParser.Parse([\"--maxWidth\", customValue.ToString()], new OutputLogger(Output), globalConfig).config;\n            Assert.NotNull(parsedConfig);\n            Assert.NotNull(parsedConfig.SummaryStyle);\n            Assert.Equal(customValue, parsedConfig.SummaryStyle.MaxParameterColumnWidth);\n        }\n\n        [Fact]\n        public void UserCanSpecifyEnvironmentVariables()\n        {\n            const string key = \"A_VERY_NICE_ENV_VAR\";\n            const string value = \"enabled\";\n\n            var parsedConfig = ConfigParser.Parse([\"--envVars\", $\"{key}:{value}\"], new OutputLogger(Output)).config;\n            Assert.NotNull(parsedConfig);\n\n            var job = parsedConfig.GetJobs().Single();\n            var envVar = job.Environment.EnvironmentVariables.Single();\n\n            Assert.Equal(key, envVar.Key);\n            Assert.Equal(value, envVar.Value);\n        }\n\n        [Theory]\n        [InlineData(Platform.AnyCpu)]\n        [InlineData(Platform.X86)]\n        [InlineData(Platform.X64)]\n        [InlineData(Platform.Arm)]\n        [InlineData(Platform.Arm64)]\n        [InlineData(Platform.LoongArch64)]\n        public void UserCanSpecifyProcessPlatform(Platform platform)\n        {\n            var parsedConfig = ConfigParser.Parse([\"--platform\", platform.ToString()], new OutputLogger(Output)).config;\n            Assert.NotNull(parsedConfig);\n\n            var job = parsedConfig.GetJobs().Single();\n\n            var parsed = job.Environment.Platform;\n\n            Assert.Equal(platform, parsed);\n        }\n\n        [Fact]\n        public void InvalidEnvVarAreRecognized()\n        {\n            Assert.False(ConfigParser.Parse([\"--envVars\", \"INVALID_NO_SEPARATOR\"], new OutputLogger(Output)).isSuccess);\n        }\n\n        [Fact]\n        public void UserCanSpecifyNoForceGCs()\n        {\n            var parsedConfiguration = ConfigParser.Parse([\"--noForcedGCs\"], new OutputLogger(Output));\n            Assert.NotNull(parsedConfiguration.config);\n            Assert.True(parsedConfiguration.isSuccess);\n\n            foreach (var job in parsedConfiguration.config.GetJobs())\n            {\n                Assert.False(job.Environment.Gc.Force);\n            }\n        }\n\n        [Fact]\n        public void UsersCanSpecifyWithoutOverheadEvalution()\n        {\n            var parsedConfiguration = ConfigParser.Parse([\"--noOverheadEvaluation\"], new OutputLogger(Output));\n            Assert.NotNull(parsedConfiguration.config);\n            Assert.True(parsedConfiguration.isSuccess);\n\n            foreach (var job in parsedConfiguration.config.GetJobs())\n            {\n                Assert.False(job.Accuracy.EvaluateOverhead);\n            }\n        }\n\n        [Fact(Skip = \"This should be handled somehow at CommandLineParser level. See https://github.com/commandlineparser/commandline/pull/892\")]\n        public void UserCanSpecifyWasmArgs()\n        {\n            var parsedConfiguration = ConfigParser.Parse([\"--runtimes\", \"wasmnet80\", \"--wasmArgs\", \"--expose_wasm --module\", GetDummyWasmEngine()], new OutputLogger(Output));\n            Assert.True(parsedConfiguration.isSuccess);\n            Assert.NotNull(parsedConfiguration.config);\n            var jobs = parsedConfiguration.config.GetJobs();\n            foreach (var job in parsedConfiguration.config.GetJobs())\n            {\n                var wasmRuntime = Assert.IsType<WasmRuntime>(job.Environment.Runtime);\n                Assert.Equal(\" --expose_wasm --module\", wasmRuntime.JavaScriptEngineArguments);\n            }\n        }\n\n        [Fact]\n        public void UserCanSpecifyWasmArgsUsingEquals()\n        {\n            var parsedConfiguration = ConfigParser.Parse([\"--runtimes\", \"wasmnet80\", \"--wasmArgs=--expose_wasm --module\" , GetDummyWasmEngine()], new OutputLogger(Output));\n            Assert.True(parsedConfiguration.isSuccess);\n            Assert.NotNull(parsedConfiguration.config);\n            var jobs = parsedConfiguration.config.GetJobs();\n            foreach (var job in parsedConfiguration.config.GetJobs())\n            {\n                var wasmRuntime = Assert.IsType<WasmRuntime>(job.Environment.Runtime);\n                Assert.Equal(\"--expose_wasm --module\", wasmRuntime.JavaScriptEngineArguments);\n            }\n        }\n\n        [Fact]\n        public void UserCanSpecifyWasmArgsViaResponseFile()\n        {\n            var tempResponseFile = Path.GetRandomFileName();\n            File.WriteAllLines(tempResponseFile,\n            [\n                \"--runtimes wasmnet80\",\n                \"--wasmArgs \\\"--expose_wasm --module\\\"\",\n                GetDummyWasmEngine()\n            ]);\n            var parsedConfiguration = ConfigParser.Parse([$\"@{tempResponseFile}\"], new OutputLogger(Output));\n            Assert.True(parsedConfiguration.isSuccess);\n            Assert.NotNull(parsedConfiguration.config);\n            var jobs = parsedConfiguration.config.GetJobs();\n            foreach (var job in parsedConfiguration.config.GetJobs())\n            {\n                var wasmRuntime = Assert.IsType<WasmRuntime>(job.Environment.Runtime);\n                // We may need change assertion to just \"--expose_wasm --module\"\n                // if https://github.com/commandlineparser/commandline/pull/892 lands\n                Assert.Equal(\" --expose_wasm --module\", wasmRuntime.JavaScriptEngineArguments);\n            }\n        }\n\n        [Fact]\n        public void UserCanSpecifyWasmMainJsTemplate()\n        {\n            var parsedConfiguration = ConfigParser.Parse([\"--runtimes\", \"wasmnet80\", \"--wasmMainJsTemplate\", \"./dummyFile.js\", GetDummyWasmEngine()], new OutputLogger(Output));\n            Assert.True(parsedConfiguration.isSuccess);\n            var job = parsedConfiguration.config!.GetJobs().Single();\n\n            var runtime = Assert.IsType<WasmRuntime>(job.Environment.Runtime);\n            Assert.Equal(\"dummyFile.js\", runtime.MainJsTemplate?.Name);\n        }\n\n        [Theory]\n        [InlineData(\"--filter abc\", \"--filter *\")]\n        [InlineData(\"-f abc\", \"--filter *\")]\n        [InlineData(\"-f *\", \"--filter *\")]\n        [InlineData(\"--runtimes net7.0 --join\", \"--filter * --join --runtimes net7.0\")]\n        [InlineData(\"--join abc\", \"--filter * --join\")]\n        public void CheckUpdateValidArgs(string strArgs, string expected)\n        {\n            var args = strArgs.Split();\n            _ = ConfigParser.TryUpdateArgs(args, out var updatedArgs, options => options.Filters = [\"*\"]);\n\n            Assert.Equal(expected.Split(), updatedArgs);\n        }\n\n        [Theory]\n        [InlineData(\"--filter abc -f abc\")]\n        [InlineData(\"--runtimes net\")]\n        public void CheckUpdateInvalidArgs(string strArgs)\n        {\n            var args = strArgs.Split();\n            bool isSuccess = ConfigParser.TryUpdateArgs(args, out var updatedArgs, options => options.Filters = [\"*\"]);\n\n            Assert.Null(updatedArgs);\n            Assert.False(isSuccess);\n        }\n\n        private string GetDummyWasmEngine()\n        {\n            // We know, that this file exists, that's enough.\n            return $\"--wasmEngine={Assembly.GetExecutingAssembly().Location}\";\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Configs/CategoriesTests.cs",
    "content": "using System;\nusing System.Linq;\nusing System.Reflection;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Running;\nusing Xunit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.Tests.Configs\n{\n    public class CategoriesTests\n    {\n        private readonly ITestOutputHelper output;\n\n        public CategoriesTests(ITestOutputHelper output)\n        {\n            this.output = output;\n        }\n\n        private void Check<T>(params string[] expected)\n        {\n            string Format(BenchmarkCase benchmarkCase) =>\n                benchmarkCase.Descriptor.WorkloadMethod.Name + \": \" +\n                string.Join(\"+\", benchmarkCase.Descriptor.Categories.OrderBy(category => category));\n\n            var actual = BenchmarkConverter\n                .TypeToBenchmarks(typeof(T))\n                .BenchmarksCases\n                .OrderBy(x => x.Descriptor.WorkloadMethod.Name)\n                .Select(Format)\n                .ToList();\n            foreach (string s in actual)\n                output.WriteLine(s);\n\n            Assert.Equal(expected, actual);\n        }\n\n        [Fact]\n        public void CategoryInheritanceTest() =>\n            Check<CategoryInheritanceTestScope.DerivedClass>(\n                \"BaseMethod: BaseClassCategory+BaseMethodCategory+DerivedClassCategory\",\n                \"DerivedMethod: BaseClassCategory+DerivedClassCategory+DerivedMethodCategory\"\n            );\n\n        public static class CategoryInheritanceTestScope\n        {\n            [BenchmarkCategory(\"BaseClassCategory\")]\n            public class BaseClass\n            {\n                [Benchmark]\n                [BenchmarkCategory(\"BaseMethodCategory\")]\n                public void BaseMethod() { }\n            }\n\n            [BenchmarkCategory(\"DerivedClassCategory\")]\n            public class DerivedClass : BaseClass\n            {\n                [Benchmark]\n                [BenchmarkCategory(\"DerivedMethodCategory\")]\n                public void DerivedMethod() { }\n            }\n        }\n\n        [Fact]\n        public void CategoryNoInheritanceTest() =>\n            Check<CategoryNoInheritanceTestScope.DerivedClass>(\n                \"BaseMethod: BaseMethodCategory+DerivedClassCategory\",\n                \"DerivedMethod: DerivedClassCategory+DerivedMethodCategory\"\n            );\n\n        public static class CategoryNoInheritanceTestScope\n        {\n            [BenchmarkCategory(\"BaseClassCategory\")]\n            public class BaseClass\n            {\n                [Benchmark]\n                [BenchmarkCategory(\"BaseMethodCategory\")]\n                public void BaseMethod() { }\n            }\n\n            [BenchmarkCategory(\"DerivedClassCategory\")]\n            [CategoryDiscoverer(false)]\n            public class DerivedClass : BaseClass\n            {\n                [Benchmark]\n                [BenchmarkCategory(\"DerivedMethodCategory\")]\n                public void DerivedMethod() { }\n            }\n        }\n\n        [Fact]\n        public void CustomCategoryDiscovererTest() =>\n            Check<CustomCategoryDiscovererTestScope.Benchmarks>(\n                \"Aaa: A+PermanentCategory\",\n                \"Bbb: B+PermanentCategory\"\n            );\n\n        public static class CustomCategoryDiscovererTestScope\n        {\n            private class CustomCategoryDiscoverer : ICategoryDiscoverer\n            {\n                public string[] GetCategories(MethodInfo method)\n                {\n                    return\n                    [\n                        \"PermanentCategory\",\n                        method.Name.Substring(0, 1)\n                    ];\n                }\n            }\n\n            [AttributeUsage(AttributeTargets.Class)]\n            private class CustomCategoryDiscovererAttribute : Attribute, IConfigSource\n            {\n                public CustomCategoryDiscovererAttribute()\n                {\n                    Config = ManualConfig.CreateEmpty().WithCategoryDiscoverer(new CustomCategoryDiscoverer());\n                }\n\n                public IConfig Config { get; }\n            }\n\n\n            [CustomCategoryDiscoverer]\n            public class Benchmarks\n            {\n                [Benchmark]\n                public void Aaa() { }\n\n                [Benchmark]\n                public void Bbb() { }\n            }\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Configs/ConfigOptionsTests.cs",
    "content": "﻿using BenchmarkDotNet.Configs;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests.Configs\n{\n    public class ConfigOptionsTests\n    {\n        [Fact]\n        public void DefaultIsTheDefaultOption() => Assert.Equal(ConfigOptions.Default, default(ConfigOptions));\n\n        [Fact]\n        public void DefaultConfigDoesNotKeepFiles() => Assert.False(DefaultConfig.Instance.Options.HasFlag(ConfigOptions.KeepBenchmarkFiles));\n\n        [Fact]\n        public void DefaultConfigDoesNotJoinSummaries() => Assert.False(DefaultConfig.Instance.Options.HasFlag(ConfigOptions.JoinSummary));\n\n        [Fact]\n        public void DefaultConfigDoesNotStopOnFirstError() => Assert.False(DefaultConfig.Instance.Options.HasFlag(ConfigOptions.StopOnFirstError));\n\n        [Fact]\n        public void DefaultConfigDoesNotDisableLogFile() => Assert.False(DefaultConfig.Instance.Options.HasFlag(ConfigOptions.DisableLogFile));\n\n        [Fact]\n        public void DefaultConfigDoesDisableOptimizationsValidator() => Assert.False(DefaultConfig.Instance.Options.HasFlag(ConfigOptions.DisableOptimizationsValidator));\n\n        [Fact]\n        public void EmptyConfigDoesDisableOptimizationsValidator() => Assert.False(ManualConfig.CreateEmpty().Options.HasFlag(ConfigOptions.DisableOptimizationsValidator));\n\n        [Fact]\n        public void ConfigFlagCanBeEnabledOrDisabled()\n        {\n            var flag = ConfigOptions.Default;\n\n            flag = flag.Set(true, ConfigOptions.StopOnFirstError);\n            Assert.True(flag.IsSet(ConfigOptions.StopOnFirstError));\n            Assert.True(flag.HasFlag(ConfigOptions.StopOnFirstError));\n\n            flag = flag.Set(false, ConfigOptions.StopOnFirstError);\n            Assert.False(flag.IsSet(ConfigOptions.StopOnFirstError));\n            Assert.False(flag.HasFlag(ConfigOptions.StopOnFirstError));\n        }\n\n        [Fact]\n        public void ConfigFlagsCanBeCombined()\n        {\n            var flag = ConfigOptions.Default;\n\n            flag = flag.Set(true, ConfigOptions.StopOnFirstError);\n            flag = flag.Set(true, ConfigOptions.JoinSummary);\n\n            Assert.True(flag.IsSet(ConfigOptions.StopOnFirstError));\n            Assert.True(flag.HasFlag(ConfigOptions.StopOnFirstError));\n            Assert.True(flag.IsSet(ConfigOptions.JoinSummary));\n            Assert.True(flag.HasFlag(ConfigOptions.JoinSummary));\n\n            flag = flag.Set(false, ConfigOptions.StopOnFirstError);\n            Assert.False(flag.IsSet(ConfigOptions.StopOnFirstError));\n            Assert.False(flag.HasFlag(ConfigOptions.StopOnFirstError));\n            Assert.True(flag.IsSet(ConfigOptions.JoinSummary));\n            Assert.True(flag.HasFlag(ConfigOptions.JoinSummary));\n\n            flag = flag.Set(false, ConfigOptions.JoinSummary);\n            Assert.False(flag.IsSet(ConfigOptions.StopOnFirstError));\n            Assert.False(flag.HasFlag(ConfigOptions.StopOnFirstError));\n            Assert.False(flag.IsSet(ConfigOptions.JoinSummary));\n            Assert.False(flag.HasFlag(ConfigOptions.JoinSummary));\n        }\n\n        [Fact]\n        public void ConfigFlagCanBeEnabledOrDisabledUsedManualConfigMethods()\n        {\n            var config = ManualConfig.Create(DefaultConfig.Instance);\n\n            config.WithOption(ConfigOptions.StopOnFirstError, true);\n            Assert.True(config.Options.IsSet(ConfigOptions.StopOnFirstError));\n            Assert.True(config.Options.HasFlag(ConfigOptions.StopOnFirstError));\n\n            config.WithOption(ConfigOptions.StopOnFirstError, false);\n            Assert.False(config.Options.IsSet(ConfigOptions.StopOnFirstError));\n            Assert.False(config.Options.HasFlag(ConfigOptions.StopOnFirstError));\n\n            config.WithOptions(ConfigOptions.StopOnFirstError);\n            Assert.True(config.Options.IsSet(ConfigOptions.StopOnFirstError));\n            Assert.True(config.Options.HasFlag(ConfigOptions.StopOnFirstError));\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Configs/ConfigPerMethodTests.cs",
    "content": "﻿using System.Linq;\nusing System.Runtime.InteropServices;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Filters;\nusing BenchmarkDotNet.Running;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests.Configs\n{\n    public class ConfigPerMethodTests\n    {\n        [Fact]\n        public void PerMethodConfigsAreRespected()\n        {\n            var never = BenchmarkConverter.TypeToBenchmarks(typeof(WithBenchmarkThatShouldNeverRun));\n\n            Assert.Empty(never.BenchmarksCases);\n\n            var always = BenchmarkConverter.TypeToBenchmarks(typeof(WithBenchmarkThatShouldAlwaysRun));\n\n            Assert.NotEmpty(always.BenchmarksCases);\n        }\n\n        public class ConditionalRun : FilterConfigBaseAttribute\n        {\n            public ConditionalRun(bool value) : base(new SimpleFilter(_ => value)) { }\n        }\n\n        public class WithBenchmarkThatShouldNeverRun\n        {\n            [Benchmark]\n            [ConditionalRun(false)]\n            public void Method() { }\n        }\n\n        public class WithBenchmarkThatShouldAlwaysRun\n        {\n            [Benchmark]\n            [ConditionalRun(true)]\n            public void Method() { }\n        }\n\n        [Fact]\n        public void CanEnableOrDisableTheBenchmarkPerOperatingSystem()\n        {\n            var allowedForWindows = BenchmarkConverter.TypeToBenchmarks(typeof(WithBenchmarkAllowedForWindows));\n            var notAllowedForWindows = BenchmarkConverter.TypeToBenchmarks(typeof(WithBenchmarkNotAllowedForWindows));\n\n            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))\n            {\n                Assert.NotEmpty(allowedForWindows.BenchmarksCases);\n                Assert.Empty(notAllowedForWindows.BenchmarksCases);\n            }\n            else\n            {\n                Assert.Empty(allowedForWindows.BenchmarksCases);\n                Assert.NotEmpty(notAllowedForWindows.BenchmarksCases);\n            }\n        }\n\n        public class WithBenchmarkAllowedForWindows\n        {\n            [Benchmark]\n            [OperatingSystemsFilter(allowed: true, OS.Windows)]\n            public void Method() { }\n        }\n\n        public class WithBenchmarkNotAllowedForWindows\n        {\n            [Benchmark]\n            [OperatingSystemsFilter(allowed: false, OS.Windows)]\n            public void Method() { }\n        }\n\n        [Fact]\n        public void CanEnableOrDisableTheBenchmarkPerOperatingSystemArchitecture()\n        {\n            var allowed = BenchmarkConverter.TypeToBenchmarks(typeof(WithBenchmarkAllowedForX64));\n            var notallowed = BenchmarkConverter.TypeToBenchmarks(typeof(WithBenchmarkNotAllowedForX64));\n\n            if (RuntimeInformation.OSArchitecture == Architecture.X64)\n            {\n                Assert.NotEmpty(allowed.BenchmarksCases);\n                Assert.Empty(notallowed.BenchmarksCases);\n            }\n            else\n            {\n                Assert.Empty(allowed.BenchmarksCases);\n                Assert.NotEmpty(notallowed.BenchmarksCases);\n            }\n        }\n\n        public class WithBenchmarkAllowedForX64\n        {\n            [Benchmark]\n            [OperatingSystemsArchitectureFilter(allowed: true, Architecture.X64)]\n            public void Method() { }\n        }\n\n        public class WithBenchmarkNotAllowedForX64\n        {\n            [Benchmark]\n            [OperatingSystemsArchitectureFilter(allowed: false, Architecture.X64)]\n            public void Method() { }\n        }\n\n        [Fact]\n        public void CanEnableOrDisableMemoryRandomizationPerMethod()\n        {\n            var benchmarks = BenchmarkConverter.TypeToBenchmarks(typeof(WithMemoryRandomization)).BenchmarksCases;\n\n            Assert.Equal(2, benchmarks.Length);\n            var disabled = benchmarks.Single(benchmark => benchmark.Descriptor.WorkloadMethod.Name == nameof(WithMemoryRandomization.DisabledByDefault));\n            Assert.False(disabled.Job.Run.MemoryRandomization);\n            var enabled = benchmarks.Single(benchmark => benchmark.Descriptor.WorkloadMethod.Name == nameof(WithMemoryRandomization.EnabledWithAttributeOnMethod));\n            Assert.True(enabled.Job.Run.MemoryRandomization);\n        }\n\n        public class WithMemoryRandomization\n        {\n            [Benchmark]\n            public void DisabledByDefault() { }\n\n            [Benchmark]\n            [MemoryRandomization(true)]\n            public void EnabledWithAttributeOnMethod() { }\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Configs/ConfigUnionTests.cs",
    "content": "﻿using BenchmarkDotNet.Analysers;\nusing BenchmarkDotNet.Columns;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Diagnosers;\nusing BenchmarkDotNet.EventProcessors;\nusing BenchmarkDotNet.Exporters;\nusing BenchmarkDotNet.Filters;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Validators;\nusing System.Linq;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests.Configs;\n\npublic class ConfigUnionTests\n{\n    [Fact]\n    public void UnionConfig()\n    {\n        // Arrange\n        var config = CreateDummyConfig();\n        var expected = config.CreateImmutableConfig();\n\n        // Act\n        config = ManualConfig.Union(config, CreateDummyConfig());\n        var result = config.CreateImmutableConfig();\n\n        // Assert\n        Validate(expected, result);\n    }\n\n    [Fact]\n    public void UnionConfigByAddMethods()\n    {\n        var p1 = new SimpleColumnProvider(TargetMethodColumn.Namespace).GetHashCode();\n        var p2 = new SimpleColumnProvider(TargetMethodColumn.Namespace).GetHashCode();\n\n        // Arrange\n        var config = CreateDummyConfig();\n        var otherConfig = CreateDummyConfig();\n        var expected = config.CreateImmutableConfig();\n\n        // Act\n        config.AddAnalyser(otherConfig.GetAnalysers().ToArray())\n              .AddColumnProvider(otherConfig.GetColumnProviders().ToArray())\n              .AddDiagnoser(otherConfig.GetDiagnosers().ToArray())\n              .AddExporter(otherConfig.GetExporters().ToArray())\n              .AddEventProcessor(otherConfig.GetEventProcessors().ToArray())\n              .AddFilter(otherConfig.GetFilters().ToArray())\n              .AddHardwareCounters(otherConfig.GetHardwareCounters().ToArray())\n              .AddLogger(otherConfig.GetLoggers().ToArray())\n              .AddLogicalGroupRules(otherConfig.GetLogicalGroupRules().ToArray())\n              .AddValidator(otherConfig.GetValidators().ToArray());\n\n        var result = config.CreateImmutableConfig();\n\n        // Assert\n        Validate(expected, result);\n    }\n\n    private static void Validate(ImmutableConfig expected, ImmutableConfig result)\n    {\n        Assert.Equal(expected.GetAnalysers(), result.GetAnalysers());\n        Assert.Equal(expected.GetColumnProviders(), result.GetColumnProviders());\n        Assert.Equal(expected.GetDiagnosers(), result.GetDiagnosers());\n        Assert.Equal(expected.GetExporters(), result.GetExporters());\n        Assert.Equal(expected.GetEventProcessors(), result.GetEventProcessors());\n        Assert.Equal(expected.GetFilters(), result.GetFilters());\n        Assert.Equal(expected.GetHardwareCounters(), result.GetHardwareCounters());\n        Assert.Equal(expected.GetLoggers(), result.GetLoggers());\n        Assert.Equal(expected.GetLogicalGroupRules(), result.GetLogicalGroupRules());\n        Assert.Equal(expected.GetValidators(), result.GetValidators());\n    }\n\n    private static ManualConfig CreateDummyConfig() =>\n        ManualConfig.CreateEmpty()\n                    .AddAnalyser([EnvironmentAnalyser.Default])\n                    .AddColumn(TargetMethodColumn.Namespace)\n                    .AddColumnProvider(DefaultColumnProviders.Instance)\n                    .AddDiagnoser([MemoryDiagnoser.Default])\n                    .AddExporter(MarkdownExporter.Default)\n                    .AddEventProcessor(DummyEventProcessor.Instance)\n                    .AddFilter(DummyFilter.Instance)\n                    .AddHardwareCounters([HardwareCounter.BranchMispredictions])\n                    .AddLogger(ConsoleLogger.Default)\n                    .AddLogicalGroupRules([BenchmarkLogicalGroupRule.ByCategory])\n                    .AddValidator([BaselineValidator.FailOnError])\n                    .HideColumns([Column.Id]);\n\n    private class DummyFilter : IFilter\n    {\n        public static DummyFilter Instance = new DummyFilter();\n\n        private DummyFilter() { }\n\n        public bool Predicate(BenchmarkCase benchmarkCase) => true;\n    }\n\n    private class DummyEventProcessor : EventProcessor\n    {\n        public static DummyEventProcessor Instance = new DummyEventProcessor();\n\n        private DummyEventProcessor() { }\n    }\n}\n"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Configs/EnvironmentVariableTests.cs",
    "content": "using System;\nusing System.Diagnostics.CodeAnalysis;\nusing BenchmarkDotNet.Jobs;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests.Configs\n{\n    public class EnvironmentVariableTests\n    {\n        [Fact]\n        public void AddVariableArray()\n        {\n            var job = new Job()\n                .WithEnvironmentVariables(new EnvironmentVariable(\"a\", \"b\"))\n                .WithEnvironmentVariables(new EnvironmentVariable(\"c\", \"d\"));\n            Assert.Single(job.Environment.EnvironmentVariables);\n        }\n\n        [Fact]\n        public void AddVariableArrayWithDuplications()\n        {\n            Assert.Throws<InvalidOperationException>(() =>\n            {\n                new Job().WithEnvironmentVariables(\n                    new EnvironmentVariable(\"a\", \"b\"),\n                    new EnvironmentVariable(\"a\", \"c\"));\n            });\n        }\n\n        [Fact]\n        public void AddOneVariable()\n        {\n            var job = new Job()\n                .WithEnvironmentVariables(new EnvironmentVariable(\"a\", \"b\"), new EnvironmentVariable(\"c\", \"d\"))\n                .WithEnvironmentVariable(new EnvironmentVariable(\"e\", \"f\"));\n            Assert.Equal(3, job.Environment.EnvironmentVariables.Count);\n            Assert.Equal(new EnvironmentVariable(\"a\", \"b\"), job.Environment.EnvironmentVariables[0]);\n            Assert.Equal(new EnvironmentVariable(\"c\", \"d\"), job.Environment.EnvironmentVariables[1]);\n            Assert.Equal(new EnvironmentVariable(\"e\", \"f\"), job.Environment.EnvironmentVariables[2]);\n        }\n\n        [Fact]\n        public void OverrideOneVariable()\n        {\n            var job = new Job()\n                .WithEnvironmentVariables(new EnvironmentVariable(\"a\", \"b\"), new EnvironmentVariable(\"c\", \"d\"))\n                .WithEnvironmentVariable(\"c\", \"e\");\n            Assert.Equal(2, job.Environment.EnvironmentVariables.Count);\n            Assert.Equal(new EnvironmentVariable(\"a\", \"b\"), job.Environment.EnvironmentVariables[0]);\n            Assert.Equal(new EnvironmentVariable(\"c\", \"e\"), job.Environment.EnvironmentVariables[1]);\n        }\n\n        [Fact]\n        [SuppressMessage(\"ReSharper\", \"AssignNullToNotNullAttribute\")]\n        public void InvalidVariables()\n        {\n            Assert.Throws<ArgumentNullException>(() => new EnvironmentVariable(null!, \"x\"));\n            Assert.Throws<ArgumentNullException>(() => new EnvironmentVariable(\"x\", null!));\n            Assert.Throws<ArgumentNullException>(() => new EnvironmentVariable(null!, null!));\n        }\n\n        [Fact]\n        public void ClearVariables()\n        {\n            var job = new Job()\n                .WithEnvironmentVariable(\"a\", \"b\")\n                .WithoutEnvironmentVariables();\n            Assert.Empty(job.Environment.EnvironmentVariables);\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Configs/ImmutableConfigTests.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing BenchmarkDotNet.Analysers;\nusing BenchmarkDotNet.Columns;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Diagnosers;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Exporters;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Order;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Tests.XUnit;\nusing BenchmarkDotNet.Validators;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests.Configs\n{\n    public class ImmutableConfigTests\n    {\n        [Fact]\n        public void DuplicateJobsAreExcluded()\n        {\n            var mutable = ManualConfig.CreateEmpty();\n\n            mutable.AddJob(new Job());\n            mutable.AddJob(new Job());\n\n            var final = ImmutableConfigBuilder.Create(mutable);\n\n            Assert.Single(final.GetJobs());\n        }\n\n        [Fact]\n        public void DuplicateColumnProvidersAreExcluded()\n        {\n            var mutable = ManualConfig.CreateEmpty();\n\n            mutable.AddColumnProvider(DefaultColumnProviders.Job);\n            mutable.AddColumnProvider(DefaultColumnProviders.Job);\n\n            var final = ImmutableConfigBuilder.Create(mutable);\n\n            Assert.Same(DefaultColumnProviders.Job, final.GetColumnProviders().Single());\n        }\n\n        [Fact]\n        public void DuplicateLoggersAreExcluded()\n        {\n            var mutable = ManualConfig.CreateEmpty();\n\n            mutable.AddLogger(ConsoleLogger.Default);\n            mutable.AddLogger(ConsoleLogger.Default);\n\n            var final = ImmutableConfigBuilder.Create(mutable);\n\n            Assert.Same(ConsoleLogger.Default, final.GetLoggers().Single());\n        }\n\n        [Fact]\n        public void DuplicateHardwareCountersAreExcluded()\n        {\n            var mutable = ManualConfig.CreateEmpty();\n\n            mutable.AddHardwareCounters(HardwareCounter.CacheMisses);\n            mutable.AddHardwareCounters(HardwareCounter.CacheMisses);\n\n            var final = ImmutableConfigBuilder.Create(mutable);\n\n            Assert.Equal(HardwareCounter.CacheMisses, final.GetHardwareCounters().Single());\n        }\n\n        [Fact]\n        public void NoSetHardwareCounterIsExcluded()\n        {\n            var mutable = ManualConfig.CreateEmpty();\n\n            mutable.AddHardwareCounters(HardwareCounter.NotSet);\n            mutable.AddHardwareCounters(HardwareCounter.CacheMisses);\n\n            var final = ImmutableConfigBuilder.Create(mutable);\n\n            Assert.Single(final.GetHardwareCounters());\n            Assert.Equal(HardwareCounter.CacheMisses, final.GetHardwareCounters().Single());\n        }\n\n        [FactEnvSpecific(\n            \"We have hardware counters diagnosers only for Windows. This test is disabled for .NET Core because NativeAOT compiler goes crazy when some dependency has reference to TraceEvent...\",\n            EnvRequirement.FullFrameworkOnly)]\n        public void WhenUserDefinesHardwareCountersWeChooseTheRightDiagnoser()\n        {\n            var mutable = ManualConfig.CreateEmpty();\n\n            mutable.AddHardwareCounters(HardwareCounter.CacheMisses);\n\n            var final = ImmutableConfigBuilder.Create(mutable);\n\n            Assert.Single(final.GetDiagnosers());\n            Assert.Single(final.GetDiagnosers().OfType<IHardwareCountersDiagnoser>());\n        }\n\n        [FactEnvSpecific(\n            \"We have hardware counters diagnosers only for Windows. This test is disabled for .NET Core because NativeAOT compiler goes crazy when some dependency has reference to TraceEvent...\",\n            EnvRequirement.FullFrameworkOnly)]\n        public void WhenUserDefinesHardwareCountersAndUsesDisassemblyDiagnoserWeAddInstructionPointerExporter()\n        {\n            var mutable = ManualConfig.CreateEmpty();\n\n            mutable.AddHardwareCounters(HardwareCounter.CacheMisses);\n            mutable.AddDiagnoser(new DisassemblyDiagnoser(new DisassemblyDiagnoserConfig()));\n\n            var final = ImmutableConfigBuilder.Create(mutable);\n\n            Assert.Single(final.GetDiagnosers().OfType<IHardwareCountersDiagnoser>());\n            Assert.Single(final.GetDiagnosers().OfType<DisassemblyDiagnoser>());\n            Assert.Single(final.GetExporters().OfType<InstructionPointerExporter>());\n        }\n\n        [Fact]\n        public void DuplicateDiagnosersAreExcludedBasedOnType()\n        {\n            var mutable = ManualConfig.CreateEmpty();\n\n            mutable.AddDiagnoser(new DisassemblyDiagnoser(new DisassemblyDiagnoserConfig()));\n            mutable.AddDiagnoser(new DisassemblyDiagnoser(new DisassemblyDiagnoserConfig()));\n\n            var final = ImmutableConfigBuilder.Create(mutable);\n\n            Assert.Single(final.GetDiagnosers());\n        }\n\n        [Fact]\n        public void DuplicateExportersAreExcluded()\n        {\n            var mutable = ManualConfig.CreateEmpty();\n\n            mutable.AddExporter(MarkdownExporter.GitHub);\n            mutable.AddExporter(MarkdownExporter.GitHub);\n\n            var final = ImmutableConfigBuilder.Create(mutable);\n\n            Assert.Same(MarkdownExporter.GitHub, final.GetExporters().Single());\n        }\n\n        [Fact]\n        public void MultipleExportersOfSameTypeWithDifferentNamesAreAccepted()\n        {\n            var mutable = ManualConfig.CreateEmpty();\n\n            mutable.AddExporter(MarkdownExporter.GitHub);\n            mutable.AddExporter(MarkdownExporter.Atlassian);\n\n            var final = ImmutableConfigBuilder.Create(mutable);\n\n            Assert.Equal(2, final.GetExporters().Count());\n        }\n\n        [Fact]\n        public void DuplicateAnalyzersAreExcluded()\n        {\n            var mutable = ManualConfig.CreateEmpty();\n\n            mutable.AddAnalyser(OutliersAnalyser.Default);\n            mutable.AddAnalyser(OutliersAnalyser.Default);\n\n            var final = ImmutableConfigBuilder.Create(mutable);\n\n            Assert.Same(OutliersAnalyser.Default, final.GetAnalysers().Single());\n        }\n\n        [Fact]\n        public void DuplicateValidatorsAreExcludedBasedOnTreatsWarningsAsErrorsProperty()\n        {\n            var mutable = ManualConfig.CreateEmpty();\n\n            mutable.AddValidator(JitOptimizationsValidator.DontFailOnError);\n            mutable.AddValidator(JitOptimizationsValidator.FailOnError);\n\n            var final = ImmutableConfigBuilder.Create(mutable);\n\n            Assert.Same(JitOptimizationsValidator.FailOnError, final.GetValidators().OfType<JitOptimizationsValidator>().Single());\n        }\n\n        [Fact]\n        public void BaseLineValidatorIsMandatory()\n        {\n            var fromEmpty = ImmutableConfigBuilder.Create(ManualConfig.CreateEmpty());\n\n            Assert.Contains(BaselineValidator.FailOnError, fromEmpty.GetValidators());\n        }\n\n        [Fact]\n        public void JitOptimizationsValidatorIsMandatoryByDefault()\n        {\n            var fromEmpty = ImmutableConfigBuilder.Create(ManualConfig.CreateEmpty());\n            Assert.Contains(JitOptimizationsValidator.DontFailOnError, fromEmpty.GetValidators());\n\n#if !DEBUG\n            // DefaultConfig.Instance doesn't include JitOptimizationsValidator.FailOnError in the DEBUG mode\n            var fromDefault = ImmutableConfigBuilder.Create(DefaultConfig.Instance);\n            Assert.Contains(JitOptimizationsValidator.FailOnError, fromDefault.GetValidators());\n#endif\n        }\n\n        [Fact]\n        public void JitOptimizationsValidatorIsMandatoryCanBeDisabledOnDemand()\n        {\n            var disabled = ImmutableConfigBuilder.Create(ManualConfig.CreateEmpty().WithOptions(ConfigOptions.DisableOptimizationsValidator));\n\n            Assert.DoesNotContain(JitOptimizationsValidator.FailOnError, disabled.GetValidators());\n            Assert.DoesNotContain(JitOptimizationsValidator.DontFailOnError, disabled.GetValidators());\n\n            var enabledThenDisabled = ImmutableConfigBuilder.Create(ManualConfig.CreateEmpty()\n                .AddValidator(JitOptimizationsValidator.FailOnError) // we enable it first (to mimic few configs merge)\n                .WithOptions(ConfigOptions.DisableOptimizationsValidator)); // then disable\n\n            Assert.DoesNotContain(JitOptimizationsValidator.FailOnError, enabledThenDisabled.GetValidators());\n            Assert.DoesNotContain(JitOptimizationsValidator.DontFailOnError, enabledThenDisabled.GetValidators());\n        }\n\n        [Fact] // See https://github.com/dotnet/BenchmarkDotNet/issues/172\n        public void MissingExporterDependencyIsAddedWhenNeeded()\n        {\n            var mutable = ManualConfig.CreateEmpty();\n\n            mutable.AddExporter(TestExporter.Default);\n\n            var exporters = ImmutableConfigBuilder.Create(mutable).GetExporters().ToArray();\n\n            Assert.Equal(2, exporters.Length);\n            Assert.Equal([TestExporterDependency.Default, TestExporter.Default], exporters);\n        }\n\n        [Fact]\n        public void MissingDependencyIsNotAddedWhenItIsAlreadyPresent()\n        {\n            var mutable = ManualConfig.CreateEmpty();\n\n            mutable.AddExporter(TestExporter.Default);\n            mutable.AddExporter(TestExporterDependency.Default);\n\n            var exporters = ImmutableConfigBuilder.Create(mutable).GetExporters().ToArray();\n\n            Assert.Equal(2, exporters.Length);\n            Assert.Equal([TestExporterDependency.Default, TestExporter.Default], exporters);\n        }\n\n        [Fact]\n        public void WhenTwoConfigsAreAddedTheRegularJobsAreJustAdded()\n        {\n            var configWithClrJob = CreateConfigFromJobs(Job.Default.WithRuntime(ClrRuntime.Net462));\n            var configWithCoreJob = CreateConfigFromJobs(Job.Default.WithRuntime(CoreRuntime.Core80));\n\n            foreach (var added in AddLeftToTheRightAndRightToTheLef(configWithCoreJob, configWithClrJob))\n            {\n                var runnableJobs = added.GetJobs();\n\n                Assert.Equal(2, runnableJobs.Count());\n                Assert.Single(runnableJobs, job => job.Environment.Runtime is ClrRuntime);\n                Assert.Single(runnableJobs, job => job.Environment.Runtime is CoreRuntime);\n            }\n        }\n\n        [Fact]\n        public void WhenTwoConfigsAreAddedTheMutatorJobsAreAppliedToAllOtherJobs()\n        {\n            const int warmupCount = 2;\n            var configWithMutatorJob = CreateConfigFromJobs(Job.Default.WithWarmupCount(warmupCount).AsMutator());\n            var configWithTwoStandardJobs = CreateConfigFromJobs(\n                Job.Default.WithRuntime(ClrRuntime.Net462),\n                Job.Default.WithRuntime(CoreRuntime.Core80));\n\n            foreach (var added in AddLeftToTheRightAndRightToTheLef(configWithTwoStandardJobs, configWithMutatorJob))\n            {\n                var runnableJobs = added.GetJobs();\n\n                Assert.Equal(2, runnableJobs.Count());\n                Assert.All(runnableJobs, job => Assert.Equal(warmupCount, job.Run.WarmupCount));\n                Assert.Single(runnableJobs, job => job.Environment.Runtime is ClrRuntime);\n                Assert.Single(runnableJobs, job => job.Environment.Runtime is CoreRuntime);\n            }\n        }\n\n        [Fact]\n        public void WhenTwoConfigsAreAddedTheMutatorJobsAreAppliedToCustomDefaultJobIfPresent()\n        {\n            const int warmupCount = 2;\n            const int iterationsCount = 10;\n\n            var configWithCustomDefaultJob = CreateConfigFromJobs(Job.Default.WithIterationCount(iterationsCount).AsDefault());\n            var configWithMutatorJob = CreateConfigFromJobs(Job.Default.WithWarmupCount(warmupCount).AsMutator());\n\n            foreach (var added in AddLeftToTheRightAndRightToTheLef(configWithCustomDefaultJob, configWithMutatorJob))\n            {\n                var mergedJob = added.GetJobs().Single();\n                Assert.Equal(warmupCount, mergedJob.Run.WarmupCount);\n                Assert.Equal(iterationsCount, mergedJob.Run.IterationCount);\n                Assert.False(mergedJob.Meta.IsMutator); // after the merge the \"child\" job becomes a standard job\n            }\n        }\n\n        [Fact]\n        public void WhenTwoConfigsAreAddedTheMutatorJobsAreAppliedToDefaultJobIfCustomDefaultJobIsNotPresent()\n        {\n            const int warmupCount = 2;\n            var configWithMutatorJob = CreateConfigFromJobs(Job.Default.WithWarmupCount(warmupCount).AsMutator());\n\n            foreach (var added in AddLeftToTheRightAndRightToTheLef(ManualConfig.CreateEmpty(), configWithMutatorJob))\n            {\n                var mergedJob = added.GetJobs().Single();\n                Assert.Equal(warmupCount, mergedJob.Run.WarmupCount);\n                Assert.False(mergedJob.Meta.IsDefault); // after the merge the \"child\" job becomes a standard job\n                Assert.False(mergedJob.Meta.IsMutator); // after the merge the \"child\" job becomes a standard job\n                Assert.Single(mergedJob.GetCharacteristicsWithValues(), changedCharacteristic => ReferenceEquals(changedCharacteristic, BenchmarkDotNet.Jobs.RunMode.WarmupCountCharacteristic));\n            }\n        }\n\n        [Fact]\n        public void WhenArtifactsPathIsNullDefaultValueShouldBeUsed()\n        {\n            var mutable = ManualConfig.CreateEmpty();\n            var final = ImmutableConfigBuilder.Create(mutable);\n            Assert.Equal(final.ArtifactsPath, DefaultConfig.Instance.ArtifactsPath);\n        }\n\n        [Fact]\n        public void WhenOrdererIsNullDefaultValueShouldBeUsed()\n        {\n            var mutable = ManualConfig.CreateEmpty();\n            var final = ImmutableConfigBuilder.Create(mutable);\n            Assert.Equal(final.Orderer, DefaultOrderer.Instance);\n        }\n\n        [Fact]\n        public void WhenSummaryStyleIsNullDefaultValueShouldBeUsed()\n        {\n            var mutable = ManualConfig.CreateEmpty();\n            var final = ImmutableConfigBuilder.Create(mutable);\n            Assert.Equal(final.SummaryStyle, SummaryStyle.Default);\n        }\n\n        [Fact]\n        public void WhenTimeoutIsNotSpecifiedTheDefaultValueIsUsed()\n        {\n            var mutable = ManualConfig.CreateEmpty();\n            var final = ImmutableConfigBuilder.Create(mutable);\n            Assert.Equal(DefaultConfig.Instance.BuildTimeout, final.BuildTimeout);\n        }\n\n        [Fact]\n        public void CustomTimeoutHasPrecedenceOverDefaultTimeout()\n        {\n            TimeSpan customTimeout = TimeSpan.FromSeconds(1);\n            var mutable = ManualConfig.CreateEmpty().WithBuildTimeout(customTimeout);\n\n            var final = ImmutableConfigBuilder.Create(mutable);\n\n            Assert.Equal(customTimeout, final.BuildTimeout);\n        }\n\n        [Theory]\n        [InlineData(false)]\n        [InlineData(true)]\n        public void WhenTwoCustomTimeoutsAreProvidedTheLongerOneIsUsed(bool direction)\n        {\n            var oneSecond = ManualConfig.CreateEmpty().WithBuildTimeout(TimeSpan.FromSeconds(1));\n            var twoSeconds = ManualConfig.CreateEmpty().WithBuildTimeout(TimeSpan.FromSeconds(2));\n\n            if (direction)\n                oneSecond.Add(twoSeconds);\n            else\n                twoSeconds.Add(oneSecond);\n\n            var final = ImmutableConfigBuilder.Create(direction ? oneSecond : twoSeconds);\n            Assert.Equal(TimeSpan.FromSeconds(2), final.BuildTimeout);\n        }\n\n        [Fact]\n        public void WhenWakeLockIsNotSpecifiedTheDefaultValueIsUsed()\n        {\n            var mutable = ManualConfig.CreateEmpty();\n            var final = ImmutableConfigBuilder.Create(mutable);\n            Assert.Equal(DefaultConfig.Instance.WakeLock, final.WakeLock);\n        }\n\n        [Fact]\n        public void CustomWakeLockHasPrecedenceOverDefaultWakeLock()\n        {\n            WakeLockType customWakeLock = WakeLockType.Display;\n            var mutable = ManualConfig.CreateEmpty().WithWakeLock(customWakeLock);\n            var final = ImmutableConfigBuilder.Create(mutable);\n            Assert.Equal(customWakeLock, final.WakeLock);\n        }\n\n        [Theory]\n        [InlineData(WakeLockType.None, WakeLockType.None, WakeLockType.None)]\n        [InlineData(WakeLockType.System, WakeLockType.None, WakeLockType.None)]\n        [InlineData(WakeLockType.Display, WakeLockType.None, WakeLockType.Display)]\n        [InlineData(WakeLockType.None, WakeLockType.System, WakeLockType.None)]\n        [InlineData(WakeLockType.System, WakeLockType.System, WakeLockType.System)]\n        [InlineData(WakeLockType.Display, WakeLockType.System, WakeLockType.Display)]\n        [InlineData(WakeLockType.None, WakeLockType.Display, WakeLockType.Display)]\n        [InlineData(WakeLockType.System, WakeLockType.Display, WakeLockType.Display)]\n        [InlineData(WakeLockType.Display, WakeLockType.Display, WakeLockType.Display)]\n        public void WhenTwoCustomWakeLocksAreProvidedDisplayBeatsNoneBeatsDefault(\n            WakeLockType left, WakeLockType right, WakeLockType expected)\n        {\n            var l = ManualConfig.CreateEmpty().WithWakeLock(left);\n            var r = ManualConfig.CreateEmpty().WithWakeLock(right);\n\n            l.Add(r);\n\n            var final = ImmutableConfigBuilder.Create(l);\n            Assert.Equal(expected, final.WakeLock);\n        }\n\n        private static ManualConfig CreateConfigFromJobs(params Job[] jobs)\n        {\n            var config = ManualConfig.CreateEmpty();\n\n            config.AddJob(jobs);\n\n            return config;\n        }\n\n        private static ImmutableConfig[] AddLeftToTheRightAndRightToTheLef(ManualConfig left, ManualConfig right)\n        {\n            var rightAddedToLeft = ManualConfig.Create(left);\n            rightAddedToLeft.Add(right);\n\n            var leftAddedToTheRight = ManualConfig.Create(right);\n            leftAddedToTheRight.Add(left);\n\n            return [rightAddedToLeft.CreateImmutableConfig(), leftAddedToTheRight.CreateImmutableConfig()];\n        }\n\n        public class TestExporter : IExporter, IExporterDependencies\n        {\n            public static readonly TestExporter Default = new TestExporter();\n\n            public IEnumerable<IExporter> Dependencies\n            {\n                get { yield return TestExporterDependency.Default; }\n            }\n\n            public IEnumerable<string> ExportToFiles(Summary summary, ILogger consoleLogger) => [];\n\n            public string Name => nameof(TestExporter);\n            public void ExportToLog(Summary summary, ILogger logger) { }\n        }\n\n        public class TestExporterDependency : IExporter\n        {\n            public static readonly TestExporterDependency Default = new TestExporterDependency();\n\n            public IEnumerable<string> ExportToFiles(Summary summary, ILogger consoleLogger) => [];\n\n            public string Name => nameof(TestExporterDependency);\n            public void ExportToLog(Summary summary, ILogger logger) { }\n        }\n\n        [Fact]\n        public void GenerateWarningWhenExporterDependencyAlreadyExistInConfig()\n        {\n            System.Globalization.CultureInfo? currentCulture = default;\n            System.Globalization.CultureInfo? currentUICulture = default;\n            {\n                var ct = System.Threading.Thread.CurrentThread;\n                currentCulture = ct.CurrentCulture;\n                currentUICulture = ct.CurrentUICulture;\n                ct.CurrentCulture = System.Globalization.CultureInfo.InvariantCulture;\n                ct.CurrentUICulture = System.Globalization.CultureInfo.InvariantCulture;\n            }\n            try\n            {\n                var mutable = ManualConfig.CreateEmpty();\n                mutable.AddExporter(new BenchmarkDotNet.Exporters.Csv.CsvMeasurementsExporter(BenchmarkDotNet.Exporters.Csv.CsvSeparator.Comma));\n                mutable.AddExporter(RPlotExporter.Default);\n\n                var final = ImmutableConfigBuilder.Create(mutable);\n\n                Assert.Single(final.ConfigAnalysisConclusion);\n            }\n            finally\n            {\n                var ct = System.Threading.Thread.CurrentThread;\n                ct.CurrentCulture = currentCulture;\n                ct.CurrentUICulture = currentUICulture;\n\n            }\n\n        }\n    }\n}\n"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Configs/JobTests.cs",
    "content": "using System;\nusing System.Linq;\nusing System.Reflection;\nusing BenchmarkDotNet.Characteristics;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Toolchains.CsProj;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests.Configs\n{\n    [Trait(\"Category\", \"JobTests\")]\n    public static class JobTests\n    {\n        private static void AssertProperties(CharacteristicObject obj, string properties) =>\n            Assert.Equal(CharacteristicObject.IdCharacteristic.ResolveValueCore(obj, null), properties);\n\n        [Fact]\n        public static void Test01Create()\n        {\n            var j = new Job(\"CustomId\");\n            Assert.False(j.Frozen);\n            Assert.False(j.Environment.Frozen);\n            Assert.False(j.Run.Frozen);\n            Assert.False(j.Environment.Gc.AllowVeryLargeObjects);\n            Assert.Equal(Platform.AnyCpu, j.Environment.Platform);\n            Assert.Equal(RunStrategy.Throughput, j.Run.RunStrategy); // set by default\n            Assert.Equal(\"CustomId\", j.Id);\n            Assert.Equal(\"CustomId\", j.DisplayInfo);\n            Assert.Equal(\"CustomId\", j.ResolvedId);\n            Assert.Equal(j.ResolvedId, j.FolderInfo);\n            Assert.Equal(\"CustomId\", j.Environment.Id);\n\n            // freeze\n            var old = j;\n            j = j.Freeze();\n            Assert.Same(old, j);\n            j = j.Freeze();\n            Assert.Same(old, j);\n            Assert.True(j.Frozen);\n            Assert.True(j.Environment.Frozen);\n            Assert.True(j.Run.Frozen);\n            Assert.False(j.Environment.Gc.AllowVeryLargeObjects);\n            Assert.Equal(Platform.AnyCpu, j.Environment.Platform);\n            Assert.Equal(RunStrategy.Throughput, j.Run.RunStrategy); // set by default\n            Assert.Equal(\"CustomId\", j.Id);\n            Assert.Equal(\"CustomId\", j.DisplayInfo);\n            Assert.Equal(\"CustomId\", j.ResolvedId);\n            Assert.Equal(j.ResolvedId, j.FolderInfo);\n            Assert.Equal(\"CustomId\", j.Environment.Id);\n\n            // unfreeze\n            old = j;\n            j = j.UnfreezeCopy();\n            Assert.NotSame(old, j);\n            Assert.False(j.Frozen);\n            Assert.False(j.Environment.Frozen);\n            Assert.False(j.Run.Frozen);\n            Assert.False(j.Environment.Gc.AllowVeryLargeObjects);\n            Assert.Equal(Platform.AnyCpu, j.Environment.Platform);\n            Assert.Equal(RunStrategy.Throughput, j.Run.RunStrategy); // set by default\n            Assert.Equal(\"CustomId\", j.Id); // id remains after unfreeze\n            Assert.Equal(\"CustomId\", j.DisplayInfo);\n            Assert.Equal(\"CustomId\", j.ResolvedId);\n            Assert.Equal(j.ResolvedId, j.FolderInfo);\n            Assert.Equal(\"CustomId\", j.Environment.Id); // id remains after unfreeze\n\n            // new job\n            j = new Job(j.Freeze());\n            Assert.False(j.Frozen);\n            Assert.False(j.Environment.Frozen);\n            Assert.False(j.Run.Frozen);\n            Assert.False(j.Environment.Gc.AllowVeryLargeObjects);\n            Assert.Equal(Platform.AnyCpu, j.Environment.Platform);\n            Assert.Equal(RunStrategy.Throughput, j.Run.RunStrategy); // set by default\n            Assert.Equal(\"Default\", j.Id); // id reset\n            Assert.True(j.DisplayInfo == \"DefaultJob\", \"DisplayInfo = \" + j.DisplayInfo);\n            Assert.True(j.ResolvedId == \"DefaultJob\", \"ResolvedId = \" + j.ResolvedId);\n            Assert.Equal(j.ResolvedId, j.FolderInfo);\n            Assert.Equal(\"Default\", j.Environment.Id);\n        }\n\n        [Fact]\n        public static void Test02Modify()\n        {\n            var j = new Job(\"SomeId\");\n\n            Assert.Equal(\"SomeId\", j.Id);\n            Assert.Equal(Platform.AnyCpu, j.Environment.Platform);\n            Assert.Equal(0, j.Run.LaunchCount);\n\n            Assert.False(j.HasValue(EnvironmentMode.PlatformCharacteristic));\n            Assert.False(j.Environment.HasValue(EnvironmentMode.PlatformCharacteristic));\n            Assert.False(j.HasValue(RunMode.LaunchCountCharacteristic));\n            Assert.False(j.Run.HasValue(RunMode.LaunchCountCharacteristic));\n\n            AssertProperties(j, \"Default\");\n            AssertProperties(j.Environment, \"Default\");\n\n            // 1. change values\n            j.Environment.Platform = Platform.X64;\n            j.Run.LaunchCount = 1;\n\n            Assert.Equal(\"SomeId\", j.Id);\n            Assert.Equal(Platform.X64, j.Environment.Platform);\n            Assert.Equal(1, j.Run.LaunchCount);\n\n            Assert.True(j.HasValue(EnvironmentMode.PlatformCharacteristic));\n            Assert.True(j.Environment.HasValue(EnvironmentMode.PlatformCharacteristic));\n            Assert.True(j.HasValue(RunMode.LaunchCountCharacteristic));\n            Assert.True(j.Run.HasValue(RunMode.LaunchCountCharacteristic));\n\n            AssertProperties(j, \"Platform=X64, LaunchCount=1\");\n            AssertProperties(j.Environment, \"Platform=X64\");\n            AssertProperties(j.Run, \"LaunchCount=1\");\n\n            // 2. reset Env mode (hack via Characteristic setting)\n            var oldEnv = j.Environment;\n            Job.EnvironmentCharacteristic[j] = new EnvironmentMode();\n\n            Assert.Equal(\"SomeId\", j.Id);\n            Assert.Equal(Platform.AnyCpu, j.Environment.Platform);\n            Assert.Equal(1, j.Run.LaunchCount);\n\n            Assert.False(j.HasValue(EnvironmentMode.PlatformCharacteristic));\n            Assert.False(j.Environment.HasValue(EnvironmentMode.PlatformCharacteristic));\n            Assert.True(j.HasValue(RunMode.LaunchCountCharacteristic));\n            Assert.True(j.Run.HasValue(RunMode.LaunchCountCharacteristic));\n\n            AssertProperties(j, \"LaunchCount=1\");\n            AssertProperties(j.Environment, \"Default\");\n            AssertProperties(j.Run, \"LaunchCount=1\");\n\n            // 2.1 proof that oldEnv was the same\n            Assert.Equal(\"SomeId\", j.Id);\n            Assert.Equal(Platform.X64, oldEnv.Platform);\n            Assert.True(oldEnv.HasValue(EnvironmentMode.PlatformCharacteristic));\n            Assert.Equal(\"Platform=X64\", oldEnv.Id);\n\n            // 3. update Env mode (hack via Characteristic setting)\n            Job.EnvironmentCharacteristic[j] = new EnvironmentMode()\n            {\n                Platform = Platform.X86\n            };\n\n            Assert.Equal(\"SomeId\", j.Id);\n            Assert.Equal(Platform.X86, j.Environment.Platform);\n            Assert.Equal(1, j.Run.LaunchCount);\n\n            Assert.True(j.HasValue(EnvironmentMode.PlatformCharacteristic));\n            Assert.True(j.Environment.HasValue(EnvironmentMode.PlatformCharacteristic));\n            Assert.True(j.HasValue(RunMode.LaunchCountCharacteristic));\n            Assert.True(j.Run.HasValue(RunMode.LaunchCountCharacteristic));\n\n            AssertProperties(j, \"Platform=X86, LaunchCount=1\");\n            AssertProperties(j.Environment, \"Platform=X86\");\n            AssertProperties(j.Run, \"LaunchCount=1\");\n\n            // 4. Freeze-unfreeze:\n            j = j.Freeze().UnfreezeCopy();\n\n            Assert.Equal(\"SomeId\", j.Id); // id not lost\n            Assert.Equal(Platform.X86, j.Environment.Platform);\n            Assert.Equal(1, j.Run.LaunchCount);\n\n            Assert.True(j.HasValue(EnvironmentMode.PlatformCharacteristic));\n            Assert.True(j.Environment.HasValue(EnvironmentMode.PlatformCharacteristic));\n            Assert.True(j.HasValue(RunMode.LaunchCountCharacteristic));\n            Assert.True(j.Run.HasValue(RunMode.LaunchCountCharacteristic));\n\n            AssertProperties(j, \"Platform=X86, LaunchCount=1\");\n            AssertProperties(j.Environment, \"Platform=X86\");\n            AssertProperties(j.Run, \"LaunchCount=1\");\n\n            // 5. Test .With extensions\n            j = j.Freeze()\n                .WithId(\"NewId\");\n            Assert.Equal(\"NewId\", j.Id); // id set\n\n            j = j.Freeze()\n                .WithPlatform(Platform.X64)\n                .WithLaunchCount(2);\n\n            Assert.Equal(\"NewId\", j.Id); // id not lost\n            Assert.Equal(\"NewId(Platform=X64, LaunchCount=2)\", j.DisplayInfo);\n            Assert.Equal(Platform.X64, j.Environment.Platform);\n            Assert.Equal(2, j.Run.LaunchCount);\n\n            Assert.True(j.HasValue(EnvironmentMode.PlatformCharacteristic));\n            Assert.True(j.Environment.HasValue(EnvironmentMode.PlatformCharacteristic));\n            Assert.True(j.HasValue(RunMode.LaunchCountCharacteristic));\n            Assert.True(j.Run.HasValue(RunMode.LaunchCountCharacteristic));\n\n            AssertProperties(j, \"Platform=X64, LaunchCount=2\");\n            AssertProperties(j.Environment, \"Platform=X64\");\n            AssertProperties(j.Run, \"LaunchCount=2\");\n        }\n\n        [Fact]\n        public static void Test03IdDoesNotFlow()\n        {\n            var j = new Job(EnvironmentMode.LegacyJitX64, RunMode.Long); // id will not flow, new Job\n            Assert.False(j.HasValue(CharacteristicObject.IdCharacteristic));\n            Assert.False(j.Environment.HasValue(CharacteristicObject.IdCharacteristic));\n\n            Job.EnvironmentCharacteristic[j] = EnvironmentMode.LegacyJitX86.UnfreezeCopy(); // id will flow\n            Assert.True(j.HasValue(CharacteristicObject.IdCharacteristic));\n            Assert.True(j.Environment.HasValue(CharacteristicObject.IdCharacteristic));\n\n            var c = new CharacteristicSet(EnvironmentMode.LegacyJitX64, RunMode.Long); // id will not flow, new CharacteristicSet\n            Assert.False(c.HasValue(CharacteristicObject.IdCharacteristic));\n\n            Job.EnvironmentCharacteristic[c] = EnvironmentMode.LegacyJitX86.UnfreezeCopy(); // id will flow\n            Assert.True(c.HasValue(CharacteristicObject.IdCharacteristic));\n\n            CharacteristicObject.IdCharacteristic[c] = \"MyId\"; // id set explicitly\n            Assert.Equal(\"MyId\", c.Id);\n\n            j = new Job(\"MyId\", EnvironmentMode.LegacyJitX64, RunMode.Long); // id set explicitly\n            Assert.Equal(\"MyId\", j.Id);\n            Assert.Equal(\"MyId\", j.Environment.Id);\n\n            Job.EnvironmentCharacteristic[j] = EnvironmentMode.LegacyJitX86.UnfreezeCopy();\n            Assert.Equal(\"LegacyJitX86\", j.Id);\n            Assert.Equal(\"LegacyJitX86\", j.Environment.Id);\n\n            j = j.WithJit(Jit.RyuJit);\n            Assert.Equal(\"LegacyJitX86\", j.Id);\n        }\n\n        [Fact]\n        public static void CustomJobIdIsPreserved()\n        {\n            const string id = \"theId\";\n\n            var jobWithId = Job.Default.WithId(id);\n\n            Assert.Equal(id, jobWithId.Id);\n\n            var shouldHaveSameId = jobWithId.WithJit(Jit.RyuJit);\n\n            Assert.Equal(id, shouldHaveSameId.Id);\n        }\n\n        [Fact]\n        public static void PredefinedJobIdIsNotPreserved()\n        {\n            var predefinedJob = Job.Default;\n\n            var customJob = predefinedJob.WithJit(Jit.RyuJit);\n\n            Assert.NotEqual(predefinedJob.Id, customJob.Id);\n        }\n\n        [Fact]\n        public static void BaselineDoesntChangeId()\n        {\n            const string id = \"theId\";\n\n            var predefinedJob = Job.Default;\n            var customJob = predefinedJob.AsBaseline();\n            Assert.Equal(predefinedJob.Id, customJob.Id);\n\n            var jobWithId = predefinedJob.WithId(id);\n            var customJob2 = jobWithId.AsBaseline();\n            Assert.Equal(jobWithId.Id, customJob2.Id);\n        }\n\n        [Fact]\n        public static void Test04Apply()\n        {\n            var j = new Job()\n            {\n                Run = { IterationCount = 1 }\n            };\n\n            AssertProperties(j, \"IterationCount=1\");\n\n            j.Apply(\n                new Job\n                {\n                    Environment = { Platform = Platform.X64 },\n                    Run = { IterationCount = 2 }\n                });\n            AssertProperties(j, \"Platform=X64, IterationCount=2\");\n\n            // filter by properties\n            j.Environment.Apply(\n                new Job()\n                    .WithJit(Jit.RyuJit)\n                    .WithGcAllowVeryLargeObjects(true)\n                    .WithIterationCount(3)\n                    .WithLaunchCount(22));\n            AssertProperties(j, \"Jit=RyuJit, Platform=X64, AllowVeryLargeObjects=True, IterationCount=2\");\n\n            // apply subnode\n            j.Apply(\n                new GcMode()\n                {\n                    AllowVeryLargeObjects = false\n                });\n            AssertProperties(j, \"Jit=RyuJit, Platform=X64, AllowVeryLargeObjects=False, IterationCount=2\");\n\n            // Apply empty\n            j.Apply(Job.Default); // does nothing\n            AssertProperties(j, \"Jit=RyuJit, Platform=X64, AllowVeryLargeObjects=False, IterationCount=2\");\n        }\n\n        [Fact]\n        public static void Test05ApplyCharacteristicSet()\n        {\n            var set1 = new CharacteristicSet();\n            var set2 = new CharacteristicSet();\n\n            set1\n                .Apply(\n                    new EnvironmentMode\n                    {\n                        Platform = Platform.X64\n                    })\n                .Apply(\n                    new Job\n                    {\n                        Run =\n                        {\n                            LaunchCount = 2\n                        },\n                        Environment =\n                        {\n                            Platform = Platform.X86\n                        }\n                    });\n            AssertProperties(set1, \"LaunchCount=2, Platform=X86\");\n            Assert.Equal(Platform.X86, Job.EnvironmentCharacteristic[set1]!.Platform);\n            Assert.True(set1.HasValue(Job.EnvironmentCharacteristic));\n            Assert.Equal(Platform.X86, EnvironmentMode.PlatformCharacteristic[set1]);\n\n            set2.Apply(EnvironmentMode.RyuJitX64).Apply(new GcMode { Concurrent = true });\n            Assert.Null(Job.RunCharacteristic[set2]);\n            Assert.False(set2.HasValue(Job.RunCharacteristic));\n            AssertProperties(set2, \"Concurrent=True, Jit=RyuJit, Platform=X64\");\n\n            var temp = set1.UnfreezeCopy();\n            set1.Apply(set2);\n            set2.Apply(temp);\n            AssertProperties(set1, \"Concurrent=True, Jit=RyuJit, LaunchCount=2, Platform=X64\");\n            AssertProperties(set2, \"Concurrent=True, Jit=RyuJit, LaunchCount=2, Platform=X86\");\n\n            var j = new Job();\n            AssertProperties(j, \"Default\");\n\n            j.Environment.Gc.Apply(set1);\n            AssertProperties(j, \"Concurrent=True\");\n\n            j.Run.Apply(set1);\n            AssertProperties(j, \"Concurrent=True, LaunchCount=2\");\n\n            j.Environment.Apply(set1);\n            AssertProperties(j, \"Jit=RyuJit, Platform=X64, Concurrent=True, LaunchCount=2\");\n\n            j.Apply(set1);\n            AssertProperties(j, \"Jit=RyuJit, Platform=X64, Concurrent=True, LaunchCount=2\");\n        }\n\n        [Fact]\n        public static void Test06CharacteristicHacks()\n        {\n            var j = new Job();\n            Assert.Equal(0, j.Run.IterationCount);\n\n            RunMode.IterationCountCharacteristic[j] = 123;\n            Assert.Equal(123, j.Run.IterationCount);\n\n            var old = j.Run;\n            Job.RunCharacteristic[j] = new RunMode();\n            Assert.Equal(0, j.Run.IterationCount);\n\n            Job.RunCharacteristic[j] = old;\n            old.IterationCount = 234;\n            Assert.Equal(234, j.Run.IterationCount);\n            Assert.Equal(234, RunMode.IterationCountCharacteristic[j]);\n\n            Characteristic a = Job.RunCharacteristic;\n            // will not throw:\n            a[j] = new RunMode();\n            Assert.Throws<ArgumentNullException>(() => a[j] = null); // nulls for job nodes are not allowed;\n            Assert.Throws<ArgumentNullException>(() => a[j] = Characteristic.EmptyValue);\n            Assert.Throws<ArgumentException>(() => a[j] = new EnvironmentMode()); // not assignable;\n            Assert.Throws<ArgumentException>(() => a[j] = new CharacteristicSet()); // not assignable;\n            Assert.Throws<ArgumentException>(() => a[j] = 123); // not assignable;\n\n            a = InfrastructureMode.ToolchainCharacteristic;\n            // will not throw:\n            a[j] = CsProjClassicNetToolchain.Net462;\n            a[j] = null;\n            a[j] = Characteristic.EmptyValue;\n            Assert.Throws<ArgumentException>(() => a[j] = new EnvironmentMode()); // not assignable;\n            Assert.Throws<ArgumentException>(() => a[j] = new CharacteristicSet()); // not assignable;\n            Assert.Throws<ArgumentException>(() => a[j] = 123); // not assignable;\n        }\n\n        [Fact]\n        public static void MutatorAppliedToOtherJobOverwritesOnlyTheConfiguredSettings()\n        {\n            var jobBefore = Job.Default.WithRuntime(CoreRuntime.Core80); // this is a default job with Runtime set to Core\n            var copy = jobBefore.UnfreezeCopy();\n\n            Assert.False(copy.HasValue(RunMode.MaxIterationCountCharacteristic));\n\n            var mutator = Job.Default.WithMaxIterationCount(20);\n\n            copy.Apply(mutator);\n\n            Assert.True(copy.HasValue(RunMode.MaxIterationCountCharacteristic));\n            Assert.Equal(20, copy.Run.MaxIterationCount);\n            Assert.False(jobBefore.HasValue(RunMode.MaxIterationCountCharacteristic));\n            Assert.True(copy.Environment.Runtime is CoreRuntime);\n            Assert.False(copy.Meta.IsMutator); // the job does not became a mutator itself, this config should not be copied\n        }\n\n        [Fact]\n        public static void AllJobModesPropertyNamesMatchCharacteristicNames() // it's mandatory to generate the right c# code\n        {\n            var jobModes = typeof(JobMode<>)\n                .Assembly\n                .GetExportedTypes()\n                .Where(type => type.IsSubclassOf(typeof(CharacteristicObject)) && IsSubclassOfobModeOfItself(type))\n                .ToArray();\n\n            foreach (var jobMode in jobModes)\n            {\n                var properties = jobMode.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly).Where(property => property.CanRead && property.CanWrite);\n\n                foreach (var property in properties)\n                {\n                    string expectedPropertyName = $\"{property.Name}Characteristic\";\n                    Assert.True(null != jobMode.GetField(expectedPropertyName, BindingFlags.Static | BindingFlags.Public), $\"{expectedPropertyName} in {jobMode.Name} does not exist\");\n                }\n            }\n        }\n\n        [Fact]\n        public static void UnfreezeCopy_PreservesIdCharacteristic()\n        {\n            // Arrange\n            var original = new Job();\n            original.SetValue(Job.IdCharacteristic, \"TestID\");\n\n            // Act\n            var copy = original.UnfreezeCopy();\n\n            // Assert\n            Assert.Equal(\"TestID\", copy.GetValue(Job.IdCharacteristic));\n        }\n\n        private static bool IsSubclassOfobModeOfItself(Type type)\n        {\n            Type jobModeOfT;\n\n            try\n            {\n                jobModeOfT = typeof(JobMode<>).MakeGenericType(type);\n            }\n            catch (ArgumentException) //  violates the constraint of type parameter 'T'.\n            {\n                return false;\n            }\n\n            return type.IsSubclassOf(jobModeOfT);\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/CorrectionsSuggesterTests.cs",
    "content": "using System;\nusing AnotherNamespace;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.ConsoleArguments;\nusing BenchmarkDotNet.Tests;\nusing NamespaceB;\nusing NamespaceB.NamespaceC;\nusing Xunit;\nusing MyClassA = NamespaceB.MyClassA;\n\nnamespace BenchmarkDotNet.Tests\n{\n    public class CorrectionsSuggesterTests\n    {\n        [Fact]\n        public void CheckNullArgument()\n        {\n            Assert.Throws<ArgumentNullException>(() => new CorrectionsSuggester([typeof(NamespaceB.NamespaceC.MyClassC)]).SuggestFor(null!));\n        }\n\n        [Fact]\n        public void CheckLexicographicalOrder()\n        {\n            var suggestedNames = new CorrectionsSuggester(\n            [\n                typeof(AnotherNamespace.MyClassZ),\n                typeof(NamespaceA.MyClassA),\n                typeof(NamespaceB.MyClassB),\n                typeof(NamespaceB.NamespaceC.MyClassC)\n            ]).GetAllBenchmarkNames();\n\n            Assert.Equal(\n            [\n                \"AnotherNamespace.MyClassZ.MethodZ\",\n                \"NamespaceA.MyClassA.MethodA\",\n                \"NamespaceA.MyClassA.MethodB\",\n                \"NamespaceB.MyClassB.MethodB\",\n                \"NamespaceB.MyClassB.MethodC\",\n                \"NamespaceB.NamespaceC.MyClassC.MethodC\"\n            ], suggestedNames);\n        }\n\n        [Fact]\n        public void FilterUnknownBenchmark_CollectionIsEmpty()\n        {\n            var suggestedNames = new CorrectionsSuggester(\n            [\n                typeof(NamespaceA.MyClassA),\n                typeof(NamespaceB.MyClassB),\n                typeof(AnotherNamespace.MyClassZ),\n                typeof(NamespaceB.NamespaceC.MyClassC)\n            ]).SuggestFor(\"Anything\");\n            Assert.Empty(suggestedNames);\n        }\n\n        [Fact]\n        public void FilterByCompositeNamespace_LevenshteinOrdering()\n        {\n            var suggestedNames = new CorrectionsSuggester(\n            [\n                typeof(NamespaceA.NamespaceC.MyClassA),\n                typeof(NamespaceB.NamespaceC.MyClassC),\n                typeof(AnotherNamespace.InnerNamespaceA.MyClassA)\n            ]).SuggestFor(\"NmespaceB.NamespaceC\");\n\n            Assert.Equal([\"NamespaceB.NamespaceC*\", \"NamespaceA.NamespaceC*\"], suggestedNames);\n        }\n\n        [Fact]\n        public void FilterByNamespace_LevenshteinOrdering()\n        {\n            var suggestedNames = new CorrectionsSuggester(\n            [\n                typeof(NamespaceA.MyClassA),\n                typeof(NamespaceB.MyClassB),\n                typeof(AnotherNamespace.MyClassZ),\n                typeof(NamespaceB.NamespaceC.MyClassC)\n            ]).SuggestFor(\"Nmespace\");\n\n            Assert.Equal([\"NamespaceA*\", \"NamespaceB*\"], suggestedNames);\n        }\n\n        [Fact]\n        public void FilterByInnerNamespace_LevenshteinOrdering()\n        {\n            var suggestedNames = new CorrectionsSuggester(\n            [\n                typeof(AnotherNamespace.InnerNamespaceA.MyClassA),\n                typeof(AnotherNamespace.InnerNamespaceB.MyClassA),\n                typeof(Lexicographical.MyClassLexicAACDE)\n            ]).SuggestFor(\"InerNamespaceB\");\n\n            Assert.Equal([\"*InnerNamespaceB*\"], suggestedNames);\n        }\n\n        [Fact]\n        public void FilterByClassFromDifferentNamespaces()\n        {\n            var suggestedNames = new CorrectionsSuggester([typeof(MyClassA), typeof(NamespaceA.MyClassA)])\n                .SuggestFor(\"MyClasA\");\n\n            Assert.Equal([\"*MyClassA*\"], suggestedNames);\n        }\n\n        [Fact]\n        public void FilterByClass_LevenshteinOrdering()\n        {\n            var suggestedNames = new CorrectionsSuggester(\n            [\n                typeof(MyClassA), typeof(MyClassB), typeof(MyClassC), typeof(MyClassZ), typeof(NamespaceB.NamespaceC.MyClassA),\n                typeof(MyClassZ.MyClassY)\n            ]).SuggestFor(\"MyClasZ\");\n\n            Assert.Equal([\"*MyClassZ*\"], suggestedNames);\n        }\n\n        [Fact]\n        public void FilterByNamespaceClassMethod_LevenshteinOrdering()\n        {\n            var suggestedNames = new CorrectionsSuggester(\n            [\n                typeof(NamespaceB.MyClassA),\n                typeof(NamespaceA.MyClassA),\n                typeof(NamespaceB.NamespaceC.MyClassA)\n            ]).SuggestFor(\"NamespaceA.MyClasA.MethodA\");\n\n            Assert.Equal(\n            [\n                \"NamespaceA.MyClassA.MethodA\",\n                \"NamespaceA.MyClassA.MethodB\",\n                \"NamespaceB.MyClassA.MethodA\",\n            ], suggestedNames);\n        }\n\n        [Fact]\n        public void FilterGeneric_LevenshteinOrdering()\n        {\n            var suggestedNames = new CorrectionsSuggester(\n            [\n                typeof(Generics.GenericA<int>),\n                typeof(Generics.GenericB<int>)\n            ]).SuggestFor(\"GeneriA<Int32>\");\n\n            Assert.Equal([\"*GenericA<Int32>*\"], suggestedNames);\n        }\n    }\n}\n\nnamespace Generics\n{\n    [DontRun]\n    public class GenericA<T>\n    {\n        [Benchmark] public void MethodG1() { }\n    }\n\n    [DontRun]\n    public class GenericB<T>\n    {\n        [Benchmark] public void MethodG1() { }\n    }\n}\n\nnamespace NamespaceA\n{\n    [DontRun]\n    public class MyClassA\n    {\n        [Benchmark] public void MethodA() { }\n\n        [Benchmark] public void MethodB() { }\n    }\n\n    namespace NamespaceC\n    {\n        [DontRun]\n        public class MyClassA\n        {\n            [Benchmark] public void MethodA() { }\n        }\n    }\n}\n\nnamespace NamespaceB\n{\n    [DontRun]\n    public class MyClassA\n    {\n        [Benchmark] public void MethodA() { }\n    }\n\n    [DontRun]\n    public class MyClassB\n    {\n        [Benchmark] public void MethodB() { }\n\n        [Benchmark] public void MethodC() { }\n    }\n\n    namespace NamespaceC\n    {\n        [DontRun]\n        public class MyClassA\n        {\n            [Benchmark] public void MethodA() { }\n\n            [Benchmark] public void MethodB() { }\n        }\n\n        [DontRun]\n        public class MyClassC\n        {\n            [Benchmark] public void MethodC() { }\n        }\n    }\n}\n\nnamespace AnotherNamespace\n{\n    [DontRun]\n    public class MyClassZ\n    {\n        [Benchmark] public void MethodZ() { }\n\n        [DontRun]\n        public class MyClassY\n        {\n            [Benchmark] public void MethodY() { }\n        }\n    }\n\n    namespace InnerNamespaceA\n    {\n        [DontRun]\n        public class MyClassA\n        {\n            [Benchmark] public void MethodA() { }\n        }\n    }\n\n    namespace InnerNamespaceB\n    {\n        [DontRun]\n        public class MyClassA\n        {\n            [Benchmark] public void MethodA() { }\n        }\n    }\n}\n\nnamespace Lexicographical\n{\n    [DontRun]\n    public class MyClassLexicABCDE\n    {\n        [Benchmark] public void MethodA() { }\n    }\n\n    [DontRun]\n    public class MyClassLexicAACDE\n    {\n        [Benchmark] public void MethodA() { }\n    }\n\n    [DontRun]\n    public class MyClassLexicAACDZ\n    {\n        [Benchmark] public void MethodA() { }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/CsProjGeneratorTests.cs",
    "content": "using BenchmarkDotNet.Characteristics;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Parameters;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Tests.Mocks;\nusing BenchmarkDotNet.Toolchains.CsProj;\nusing JetBrains.Annotations;\nusing System;\nusing System.IO;\nusing System.Linq;\nusing System.Reflection;\nusing System.Xml;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests\n{\n    public class CsProjGeneratorTests\n    {\n        private FileInfo TestAssemblyFileInfo = new FileInfo(typeof(CsProjGeneratorTests).Assembly.Location);\n        private const string runtimeHostConfigurationOptionChunk = \"\"\"\n<ItemGroup>\n  <RuntimeHostConfigurationOption Include=\"System.Runtime.Loader.UseRidGraph\" Value=\"true\" />\n</ItemGroup>\n\"\"\";\n\n        [Theory]\n        [InlineData(\"net471\", false)]\n        [InlineData(\"netcoreapp3.1\", true)]\n        public void ItsPossibleToCustomizeProjectSdkBasedOnProjectSdkFromTheProjectFile(string targetFrameworkMoniker, bool isNetCore)\n        {\n            const string withCustomProjectSdk = @\"\n<Project Sdk=\"\"CUSTOM\"\">\n</Project>\n\";\n            AssertParsedSdkName(withCustomProjectSdk, targetFrameworkMoniker, \"CUSTOM\", isNetCore);\n        }\n\n        [Fact]\n        public void ItsImpossibleToCustomizeProjectSdkForFullFrameworkAppsBasedOnTheImportOfSdk()\n        {\n            const string withCustomProjectImport = @\"\n<Project Sdk=\"\"Microsoft.NET.Sdk\"\">\n  <Import Sdk=\"\"Microsoft.NET.Sdk.WindowsDesktop\"\" Project=\"\"Sdk.props\"\" Condition=\"\"'$(TargetFramework)'=='netcoreapp3.1'\"\"/>\n</Project>\n\";\n            AssertParsedSdkName(withCustomProjectImport, \"net471\", \"Microsoft.NET.Sdk\", false);\n        }\n\n        [Fact]\n        public void ItsPossibleToCustomizeProjectSdkForNetCoreAppsBasedOnTheImportOfSdk()\n        {\n            const string withCustomProjectImport = @\"\n<Project Sdk=\"\"Microsoft.NET.Sdk\"\">\n  <Import Sdk=\"\"Microsoft.NET.Sdk.WindowsDesktop\"\" Project=\"\"Sdk.props\"\" Condition=\"\"'$(TargetFramework)'=='netcoreapp3.1'\"\"/>\n</Project>\n\";\n            AssertParsedSdkName(withCustomProjectImport, \"netcoreapp3.1\", \"Microsoft.NET.Sdk.WindowsDesktop\", true);\n        }\n\n        [AssertionMethod]\n        private void AssertParsedSdkName(string csProjContent, string targetFrameworkMoniker, string expectedSdkValue, bool isNetCore)\n        {\n            var sut = new CsProjGenerator(targetFrameworkMoniker, \"\", \"\", \"\", isNetCore);\n\n            var xmlDoc = new XmlDocument();\n            xmlDoc.LoadXml(csProjContent);\n            var (customProperties, sdkName) = sut.GetSettingsThatNeedToBeCopied(xmlDoc, TestAssemblyFileInfo);\n\n            Assert.Equal(expectedSdkValue, sdkName);\n            Assert.Empty(customProperties);\n        }\n\n        private static void AssertCustomProperties(string expected, string actual)\n        {\n            Assert.Equal(expected.Replace(\"\\r\", \"\").Replace(\"\\n\", Environment.NewLine), actual);\n        }\n\n        [Fact]\n        public void UseWpfSettingGetsCopied()\n        {\n            const string withUseWpfTrue = @\"\n<Project Sdk=\"\"Microsoft.NET.Sdk\"\">\n  <PropertyGroup>\n    <PlatformTarget>AnyCPU</PlatformTarget>\n    <UseWpf>true</UseWpf>\n  </PropertyGroup>\n</Project>\n\";\n            var sut = new CsProjGenerator(\"netcoreapp3.1\", \"\", \"\", \"\", true);\n\n            var xmlDoc = new XmlDocument();\n            xmlDoc.LoadXml(withUseWpfTrue);\n            var (customProperties, sdkName) = sut.GetSettingsThatNeedToBeCopied(xmlDoc, TestAssemblyFileInfo);\n\n            AssertCustomProperties(@\"<PropertyGroup>\n  <UseWpf>true</UseWpf>\n</PropertyGroup>\", customProperties);\n            Assert.Equal(\"Microsoft.NET.Sdk\", sdkName);\n        }\n\n        [Fact]\n        public void SettingsFromPropsFileImportedUsingAbsolutePathGetCopies()\n        {\n            const string imported = @\"\n<Project>\n  <PropertyGroup>\n    <LangVersion>9.9</LangVersion>\n  </PropertyGroup>\n</Project>\n\";\n            var propsFilePath = Path.Combine(TestAssemblyFileInfo.DirectoryName!, \"test.props\");\n            File.WriteAllText(propsFilePath, imported);\n\n            string importingAbsolutePath = $@\"\n<Project Sdk=\"\"Microsoft.NET.Sdk\"\">\n  <Import Project=\"\"{propsFilePath}\"\" />\n</Project>\";\n\n            var sut = new CsProjGenerator(\"netcoreapp3.1\", \"\", \"\", \"\", true);\n\n            var xmlDoc = new XmlDocument();\n            xmlDoc.LoadXml(importingAbsolutePath);\n            var (customProperties, sdkName) = sut.GetSettingsThatNeedToBeCopied(xmlDoc, TestAssemblyFileInfo);\n\n            AssertCustomProperties(@\"<PropertyGroup>\n  <LangVersion>9.9</LangVersion>\n</PropertyGroup>\", customProperties);\n            Assert.Equal(\"Microsoft.NET.Sdk\", sdkName);\n\n            File.Delete(propsFilePath);\n        }\n\n        [Fact]\n        public void SettingsFromPropsFileImportedUsingRelativePathGetCopies()\n        {\n            const string imported = @\"\n<Project>\n  <PropertyGroup>\n    <LangVersion>9.9</LangVersion>\n  </PropertyGroup>\n</Project>\n\";\n            var propsFilePath = Path.Combine(TestAssemblyFileInfo.DirectoryName!, \"test.props\");\n            File.WriteAllText(propsFilePath, imported);\n\n            string importingRelativePath = $@\"\n<Project Sdk=\"\"Microsoft.NET.Sdk\"\">\n  <Import Project=\"\".{Path.DirectorySeparatorChar}test.props\"\" />\n</Project>\";\n\n            var sut = new CsProjGenerator(\"netcoreapp3.1\", \"\", \"\", \"\", true);\n\n            var xmlDoc = new XmlDocument();\n            xmlDoc.LoadXml(importingRelativePath);\n            var (customProperties, sdkName) = sut.GetSettingsThatNeedToBeCopied(xmlDoc, TestAssemblyFileInfo);\n\n            AssertCustomProperties(@\"<PropertyGroup>\n  <LangVersion>9.9</LangVersion>\n</PropertyGroup>\", customProperties);\n            Assert.Equal(\"Microsoft.NET.Sdk\", sdkName);\n\n            File.Delete(propsFilePath);\n        }\n\n        [Fact]\n        public void RuntimeHostConfigurationOptionIsCopied()\n        {\n            string source = $@\"\n<Project Sdk=\"\"Microsoft.NET.Sdk\"\">\n{runtimeHostConfigurationOptionChunk}\n</Project>\";\n\n            var sut = new CsProjGenerator(\"netcoreapp3.1\", \"\", \"\", \"\", true);\n\n            var xmlDoc = new XmlDocument();\n            xmlDoc.LoadXml(source);\n            var (customProperties, sdkName) = sut.GetSettingsThatNeedToBeCopied(xmlDoc, TestAssemblyFileInfo);\n\n            AssertCustomProperties(runtimeHostConfigurationOptionChunk, customProperties);\n            Assert.Equal(\"Microsoft.NET.Sdk\", sdkName);\n        }\n\n        [Fact]\n        public void WarningsAsErrorsSettingGetsCopied()\n        {\n            const string withWarningsAsErrors = @\"\n<Project Sdk=\"\"Microsoft.NET.Sdk\"\">\n  <PropertyGroup>\n    <WarningsAsErrors>NU1102;NU1603</WarningsAsErrors>\n  </PropertyGroup>\n</Project>\n\";\n            var sut = new CsProjGenerator(\"netcoreapp3.1\", \"\", \"\", \"\", true);\n\n            var xmlDoc = new XmlDocument();\n            xmlDoc.LoadXml(withWarningsAsErrors);\n            var (customProperties, sdkName) = sut.GetSettingsThatNeedToBeCopied(xmlDoc, TestAssemblyFileInfo);\n\n            AssertCustomProperties(@\"<PropertyGroup>\n  <WarningsAsErrors>NU1102;NU1603</WarningsAsErrors>\n</PropertyGroup>\", customProperties);\n            Assert.Equal(\"Microsoft.NET.Sdk\", sdkName);\n        }\n\n        [Fact]\n        public void TheDefaultFilePathShouldBeUsedWhenAnAssemblyLocationIsEmpty()\n        {\n            const string programName = \"testProgram\";\n            var config = ManualConfig.CreateEmpty().CreateImmutableConfig();\n\n            //Simulate loading an assembly from a stream\n            var benchmarkDotNetAssembly = typeof(MockFactory.MockBenchmarkClass).GetTypeInfo().Assembly;\n            var streamLoadedAssembly = Assembly.Load(File.ReadAllBytes(benchmarkDotNetAssembly.Location));\n            var assemblyType = streamLoadedAssembly.GetRunnableBenchmarks().Select(type => type).First();\n\n            var target = new Descriptor(assemblyType, MockFactory.MockMethodInfo);\n            var benchmarkCase = BenchmarkCase.Create(target, Job.Default, ParameterInstances.Empty, config);\n\n            var benchmarks = new[] { new BenchmarkBuildInfo(benchmarkCase, config.CreateImmutableConfig(), 999, new([])) };\n            var projectGenerator = new SteamLoadedBuildPartition(\"netcoreapp3.1\", \"\", \"\", \"\", true);\n            string binariesPath = projectGenerator.ResolvePathForBinaries(new BuildPartition(benchmarks, new Resolver()), programName);\n\n            string expectedPath = Path.Combine(Path.Combine(Directory.GetCurrentDirectory(), \"BenchmarkDotNet.Bin\"), programName);\n            Assert.Equal(expectedPath, binariesPath);\n        }\n\n        [Fact]\n        public void TestAssemblyFilePathIsUsedWhenTheAssemblyLocationIsNotEmpty()\n        {\n            const string programName = \"testProgram\";\n            var target = new Descriptor(MockFactory.MockType, MockFactory.MockMethodInfo);\n            var benchmarkCase = BenchmarkCase.Create(target, Job.Default, ParameterInstances.Empty, ManualConfig.CreateEmpty().CreateImmutableConfig());\n            var benchmarks = new[] { new BenchmarkBuildInfo(benchmarkCase, ManualConfig.CreateEmpty().CreateImmutableConfig(), 0, new([])) };\n            var projectGenerator = new SteamLoadedBuildPartition(\"netcoreapp3.1\", \"\", \"\", \"\", true);\n            var buildPartition = new BuildPartition(benchmarks, new Resolver());\n            string binariesPath = projectGenerator.ResolvePathForBinaries(buildPartition, programName);\n\n            string expectedPath = Path.Combine(Path.GetDirectoryName(buildPartition.AssemblyLocation)!, programName);\n            Assert.Equal(expectedPath, binariesPath);\n        }\n\n        private class SteamLoadedBuildPartition : CsProjGenerator\n        {\n            internal string ResolvePathForBinaries(BuildPartition buildPartition, string programName)\n            {\n                return base.GetBuildArtifactsDirectoryPath(buildPartition, programName);\n            }\n\n            public SteamLoadedBuildPartition(string targetFrameworkMoniker, string cliPath, string packagesPath, string runtimeFrameworkVersion, bool isNetCore)\n                : base(targetFrameworkMoniker, cliPath, packagesPath, runtimeFrameworkVersion, isNetCore) { }\n        }\n    }\n}\n"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/CsvHelperTests.cs",
    "content": "﻿using BenchmarkDotNet.Exporters.Csv;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests\n{\n    public class CsvHelperTests\n    {\n        [Theory]\n        [InlineData(\"Just a text\", \"Just a text\")]\n        [InlineData(\"Text with \\n linebreak\", \"\\\"Text with \\n linebreak\\\"\")]\n        [InlineData(\"Text with \\r tab\", \"\\\"Text with \\r tab\\\"\")]\n        [InlineData(\"Text with letters, comma\", \"\\\"Text with letters, comma\\\"\")]\n        [InlineData(\"Text; with separator\", \"\\\"Text; with separator\\\"\")]\n        [InlineData(\"Text with \\\"quotes\\\"\", \"\\\"Text with \\\"\\\"quotes\\\"\\\"\\\"\")]\n        public void EscapeEncloseLineBreaks(string actual, string expected)\n        {\n            Assert.Equal(expected, CsvHelper.Escape(actual, \";\"));\n        }\n\n        [Theory]\n        [InlineData(\"Text with || separator\", \"\\\"Text with || separator\\\"\")]\n        [InlineData(\"Text with | separator\", \"Text with | separator\")]\n        public void EscapeEncloseComplexSeparators(string actual, string expected)\n        {\n            Assert.Equal(expected, CsvHelper.Escape(actual, \"||\"));\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Detectors/Cpu/CpuInfoFormatterTests.cs",
    "content": "﻿using System.Text;\nusing System.Threading.Tasks;\nusing BenchmarkDotNet.Tests.Infra;\nusing Perfolizer.Helpers;\nusing Perfolizer.Models;\nusing VerifyXunit;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests.Detectors.Cpu;\n\n[Collection(\"VerifyTests\")]\npublic class CpuInfoFormatterTests\n{\n    [Fact]\n    public Task FormatTest()\n    {\n        var captions = new StringBuilder();\n        foreach (var processorName in new[] { null, \"\", \"Intel\" })\n        foreach (var physicalProcessorCount in new int?[] { null, 0, 1, 2 })\n        foreach (var physicalCoreCount in new int?[] { null, 0, 1, 2 })\n        foreach (var logicalCoreCount in new int?[] { null, 0, 1, 2 })\n        {\n            var cpu = new CpuInfo\n            {\n                ProcessorName = processorName,\n                PhysicalProcessorCount = physicalProcessorCount,\n                PhysicalCoreCount = physicalCoreCount,\n                LogicalCoreCount = logicalCoreCount,\n            };\n\n            captions.AppendLine(cpu.ToFullBrandName());\n        }\n\n        var settings = VerifyHelper.Create();\n        return Verifier.Verify(captions.ToString(), settings);\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Detectors/Cpu/LinuxCpuInfoParserTests.cs",
    "content": "﻿using BenchmarkDotNet.Detectors.Cpu.Linux;\nusing Perfolizer.Models;\nusing Xunit;\nusing Xunit.Abstractions;\nusing static Perfolizer.Horology.Frequency;\n\nnamespace BenchmarkDotNet.Tests.Detectors.Cpu;\n\n// ReSharper disable StringLiteralTypo\npublic class LinuxCpuInfoParserTests(ITestOutputHelper output)\n{\n    private ITestOutputHelper Output { get; } = output;\n\n    [Fact]\n    public void EmptyTest()\n    {\n        var actual = LinuxCpuInfoParser.Parse(\"\", \"\");\n        var expected = new CpuInfo();\n        Output.AssertEqual(expected, actual);\n    }\n\n    [Fact]\n    public void MalformedTest()\n    {\n        var actual = LinuxCpuInfoParser.Parse(\"malformedkey: malformedvalue\\n\\nmalformedkey2: malformedvalue2\", string.Empty);\n        var expected = new CpuInfo();\n        Output.AssertEqual(expected, actual);\n    }\n\n    [Fact]\n    public void TwoProcessorWithDifferentCoresCountTest()\n    {\n        string cpuInfo = TestHelper.ReadTestFile(\"ProcCpuInfoProcessorWithDifferentCoresCount.txt\");\n        var actual = LinuxCpuInfoParser.Parse(cpuInfo, string.Empty);\n        var expected = new CpuInfo\n        {\n            ProcessorName = \"Unknown processor with 2 cores and hyper threading, Unknown processor with 4 cores\",\n            PhysicalProcessorCount = 2,\n            PhysicalCoreCount = 6,\n            LogicalCoreCount = 8,\n            NominalFrequencyHz = 2_500_000_000,\n            MaxFrequencyHz = 2_500_000_000\n        };\n        Output.AssertEqual(expected, actual);\n    }\n\n\n    [Fact]\n    public void RealOneProcessorTwoCoresTest()\n    {\n        string cpuInfo = TestHelper.ReadTestFile(\"ProcCpuInfoRealOneProcessorTwoCores.txt\");\n        var actual = LinuxCpuInfoParser.Parse(cpuInfo, string.Empty);\n        var expected = new CpuInfo\n        {\n            ProcessorName = \"Intel(R) Core(TM) i5-6200U CPU @ 2.30GHz\",\n            PhysicalProcessorCount = 1,\n            PhysicalCoreCount = 2,\n            LogicalCoreCount = 4,\n            NominalFrequencyHz = 2_300_000_000,\n            MaxFrequencyHz = 2_300_000_000\n        };\n        Output.AssertEqual(expected, actual);\n    }\n\n    [Fact]\n    public void RealOneProcessorFourCoresTest()\n    {\n        string cpuInfo = TestHelper.ReadTestFile(\"ProcCpuInfoRealOneProcessorFourCores.txt\");\n        var actual = LinuxCpuInfoParser.Parse(cpuInfo, string.Empty);\n        var expected = new CpuInfo\n        {\n            ProcessorName = \"Intel(R) Core(TM) i7-4710MQ CPU @ 2.50GHz\",\n            PhysicalProcessorCount = 1,\n            PhysicalCoreCount = 4,\n            LogicalCoreCount = 8,\n            NominalFrequencyHz = 2_494_300_000,\n            MaxFrequencyHz = 2_500_000_000\n        };\n        Output.AssertEqual(expected, actual);\n    }\n\n    // https://github.com/dotnet/BenchmarkDotNet/issues/2577\n    [Fact]\n    public void Issue2577Test()\n    {\n        const string cpuInfo =\n            \"\"\"\n            processor       : 0\n            BogoMIPS        : 50.00\n            Features        : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm lrcpc dcpop asimddp\n            CPU implementer : 0x41\n            CPU architecture: 8\n            CPU variant     : 0x3\n            CPU part        : 0xd0c\n            CPU revision    : 1\n            \"\"\";\n        const string lscpu =\n            \"\"\"\n            Architecture:           aarch64\n              CPU op-mode(s):       32-bit, 64-bit\n              Byte Order:           Little Endian\n            CPU(s):                 16\n              On-line CPU(s) list:  0-15\n            Vendor ID:              ARM\n              Model name:           Neoverse-N1\n                Model:              1\n                Thread(s) per core: 1\n                Core(s) per socket: 16\n                Socket(s):          1\n                Stepping:           r3p1\n                BogoMIPS:           50.00\n                Flags:              fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm lrcpc dcpop asimddp\n            \"\"\";\n        var actual = LinuxCpuInfoParser.Parse(cpuInfo, lscpu);\n        var expected = new CpuInfo { ProcessorName = \"Neoverse-N1\", PhysicalCoreCount = 16 };\n        Output.AssertEqual(expected, actual);\n    }\n\n    [Fact]\n    public void AmdRyzen9_7950X()\n    {\n        string cpuInfo = TestHelper.ReadTestFile(\"ryzen9-cpuinfo.txt\");\n        const string lscpu =\n            \"\"\"\n            Architecture:             x86_64\n              CPU op-mode(s):         32-bit, 64-bit\n              Address sizes:          48 bits physical, 48 bits virtual\n              Byte Order:             Little Endian\n            CPU(s):                   32\n              On-line CPU(s) list:    0-31\n            Vendor ID:                AuthenticAMD\n              Model name:             AMD Ryzen 9 7950X 16-Core Processor\n                CPU family:           25\n                Model:                97\n                Thread(s) per core:   2\n                Core(s) per socket:   16\n                Socket(s):            1\n                Stepping:             2\n                CPU(s) scaling MHz:   41%\n                CPU max MHz:          5881.0000\n                CPU min MHz:          400.0000\n                BogoMIPS:             8983.23\n                Flags:                fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good amd_lbr_v2 nopl nonstop_tsc cpuid extd_apicid aperfmperf rapl \n                                      pni pclmulqdq monitor ssse3 fma cx16 sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx f16c rdrand lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw ibs skinit wdt tce topoext perfctr_core perfctr_nb\n                                       bpext perfctr_llc mwaitx cpb cat_l3 cdp_l3 hw_pstate ssbd mba perfmon_v2 ibrs ibpb stibp ibrs_enhanced vmmcall fsgsbase bmi1 avx2 smep bmi2 erms invpcid cqm rdt_a avx512f avx512dq rdseed adx smap avx512ifma clflushopt clwb avx512\n                                      cd sha_ni avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local user_shstk avx512_bf16 clzero irperf xsaveerptr rdpru wbnoinvd cppc arat npt lbrv svm_lock nrip_save tsc_scale vmcb_clean\n                                       flushbyasid decodeassists pausefilter pfthreshold avic v_vmsave_vmload vgif x2avic v_spec_ctrl vnmi avx512vbmi umip pku ospke avx512_vbmi2 gfni vaes vpclmulqdq avx512_vnni avx512_bitalg avx512_vpopcntdq rdpid overflow_recov succo\n                                      r smca fsrm flush_l1d\n            \"\"\";\n        var actual = LinuxCpuInfoParser.Parse(cpuInfo, lscpu);\n        var expected = new CpuInfo\n        {\n            ProcessorName = \"AMD Ryzen 9 7950X 16-Core Processor\",\n            PhysicalProcessorCount = 1,\n            PhysicalCoreCount = 16,\n            LogicalCoreCount = 32,\n            NominalFrequencyHz = 400_000_000,\n            MaxFrequencyHz = 5_881_000_000\n        };\n        Output.AssertEqual(expected, actual);\n    }\n\n    [Theory]\n    [InlineData(\"Intel(R) Core(TM) i7-4710MQ CPU @ 2.50GHz\", 2.50)]\n    [InlineData(\"Intel(R) Core(TM) i5-6200U CPU @ 2.30GHz\", 2.30)]\n    [InlineData(\"Unknown processor with 2 cores and hyper threading, Unknown processor with 4 cores\", 0)]\n    [InlineData(\"Intel(R) Core(TM) i5-2500 CPU @ 3.30GHz\", 3.30)]\n    public void ParseFrequencyFromBrandStringTests(string brandString, double expectedGHz)\n    {\n        var frequency = LinuxCpuInfoParser.ParseFrequencyFromBrandString(brandString) ?? Zero;\n        Assert.Equal(FromGHz(expectedGHz), frequency);\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Detectors/Cpu/PowershellWmiCpuInfoParserTests.cs",
    "content": "﻿using BenchmarkDotNet.Detectors.Cpu.Windows;\nusing Perfolizer.Models;\nusing Xunit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.Tests.Detectors.Cpu;\n\npublic class PowershellWmiCpuInfoParserTests(ITestOutputHelper output)\n{\n    private ITestOutputHelper Output { get; } = output;\n\n\n    [Fact]\n    public void EmptyTest()\n    {\n        CpuInfo? actual = PowershellWmiCpuInfoParser.Parse(string.Empty);\n        CpuInfo expected = new CpuInfo();\n        Output.AssertEqual(expected, actual);\n    }\n\n\n    [Fact]\n    public void MalformedTest()\n    {\n        CpuInfo? actual = PowershellWmiCpuInfoParser\n            .Parse(\"malformedkey=malformedvalue\\n\\nmalformedkey2=malformedvalue2\");\n        CpuInfo expected = new CpuInfo();\n        Output.AssertEqual(expected, actual);\n    }\n\n    [Fact]\n    public void RealTwoProcessorEightCoresTest()\n    {\n        const string cpuInfo =\n            \"\"\"\n            MaxClockSpeed:2400\n            Name:Intel(R) Xeon(R) CPU E5-2630 v3\n            NumberOfCores:8\n            NumberOfLogicalProcessors:16\n                            \n                          \n            MaxClockSpeed:2400\n            Name:Intel(R) Xeon(R) CPU E5-2630 v3\n            NumberOfCores:8\n            NumberOfLogicalProcessors:16\n            \n            \"\"\";\n        CpuInfo? actual = PowershellWmiCpuInfoParser.Parse(cpuInfo);\n\n        CpuInfo expected = new CpuInfo\n        {\n            ProcessorName = \"Intel(R) Xeon(R) CPU E5-2630 v3\",\n            PhysicalProcessorCount = 2,\n            PhysicalCoreCount = 16,\n            LogicalCoreCount = 32,\n            NominalFrequencyHz = 2_400_000_000,\n            MaxFrequencyHz = 2_400_000_000,\n        };\n\n        Output.AssertEqual(expected, actual);\n    }\n\n    [Fact]\n    public void RealTwoProcessorEightCoresWithWmicBugTest()\n    {\n        const string cpuInfo =\n            \"\\r\\r\\n\" +\n            \"\\r\\r\\n\" +\n            \"MaxClockSpeed:3111\\r\\r\\n\" +\n            \"Name:Intel(R) Xeon(R) CPU E5-2687W 0\\r\\r\\n\" +\n            \"NumberOfCores:8\\r\\r\\n\" +\n            \"NumberOfLogicalProcessors:16\\r\\r\\n\" +\n            \"\\r\\r\\n\" +\n            \"\\r\\r\\n\" +\n            \"MaxClockSpeed:3111\\r\\r\\n\" +\n            \"Name:Intel(R) Xeon(R) CPU E5-2687W 0\\r\\r\\n\" +\n            \"NumberOfCores:8\\r\\r\\n\" +\n            \"NumberOfLogicalProcessors:16\\r\\r\\n\" +\n            \"\\r\\r\\n\" +\n            \"\\r\\r\\n\" +\n            \"\\r\\r\\n\";\n\n        CpuInfo? actual = PowershellWmiCpuInfoParser.Parse(cpuInfo);\n\n        CpuInfo expected = new CpuInfo\n        {\n            ProcessorName = \"Intel(R) Xeon(R) CPU E5-2687W 0\",\n            PhysicalProcessorCount = 2,\n            PhysicalCoreCount = 16,\n            LogicalCoreCount = 32,\n            NominalFrequencyHz = 3_111_000_000,\n            MaxFrequencyHz = 3_111_000_000,\n        };\n\n        Output.AssertEqual(expected, actual);\n    }\n\n    [Fact]\n    public void RealOneProcessorFourCoresTest()\n    {\n        const string cpuInfo = \"\"\"\n\n            MaxClockSpeed:2500\n            Name:Intel(R) Core(TM) i7-4710MQ\n            NumberOfCores:4\n            NumberOfLogicalProcessors:8\n            \"\"\";\n\n        CpuInfo? actual = PowershellWmiCpuInfoParser.Parse(cpuInfo);\n        CpuInfo expected = new CpuInfo\n        {\n            ProcessorName = \"Intel(R) Core(TM) i7-4710MQ\",\n            PhysicalProcessorCount = 1,\n            PhysicalCoreCount = 4,\n            LogicalCoreCount = 8,\n            NominalFrequencyHz = 2_500_000_000,\n            MaxFrequencyHz = 2_500_000_000,\n        };\n\n        Output.AssertEqual(expected, actual);\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Detectors/Cpu/SysctlCpuInfoParserTests.cs",
    "content": "﻿using BenchmarkDotNet.Detectors.Cpu.macOS;\nusing Perfolizer.Models;\nusing Xunit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.Tests.Detectors.Cpu;\n\n// ReSharper disable StringLiteralTypo\npublic class SysctlCpuInfoParserTests(ITestOutputHelper output)\n{\n    private ITestOutputHelper Output { get; } = output;\n\n    [Fact]\n    public void EmptyTest()\n    {\n        var actual = SysctlCpuInfoParser.Parse(string.Empty);\n        var expected = new CpuInfo();\n        Output.AssertEqual(expected, actual);\n    }\n\n    [Fact]\n    public void MalformedTest()\n    {\n        var actual = SysctlCpuInfoParser.Parse(\"malformedkey=malformedvalue\\n\\nmalformedkey2=malformedvalue2\");\n        var expected = new CpuInfo();\n        Output.AssertEqual(expected, actual);\n    }\n\n    [Fact]\n    public void RealOneProcessorFourCoresTest()\n    {\n        string cpuInfo = TestHelper.ReadTestFile(\"SysctlRealOneProcessorFourCores.txt\");\n        var actual = SysctlCpuInfoParser.Parse(cpuInfo);\n        var expected = new CpuInfo\n        {\n            ProcessorName = \"Intel(R) Core(TM) i7-4770HQ CPU @ 2.20GHz\",\n            PhysicalProcessorCount = 1,\n            PhysicalCoreCount = 4,\n            LogicalCoreCount = 8,\n            NominalFrequencyHz = 2_200_000_000,\n            MaxFrequencyHz = 2_200_000_000\n        };\n        Output.AssertEqual(expected, actual);\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Detectors/Cpu/TestFiles/ProcCpuInfoProcessorWithDifferentCoresCount.txt",
    "content": "processor\t: 0\nphysical id\t: 0\nmodel name  : Unknown processor with 2 cores and hyper threading\ncore id\t\t: 0\ncpu cores\t: 2\n\nprocessor\t: 1\nphysical id\t: 0\nmodel name  : Unknown processor with 2 cores and hyper threading\ncore id\t\t: 0\ncpu cores\t: 2\n\nprocessor\t: 2\nmodel name  : Unknown processor with 4 cores\nphysical id\t: 3\ncore id\t\t: 0\ncpu cores\t: 4\n\nprocessor\t: 3\nmodel name  : Unknown processor with 2 cores and hyper threading\nphysical id\t: 0\ncore id\t\t: 1\ncpu cores\t: 2\n\nprocessor\t: 4\nmodel name  : Unknown processor with 2 cores and hyper threading\nphysical id\t: 0\ncore id\t\t: 1\ncpu cores\t: 2\n\nprocessor\t: 5\nmodel name  : Unknown processor with 4 cores\nphysical id\t: 3\ncore id\t\t: 1\ncpu cores\t: 4\n\nprocessor\t: 6\nmodel name  : Unknown processor with 4 cores\nphysical id\t: 3\ncore id\t\t: 2\ncpu cores\t: 4\n\nprocessor\t: 7\nmodel name  : Unknown processor with 4 cores\nphysical id\t: 3\ncore id\t\t: 2\ncpu cores\t: 4\n\nnominal freq : 2500\nmax freq : 2500\nmin freq : 800"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Detectors/Cpu/TestFiles/ProcCpuInfoRealOneProcessorFourCores.txt",
    "content": "processor\t: 0\nvendor_id\t: GenuineIntel\ncpu family\t: 6\nmodel\t\t: 60\nmodel name\t: Intel(R) Core(TM) i7-4710MQ CPU @ 2.50GHz\nstepping\t: 3\nmicrocode\t: 0x1c\ncpu MHz\t\t: 2494.300\ncache size\t: 6144 KB\nphysical id\t: 0\nsiblings\t: 8\ncore id\t\t: 0\ncpu cores\t: 4\napicid\t\t: 0\ninitial apicid\t: 0\nfpu\t\t: yes\nfpu_exception\t: yes\ncpuid level\t: 13\nwp\t\t: yes\nflags\t\t: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 movbe popcnt aes xsave avx f16c rdrand lahf_lm abm cpuid_fault epb tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid xsaveopt dtherm ida arat pln pts\nbugs\t\t:\nbogomips\t: 4988.60\nclflush size\t: 64\ncache_alignment\t: 64\naddress sizes\t: 39 bits physical, 48 bits virtual\npower management:\n\nprocessor\t: 1\nvendor_id\t: GenuineIntel\ncpu family\t: 6\nmodel\t\t: 60\nmodel name\t: Intel(R) Core(TM) i7-4710MQ CPU @ 2.50GHz\nstepping\t: 3\nmicrocode\t: 0x1c\ncpu MHz\t\t: 2494.300\ncache size\t: 6144 KB\nphysical id\t: 0\nsiblings\t: 8\ncore id\t\t: 0\ncpu cores\t: 4\napicid\t\t: 1\ninitial apicid\t: 1\nfpu\t\t: yes\nfpu_exception\t: yes\ncpuid level\t: 13\nwp\t\t: yes\nflags\t\t: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 movbe popcnt aes xsave avx f16c rdrand lahf_lm abm cpuid_fault epb tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid xsaveopt dtherm ida arat pln pts\nbugs\t\t:\nbogomips\t: 4988.60\nclflush size\t: 64\ncache_alignment\t: 64\naddress sizes\t: 39 bits physical, 48 bits virtual\npower management:\n\nprocessor\t: 2\nvendor_id\t: GenuineIntel\ncpu family\t: 6\nmodel\t\t: 60\nmodel name\t: Intel(R) Core(TM) i7-4710MQ CPU @ 2.50GHz\nstepping\t: 3\nmicrocode\t: 0x1c\ncpu MHz\t\t: 2494.300\ncache size\t: 6144 KB\nphysical id\t: 0\nsiblings\t: 8\ncore id\t\t: 1\ncpu cores\t: 4\napicid\t\t: 2\ninitial apicid\t: 2\nfpu\t\t: yes\nfpu_exception\t: yes\ncpuid level\t: 13\nwp\t\t: yes\nflags\t\t: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 movbe popcnt aes xsave avx f16c rdrand lahf_lm abm cpuid_fault epb tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid xsaveopt dtherm ida arat pln pts\nbugs\t\t:\nbogomips\t: 4988.60\nclflush size\t: 64\ncache_alignment\t: 64\naddress sizes\t: 39 bits physical, 48 bits virtual\npower management:\n\nprocessor\t: 3\nvendor_id\t: GenuineIntel\ncpu family\t: 6\nmodel\t\t: 60\nmodel name\t: Intel(R) Core(TM) i7-4710MQ CPU @ 2.50GHz\nstepping\t: 3\nmicrocode\t: 0x1c\ncpu MHz\t\t: 2494.300\ncache size\t: 6144 KB\nphysical id\t: 0\nsiblings\t: 8\ncore id\t\t: 1\ncpu cores\t: 4\napicid\t\t: 3\ninitial apicid\t: 3\nfpu\t\t: yes\nfpu_exception\t: yes\ncpuid level\t: 13\nwp\t\t: yes\nflags\t\t: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 movbe popcnt aes xsave avx f16c rdrand lahf_lm abm cpuid_fault epb tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid xsaveopt dtherm ida arat pln pts\nbugs\t\t:\nbogomips\t: 4988.60\nclflush size\t: 64\ncache_alignment\t: 64\naddress sizes\t: 39 bits physical, 48 bits virtual\npower management:\n\nprocessor\t: 4\nvendor_id\t: GenuineIntel\ncpu family\t: 6\nmodel\t\t: 60\nmodel name\t: Intel(R) Core(TM) i7-4710MQ CPU @ 2.50GHz\nstepping\t: 3\nmicrocode\t: 0x1c\ncpu MHz\t\t: 2494.300\ncache size\t: 6144 KB\nphysical id\t: 0\nsiblings\t: 8\ncore id\t\t: 2\ncpu cores\t: 4\napicid\t\t: 4\ninitial apicid\t: 4\nfpu\t\t: yes\nfpu_exception\t: yes\ncpuid level\t: 13\nwp\t\t: yes\nflags\t\t: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 movbe popcnt aes xsave avx f16c rdrand lahf_lm abm cpuid_fault epb tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid xsaveopt dtherm ida arat pln pts\nbugs\t\t:\nbogomips\t: 4988.60\nclflush size\t: 64\ncache_alignment\t: 64\naddress sizes\t: 39 bits physical, 48 bits virtual\npower management:\n\nprocessor\t: 5\nvendor_id\t: GenuineIntel\ncpu family\t: 6\nmodel\t\t: 60\nmodel name\t: Intel(R) Core(TM) i7-4710MQ CPU @ 2.50GHz\nstepping\t: 3\nmicrocode\t: 0x1c\ncpu MHz\t\t: 2494.300\ncache size\t: 6144 KB\nphysical id\t: 0\nsiblings\t: 8\ncore id\t\t: 2\ncpu cores\t: 4\napicid\t\t: 5\ninitial apicid\t: 5\nfpu\t\t: yes\nfpu_exception\t: yes\ncpuid level\t: 13\nwp\t\t: yes\nflags\t\t: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 movbe popcnt aes xsave avx f16c rdrand lahf_lm abm cpuid_fault epb tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid xsaveopt dtherm ida arat pln pts\nbugs\t\t:\nbogomips\t: 4988.60\nclflush size\t: 64\ncache_alignment\t: 64\naddress sizes\t: 39 bits physical, 48 bits virtual\npower management:\n\nprocessor\t: 6\nvendor_id\t: GenuineIntel\ncpu family\t: 6\nmodel\t\t: 60\nmodel name\t: Intel(R) Core(TM) i7-4710MQ CPU @ 2.50GHz\nstepping\t: 3\nmicrocode\t: 0x1c\ncpu MHz\t\t: 2494.300\ncache size\t: 6144 KB\nphysical id\t: 0\nsiblings\t: 8\ncore id\t\t: 3\ncpu cores\t: 4\napicid\t\t: 6\ninitial apicid\t: 6\nfpu\t\t: yes\nfpu_exception\t: yes\ncpuid level\t: 13\nwp\t\t: yes\nflags\t\t: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 movbe popcnt aes xsave avx f16c rdrand lahf_lm abm cpuid_fault epb tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid xsaveopt dtherm ida arat pln pts\nbugs\t\t:\nbogomips\t: 4988.60\nclflush size\t: 64\ncache_alignment\t: 64\naddress sizes\t: 39 bits physical, 48 bits virtual\npower management:\n\nprocessor\t: 7\nvendor_id\t: GenuineIntel\ncpu family\t: 6\nmodel\t\t: 60\nmodel name\t: Intel(R) Core(TM) i7-4710MQ CPU @ 2.50GHz\nstepping\t: 3\nmicrocode\t: 0x1c\ncpu MHz\t\t: 2494.300\ncache size\t: 6144 KB\nphysical id\t: 0\nsiblings\t: 8\ncore id\t\t: 3\ncpu cores\t: 4\napicid\t\t: 7\ninitial apicid\t: 7\nfpu\t\t: yes\nfpu_exception\t: yes\ncpuid level\t: 13\nwp\t\t: yes\nflags\t\t: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 movbe popcnt aes xsave avx f16c rdrand lahf_lm abm cpuid_fault epb tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid xsaveopt dtherm ida arat pln pts\nbugs\t\t:\nbogomips\t: 4988.60\nclflush size\t: 64\ncache_alignment\t: 64\naddress sizes\t: 39 bits physical, 48 bits virtual\npower management:\nnominal freq : 2500\nmax freq : 2500\nmin freq : 800"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Detectors/Cpu/TestFiles/ProcCpuInfoRealOneProcessorTwoCores.txt",
    "content": "processor\t: 0\nvendor_id\t: GenuineIntel\ncpu family\t: 6\nmodel\t\t: 78\nmodel name\t: Intel(R) Core(TM) i5-6200U CPU @ 2.30GHz\nstepping\t: 3\nmicrocode\t: 0x74\ncpu MHz\t\t: 2400.000\ncache size\t: 3072 KB\nphysical id\t: 0\nsiblings\t: 4\ncore id\t\t: 0\ncpu cores\t: 2\napicid\t\t: 0\ninitial apicid\t: 0\nfpu\t\t: yes\nfpu_exception\t: yes\ncpuid level\t: 22\nwp\t\t: yes\nflags\t\t: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault epb intel_pt tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx rdseed adx smap clflushopt xsaveopt xsavec xgetbv1 xsaves dtherm ida arat pln pts hwp hwp_notify hwp_act_window hwp_epp\nbugs\t\t:\nbogomips\t: 4800.00\nclflush size\t: 64\ncache_alignment\t: 64\naddress sizes\t: 39 bits physical, 48 bits virtual\npower management:\n\nprocessor\t: 1\nvendor_id\t: GenuineIntel\ncpu family\t: 6\nmodel\t\t: 78\nmodel name\t: Intel(R) Core(TM) i5-6200U CPU @ 2.30GHz\nstepping\t: 3\nmicrocode\t: 0x74\ncpu MHz\t\t: 2400.000\ncache size\t: 3072 KB\nphysical id\t: 0\nsiblings\t: 4\ncore id\t\t: 1\ncpu cores\t: 2\napicid\t\t: 2\ninitial apicid\t: 2\nfpu\t\t: yes\nfpu_exception\t: yes\ncpuid level\t: 22\nwp\t\t: yes\nflags\t\t: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault epb intel_pt tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx rdseed adx smap clflushopt xsaveopt xsavec xgetbv1 xsaves dtherm ida arat pln pts hwp hwp_notify hwp_act_window hwp_epp\nbugs\t\t:\nbogomips\t: 4800.00\nclflush size\t: 64\ncache_alignment\t: 64\naddress sizes\t: 39 bits physical, 48 bits virtual\npower management:\n\nprocessor\t: 2\nvendor_id\t: GenuineIntel\ncpu family\t: 6\nmodel\t\t: 78\nmodel name\t: Intel(R) Core(TM) i5-6200U CPU @ 2.30GHz\nstepping\t: 3\nmicrocode\t: 0x74\ncpu MHz\t\t: 2400.000\ncache size\t: 3072 KB\nphysical id\t: 0\nsiblings\t: 4\ncore id\t\t: 0\ncpu cores\t: 2\napicid\t\t: 1\ninitial apicid\t: 1\nfpu\t\t: yes\nfpu_exception\t: yes\ncpuid level\t: 22\nwp\t\t: yes\nflags\t\t: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault epb intel_pt tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx rdseed adx smap clflushopt xsaveopt xsavec xgetbv1 xsaves dtherm ida arat pln pts hwp hwp_notify hwp_act_window hwp_epp\nbugs\t\t:\nbogomips\t: 4800.00\nclflush size\t: 64\ncache_alignment\t: 64\naddress sizes\t: 39 bits physical, 48 bits virtual\npower management:\n\nprocessor\t: 3\nvendor_id\t: GenuineIntel\ncpu family\t: 6\nmodel\t\t: 78\nmodel name\t: Intel(R) Core(TM) i5-6200U CPU @ 2.30GHz\nstepping\t: 3\nmicrocode\t: 0x74\ncpu MHz\t\t: 2400.000\ncache size\t: 3072 KB\nphysical id\t: 0\nsiblings\t: 4\ncore id\t\t: 1\ncpu cores\t: 2\napicid\t\t: 3\ninitial apicid\t: 3\nfpu\t\t: yes\nfpu_exception\t: yes\ncpuid level\t: 22\nwp\t\t: yes\nflags\t\t: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault epb intel_pt tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx rdseed adx smap clflushopt xsaveopt xsavec xgetbv1 xsaves dtherm ida arat pln pts hwp hwp_notify hwp_act_window hwp_epp\nbugs\t\t:\nbogomips\t: 4800.00\nclflush size\t: 64\ncache_alignment\t: 64\naddress sizes\t: 39 bits physical, 48 bits virtual\npower management:\nnominal freq : 2300\nmax freq : 2300\nmin freq : 800"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Detectors/Cpu/TestFiles/SysctlRealOneProcessorFourCores.txt",
    "content": "hw.ncpu: 8\nhw.byteorder: 1234\nhw.memsize: 17179869184\nhw.activecpu: 8\nhw.physicalcpu: 4\nhw.physicalcpu_max: 4\nhw.logicalcpu: 8\nhw.logicalcpu_max: 8\nhw.cputype: 7\nhw.cpusubtype: 8\nhw.cpu64bit_capable: 1\nhw.cpufamily: 280134364\nhw.cacheconfig: 8 2 2 8 0 0 0 0 0 0\nhw.cachesize: 17179869184 32768 262144 6291456 0 0 0 0 0 0\nhw.pagesize: 4096\nhw.pagesize32: 4096\nhw.busfrequency: 100000000\nhw.busfrequency_min: 100000000\nhw.busfrequency_max: 100000000\nhw.cpufrequency: 2200000000\nhw.cpufrequency_min: 2200000000\nhw.cpufrequency_max: 2200000000\nhw.cachelinesize: 64\nhw.l1icachesize: 32768\nhw.l1dcachesize: 32768\nhw.l2cachesize: 262144\nhw.l3cachesize: 6291456\nhw.tbfrequency: 1000000000\nhw.packages: 1\nhw.optional.floatingpoint: 1\nhw.optional.mmx: 1\nhw.optional.sse: 1\nhw.optional.sse2: 1\nhw.optional.sse3: 1\nhw.optional.supplementalsse3: 1\nhw.optional.sse4_1: 1\nhw.optional.sse4_2: 1\nhw.optional.x86_64: 1\nhw.optional.aes: 1\nhw.optional.avx1_0: 1\nhw.optional.rdrand: 1\nhw.optional.f16c: 1\nhw.optional.enfstrg: 1\nhw.optional.fma: 1\nhw.optional.avx2_0: 1\nhw.optional.bmi1: 1\nhw.optional.bmi2: 1\nhw.optional.rtm: 0\nhw.optional.hle: 0\nhw.optional.adx: 1\nhw.optional.mpx: 0\nhw.optional.sgx: 0\nhw.optional.avx512f: 0\nhw.optional.avx512cd: 0\nhw.optional.avx512dq: 0\nhw.optional.avx512bw: 0\nhw.optional.avx512vl: 0\nhw.optional.avx512ifma: 0\nhw.optional.avx512vbmi: 0\nhw.targettype: Mac\nhw.cputhreadtype: 1\nmachdep.cpu.max_basic: 13\nmachdep.cpu.max_ext: 2147483656\nmachdep.cpu.vendor: GenuineIntel\nmachdep.cpu.brand_string: Intel(R) Core(TM) i7-4770HQ CPU @ 2.20GHz\nmachdep.cpu.family: 6\nmachdep.cpu.model: 70\nmachdep.cpu.extmodel: 4\nmachdep.cpu.extfamily: 0\nmachdep.cpu.stepping: 1\nmachdep.cpu.feature_bits: 9221959987971750911\nmachdep.cpu.leaf7_feature_bits: 10155\nmachdep.cpu.extfeature_bits: 142473169152\nmachdep.cpu.signature: 263777\nmachdep.cpu.brand: 0\nmachdep.cpu.features: FPU VME DE PSE TSC MSR PAE MCE CX8 APIC SEP MTRR PGE MCA CMOV PAT PSE36 CLFSH DS ACPI MMX FXSR SSE SSE2 SS HTT TM PBE SSE3 PCLMULQDQ DTES64 MON DSCPL VMX EST TM2 SSSE3 FMA CX16 TPR PDCM SSE4.1 SSE4.2 x2APIC MOVBE POPCNT AES PCID XSAVE OSXSAVE SEGLIM64 TSCTMR AVX1.0 RDRAND F16C\nmachdep.cpu.leaf7_features: SMEP ERMS RDWRFSGS TSC_THREAD_OFFSET BMI1 AVX2 BMI2 INVPCID FPU_CSDS\nmachdep.cpu.extfeatures: SYSCALL XD 1GBPAGE EM64T LAHF LZCNT RDTSCP TSCI\nmachdep.cpu.logical_per_package: 16\nmachdep.cpu.cores_per_package: 8\nmachdep.cpu.microcode_version: 19\nmachdep.cpu.processor_flag: 5\nmachdep.cpu.mwait.linesize_min: 64\nmachdep.cpu.mwait.linesize_max: 64\nmachdep.cpu.mwait.extensions: 3\nmachdep.cpu.mwait.sub_Cstates: 270624\nmachdep.cpu.thermal.sensor: 1\nmachdep.cpu.thermal.dynamic_acceleration: 1\nmachdep.cpu.thermal.invariant_APIC_timer: 1\nmachdep.cpu.thermal.thresholds: 2\nmachdep.cpu.thermal.ACNT_MCNT: 1\nmachdep.cpu.thermal.core_power_limits: 1\nmachdep.cpu.thermal.fine_grain_clock_mod: 1\nmachdep.cpu.thermal.package_thermal_intr: 1\nmachdep.cpu.thermal.hardware_feedback: 0\nmachdep.cpu.thermal.energy_policy: 1\nmachdep.cpu.xsave.extended_state: 7 832 832 0\nmachdep.cpu.xsave.extended_state1: 1 0 0 0\nmachdep.cpu.arch_perf.version: 3\nmachdep.cpu.arch_perf.number: 4\nmachdep.cpu.arch_perf.width: 48\nmachdep.cpu.arch_perf.events_number: 7\nmachdep.cpu.arch_perf.events: 0\nmachdep.cpu.arch_perf.fixed_number: 3\nmachdep.cpu.arch_perf.fixed_width: 48\nmachdep.cpu.cache.linesize: 64\nmachdep.cpu.cache.L2_associativity: 8\nmachdep.cpu.cache.size: 256\nmachdep.cpu.tlb.inst.large: 8\nmachdep.cpu.tlb.data.small: 64\nmachdep.cpu.tlb.data.small_level1: 64\nmachdep.cpu.tlb.shared: 1024\nmachdep.cpu.address_bits.physical: 39\nmachdep.cpu.address_bits.virtual: 48\nmachdep.cpu.core_count: 4\nmachdep.cpu.thread_count: 8\nmachdep.cpu.tsc_ccc.numerator: 0\nmachdep.cpu.tsc_ccc.denominator: 0"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Detectors/Cpu/TestFiles/ryzen9-cpuinfo.txt",
    "content": "processor\t: 0\nvendor_id\t: AuthenticAMD\ncpu family\t: 25\nmodel\t\t: 97\nmodel name\t: AMD Ryzen 9 7950X 16-Core Processor\nstepping\t: 2\nmicrocode\t: 0xa601201\ncpu MHz\t\t: 5346.955\ncache size\t: 1024 KB\nphysical id\t: 0\nsiblings\t: 32\ncore id\t\t: 0\ncpu cores\t: 16\napicid\t\t: 0\ninitial apicid\t: 0\nfpu\t\t: yes\nfpu_exception\t: yes\ncpuid level\t: 16\nwp\t\t: yes\nflags\t\t: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good amd_lbr_v2 nopl nonstop_tsc cpuid extd_apicid aperfmperf rapl pni pclmulqdq monitor ssse3 fma cx16 sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx f16c rdrand lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw ibs skinit wdt tce topoext perfctr_core perfctr_nb bpext perfctr_llc mwaitx cpb cat_l3 cdp_l3 hw_pstate ssbd mba perfmon_v2 ibrs ibpb stibp ibrs_enhanced vmmcall fsgsbase bmi1 avx2 smep bmi2 erms invpcid cqm rdt_a avx512f avx512dq rdseed adx smap avx512ifma clflushopt clwb avx512cd sha_ni avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local user_shstk avx512_bf16 clzero irperf xsaveerptr rdpru wbnoinvd cppc arat npt lbrv svm_lock nrip_save tsc_scale vmcb_clean flushbyasid decodeassists pausefilter pfthreshold avic v_vmsave_vmload vgif x2avic v_spec_ctrl vnmi avx512vbmi umip pku ospke avx512_vbmi2 gfni vaes vpclmulqdq avx512_vnni avx512_bitalg avx512_vpopcntdq rdpid overflow_recov succor smca fsrm flush_l1d\nbugs\t\t: sysret_ss_attrs spectre_v1 spectre_v2 spec_store_bypass srso\nbogomips\t: 8983.23\nTLB size\t: 3584 4K pages\nclflush size\t: 64\ncache_alignment\t: 64\naddress sizes\t: 48 bits physical, 48 bits virtual\npower management: ts ttp tm hwpstate cpb eff_freq_ro [13] [14]\n\nprocessor\t: 1\nvendor_id\t: AuthenticAMD\ncpu family\t: 25\nmodel\t\t: 97\nmodel name\t: AMD Ryzen 9 7950X 16-Core Processor\nstepping\t: 2\nmicrocode\t: 0xa601201\ncpu MHz\t\t: 5487.348\ncache size\t: 1024 KB\nphysical id\t: 0\nsiblings\t: 32\ncore id\t\t: 1\ncpu cores\t: 16\napicid\t\t: 2\ninitial apicid\t: 2\nfpu\t\t: yes\nfpu_exception\t: yes\ncpuid level\t: 16\nwp\t\t: yes\nflags\t\t: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good amd_lbr_v2 nopl nonstop_tsc cpuid extd_apicid aperfmperf rapl pni pclmulqdq monitor ssse3 fma cx16 sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx f16c rdrand lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw ibs skinit wdt tce topoext perfctr_core perfctr_nb bpext perfctr_llc mwaitx cpb cat_l3 cdp_l3 hw_pstate ssbd mba perfmon_v2 ibrs ibpb stibp ibrs_enhanced vmmcall fsgsbase bmi1 avx2 smep bmi2 erms invpcid cqm rdt_a avx512f avx512dq rdseed adx smap avx512ifma clflushopt clwb avx512cd sha_ni avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local user_shstk avx512_bf16 clzero irperf xsaveerptr rdpru wbnoinvd cppc arat npt lbrv svm_lock nrip_save tsc_scale vmcb_clean flushbyasid decodeassists pausefilter pfthreshold avic v_vmsave_vmload vgif x2avic v_spec_ctrl vnmi avx512vbmi umip pku ospke avx512_vbmi2 gfni vaes vpclmulqdq avx512_vnni avx512_bitalg avx512_vpopcntdq rdpid overflow_recov succor smca fsrm flush_l1d\nbugs\t\t: sysret_ss_attrs spectre_v1 spectre_v2 spec_store_bypass srso\nbogomips\t: 8983.23\nTLB size\t: 3584 4K pages\nclflush size\t: 64\ncache_alignment\t: 64\naddress sizes\t: 48 bits physical, 48 bits virtual\npower management: ts ttp tm hwpstate cpb eff_freq_ro [13] [14]\n\nprocessor\t: 2\nvendor_id\t: AuthenticAMD\ncpu family\t: 25\nmodel\t\t: 97\nmodel name\t: AMD Ryzen 9 7950X 16-Core Processor\nstepping\t: 2\nmicrocode\t: 0xa601201\ncpu MHz\t\t: 5479.603\ncache size\t: 1024 KB\nphysical id\t: 0\nsiblings\t: 32\ncore id\t\t: 2\ncpu cores\t: 16\napicid\t\t: 4\ninitial apicid\t: 4\nfpu\t\t: yes\nfpu_exception\t: yes\ncpuid level\t: 16\nwp\t\t: yes\nflags\t\t: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good amd_lbr_v2 nopl nonstop_tsc cpuid extd_apicid aperfmperf rapl pni pclmulqdq monitor ssse3 fma cx16 sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx f16c rdrand lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw ibs skinit wdt tce topoext perfctr_core perfctr_nb bpext perfctr_llc mwaitx cpb cat_l3 cdp_l3 hw_pstate ssbd mba perfmon_v2 ibrs ibpb stibp ibrs_enhanced vmmcall fsgsbase bmi1 avx2 smep bmi2 erms invpcid cqm rdt_a avx512f avx512dq rdseed adx smap avx512ifma clflushopt clwb avx512cd sha_ni avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local user_shstk avx512_bf16 clzero irperf xsaveerptr rdpru wbnoinvd cppc arat npt lbrv svm_lock nrip_save tsc_scale vmcb_clean flushbyasid decodeassists pausefilter pfthreshold avic v_vmsave_vmload vgif x2avic v_spec_ctrl vnmi avx512vbmi umip pku ospke avx512_vbmi2 gfni vaes vpclmulqdq avx512_vnni avx512_bitalg avx512_vpopcntdq rdpid overflow_recov succor smca fsrm flush_l1d\nbugs\t\t: sysret_ss_attrs spectre_v1 spectre_v2 spec_store_bypass srso\nbogomips\t: 8983.23\nTLB size\t: 3584 4K pages\nclflush size\t: 64\ncache_alignment\t: 64\naddress sizes\t: 48 bits physical, 48 bits virtual\npower management: ts ttp tm hwpstate cpb eff_freq_ro [13] [14]\n\nprocessor\t: 3\nvendor_id\t: AuthenticAMD\ncpu family\t: 25\nmodel\t\t: 97\nmodel name\t: AMD Ryzen 9 7950X 16-Core Processor\nstepping\t: 2\nmicrocode\t: 0xa601201\ncpu MHz\t\t: 5601.456\ncache size\t: 1024 KB\nphysical id\t: 0\nsiblings\t: 32\ncore id\t\t: 3\ncpu cores\t: 16\napicid\t\t: 6\ninitial apicid\t: 6\nfpu\t\t: yes\nfpu_exception\t: yes\ncpuid level\t: 16\nwp\t\t: yes\nflags\t\t: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good amd_lbr_v2 nopl nonstop_tsc cpuid extd_apicid aperfmperf rapl pni pclmulqdq monitor ssse3 fma cx16 sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx f16c rdrand lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw ibs skinit wdt tce topoext perfctr_core perfctr_nb bpext perfctr_llc mwaitx cpb cat_l3 cdp_l3 hw_pstate ssbd mba perfmon_v2 ibrs ibpb stibp ibrs_enhanced vmmcall fsgsbase bmi1 avx2 smep bmi2 erms invpcid cqm rdt_a avx512f avx512dq rdseed adx smap avx512ifma clflushopt clwb avx512cd sha_ni avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local user_shstk avx512_bf16 clzero irperf xsaveerptr rdpru wbnoinvd cppc arat npt lbrv svm_lock nrip_save tsc_scale vmcb_clean flushbyasid decodeassists pausefilter pfthreshold avic v_vmsave_vmload vgif x2avic v_spec_ctrl vnmi avx512vbmi umip pku ospke avx512_vbmi2 gfni vaes vpclmulqdq avx512_vnni avx512_bitalg avx512_vpopcntdq rdpid overflow_recov succor smca fsrm flush_l1d\nbugs\t\t: sysret_ss_attrs spectre_v1 spectre_v2 spec_store_bypass srso\nbogomips\t: 8983.23\nTLB size\t: 3584 4K pages\nclflush size\t: 64\ncache_alignment\t: 64\naddress sizes\t: 48 bits physical, 48 bits virtual\npower management: ts ttp tm hwpstate cpb eff_freq_ro [13] [14]\n\nprocessor\t: 4\nvendor_id\t: AuthenticAMD\ncpu family\t: 25\nmodel\t\t: 97\nmodel name\t: AMD Ryzen 9 7950X 16-Core Processor\nstepping\t: 2\nmicrocode\t: 0xa601201\ncpu MHz\t\t: 5410.513\ncache size\t: 1024 KB\nphysical id\t: 0\nsiblings\t: 32\ncore id\t\t: 4\ncpu cores\t: 16\napicid\t\t: 8\ninitial apicid\t: 8\nfpu\t\t: yes\nfpu_exception\t: yes\ncpuid level\t: 16\nwp\t\t: yes\nflags\t\t: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good amd_lbr_v2 nopl nonstop_tsc cpuid extd_apicid aperfmperf rapl pni pclmulqdq monitor ssse3 fma cx16 sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx f16c rdrand lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw ibs skinit wdt tce topoext perfctr_core perfctr_nb bpext perfctr_llc mwaitx cpb cat_l3 cdp_l3 hw_pstate ssbd mba perfmon_v2 ibrs ibpb stibp ibrs_enhanced vmmcall fsgsbase bmi1 avx2 smep bmi2 erms invpcid cqm rdt_a avx512f avx512dq rdseed adx smap avx512ifma clflushopt clwb avx512cd sha_ni avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local user_shstk avx512_bf16 clzero irperf xsaveerptr rdpru wbnoinvd cppc arat npt lbrv svm_lock nrip_save tsc_scale vmcb_clean flushbyasid decodeassists pausefilter pfthreshold avic v_vmsave_vmload vgif x2avic v_spec_ctrl vnmi avx512vbmi umip pku ospke avx512_vbmi2 gfni vaes vpclmulqdq avx512_vnni avx512_bitalg avx512_vpopcntdq rdpid overflow_recov succor smca fsrm flush_l1d\nbugs\t\t: sysret_ss_attrs spectre_v1 spectre_v2 spec_store_bypass srso\nbogomips\t: 8983.23\nTLB size\t: 3584 4K pages\nclflush size\t: 64\ncache_alignment\t: 64\naddress sizes\t: 48 bits physical, 48 bits virtual\npower management: ts ttp tm hwpstate cpb eff_freq_ro [13] [14]\n\nprocessor\t: 5\nvendor_id\t: AuthenticAMD\ncpu family\t: 25\nmodel\t\t: 97\nmodel name\t: AMD Ryzen 9 7950X 16-Core Processor\nstepping\t: 2\nmicrocode\t: 0xa601201\ncpu MHz\t\t: 5493.255\ncache size\t: 1024 KB\nphysical id\t: 0\nsiblings\t: 32\ncore id\t\t: 5\ncpu cores\t: 16\napicid\t\t: 10\ninitial apicid\t: 10\nfpu\t\t: yes\nfpu_exception\t: yes\ncpuid level\t: 16\nwp\t\t: yes\nflags\t\t: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good amd_lbr_v2 nopl nonstop_tsc cpuid extd_apicid aperfmperf rapl pni pclmulqdq monitor ssse3 fma cx16 sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx f16c rdrand lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw ibs skinit wdt tce topoext perfctr_core perfctr_nb bpext perfctr_llc mwaitx cpb cat_l3 cdp_l3 hw_pstate ssbd mba perfmon_v2 ibrs ibpb stibp ibrs_enhanced vmmcall fsgsbase bmi1 avx2 smep bmi2 erms invpcid cqm rdt_a avx512f avx512dq rdseed adx smap avx512ifma clflushopt clwb avx512cd sha_ni avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local user_shstk avx512_bf16 clzero irperf xsaveerptr rdpru wbnoinvd cppc arat npt lbrv svm_lock nrip_save tsc_scale vmcb_clean flushbyasid decodeassists pausefilter pfthreshold avic v_vmsave_vmload vgif x2avic v_spec_ctrl vnmi avx512vbmi umip pku ospke avx512_vbmi2 gfni vaes vpclmulqdq avx512_vnni avx512_bitalg avx512_vpopcntdq rdpid overflow_recov succor smca fsrm flush_l1d\nbugs\t\t: sysret_ss_attrs spectre_v1 spectre_v2 spec_store_bypass srso\nbogomips\t: 8983.23\nTLB size\t: 3584 4K pages\nclflush size\t: 64\ncache_alignment\t: 64\naddress sizes\t: 48 bits physical, 48 bits virtual\npower management: ts ttp tm hwpstate cpb eff_freq_ro [13] [14]\n\nprocessor\t: 6\nvendor_id\t: AuthenticAMD\ncpu family\t: 25\nmodel\t\t: 97\nmodel name\t: AMD Ryzen 9 7950X 16-Core Processor\nstepping\t: 2\nmicrocode\t: 0xa601201\ncpu MHz\t\t: 4422.161\ncache size\t: 1024 KB\nphysical id\t: 0\nsiblings\t: 32\ncore id\t\t: 6\ncpu cores\t: 16\napicid\t\t: 12\ninitial apicid\t: 12\nfpu\t\t: yes\nfpu_exception\t: yes\ncpuid level\t: 16\nwp\t\t: yes\nflags\t\t: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good amd_lbr_v2 nopl nonstop_tsc cpuid extd_apicid aperfmperf rapl pni pclmulqdq monitor ssse3 fma cx16 sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx f16c rdrand lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw ibs skinit wdt tce topoext perfctr_core perfctr_nb bpext perfctr_llc mwaitx cpb cat_l3 cdp_l3 hw_pstate ssbd mba perfmon_v2 ibrs ibpb stibp ibrs_enhanced vmmcall fsgsbase bmi1 avx2 smep bmi2 erms invpcid cqm rdt_a avx512f avx512dq rdseed adx smap avx512ifma clflushopt clwb avx512cd sha_ni avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local user_shstk avx512_bf16 clzero irperf xsaveerptr rdpru wbnoinvd cppc arat npt lbrv svm_lock nrip_save tsc_scale vmcb_clean flushbyasid decodeassists pausefilter pfthreshold avic v_vmsave_vmload vgif x2avic v_spec_ctrl vnmi avx512vbmi umip pku ospke avx512_vbmi2 gfni vaes vpclmulqdq avx512_vnni avx512_bitalg avx512_vpopcntdq rdpid overflow_recov succor smca fsrm flush_l1d\nbugs\t\t: sysret_ss_attrs spectre_v1 spectre_v2 spec_store_bypass srso\nbogomips\t: 8983.23\nTLB size\t: 3584 4K pages\nclflush size\t: 64\ncache_alignment\t: 64\naddress sizes\t: 48 bits physical, 48 bits virtual\npower management: ts ttp tm hwpstate cpb eff_freq_ro [13] [14]\n\nprocessor\t: 7\nvendor_id\t: AuthenticAMD\ncpu family\t: 25\nmodel\t\t: 97\nmodel name\t: AMD Ryzen 9 7950X 16-Core Processor\nstepping\t: 2\nmicrocode\t: 0xa601201\ncpu MHz\t\t: 5505.019\ncache size\t: 1024 KB\nphysical id\t: 0\nsiblings\t: 32\ncore id\t\t: 7\ncpu cores\t: 16\napicid\t\t: 14\ninitial apicid\t: 14\nfpu\t\t: yes\nfpu_exception\t: yes\ncpuid level\t: 16\nwp\t\t: yes\nflags\t\t: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good amd_lbr_v2 nopl nonstop_tsc cpuid extd_apicid aperfmperf rapl pni pclmulqdq monitor ssse3 fma cx16 sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx f16c rdrand lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw ibs skinit wdt tce topoext perfctr_core perfctr_nb bpext perfctr_llc mwaitx cpb cat_l3 cdp_l3 hw_pstate ssbd mba perfmon_v2 ibrs ibpb stibp ibrs_enhanced vmmcall fsgsbase bmi1 avx2 smep bmi2 erms invpcid cqm rdt_a avx512f avx512dq rdseed adx smap avx512ifma clflushopt clwb avx512cd sha_ni avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local user_shstk avx512_bf16 clzero irperf xsaveerptr rdpru wbnoinvd cppc arat npt lbrv svm_lock nrip_save tsc_scale vmcb_clean flushbyasid decodeassists pausefilter pfthreshold avic v_vmsave_vmload vgif x2avic v_spec_ctrl vnmi avx512vbmi umip pku ospke avx512_vbmi2 gfni vaes vpclmulqdq avx512_vnni avx512_bitalg avx512_vpopcntdq rdpid overflow_recov succor smca fsrm flush_l1d\nbugs\t\t: sysret_ss_attrs spectre_v1 spectre_v2 spec_store_bypass srso\nbogomips\t: 8983.23\nTLB size\t: 3584 4K pages\nclflush size\t: 64\ncache_alignment\t: 64\naddress sizes\t: 48 bits physical, 48 bits virtual\npower management: ts ttp tm hwpstate cpb eff_freq_ro [13] [14]\n\nprocessor\t: 8\nvendor_id\t: AuthenticAMD\ncpu family\t: 25\nmodel\t\t: 97\nmodel name\t: AMD Ryzen 9 7950X 16-Core Processor\nstepping\t: 2\nmicrocode\t: 0xa601201\ncpu MHz\t\t: 5414.920\ncache size\t: 1024 KB\nphysical id\t: 0\nsiblings\t: 32\ncore id\t\t: 8\ncpu cores\t: 16\napicid\t\t: 16\ninitial apicid\t: 16\nfpu\t\t: yes\nfpu_exception\t: yes\ncpuid level\t: 16\nwp\t\t: yes\nflags\t\t: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good amd_lbr_v2 nopl nonstop_tsc cpuid extd_apicid aperfmperf rapl pni pclmulqdq monitor ssse3 fma cx16 sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx f16c rdrand lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw ibs skinit wdt tce topoext perfctr_core perfctr_nb bpext perfctr_llc mwaitx cpb cat_l3 cdp_l3 hw_pstate ssbd mba perfmon_v2 ibrs ibpb stibp ibrs_enhanced vmmcall fsgsbase bmi1 avx2 smep bmi2 erms invpcid cqm rdt_a avx512f avx512dq rdseed adx smap avx512ifma clflushopt clwb avx512cd sha_ni avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local user_shstk avx512_bf16 clzero irperf xsaveerptr rdpru wbnoinvd cppc arat npt lbrv svm_lock nrip_save tsc_scale vmcb_clean flushbyasid decodeassists pausefilter pfthreshold avic v_vmsave_vmload vgif x2avic v_spec_ctrl vnmi avx512vbmi umip pku ospke avx512_vbmi2 gfni vaes vpclmulqdq avx512_vnni avx512_bitalg avx512_vpopcntdq rdpid overflow_recov succor smca fsrm flush_l1d\nbugs\t\t: sysret_ss_attrs spectre_v1 spectre_v2 spec_store_bypass srso\nbogomips\t: 8983.23\nTLB size\t: 3584 4K pages\nclflush size\t: 64\ncache_alignment\t: 64\naddress sizes\t: 48 bits physical, 48 bits virtual\npower management: ts ttp tm hwpstate cpb eff_freq_ro [13] [14]\n\nprocessor\t: 9\nvendor_id\t: AuthenticAMD\ncpu family\t: 25\nmodel\t\t: 97\nmodel name\t: AMD Ryzen 9 7950X 16-Core Processor\nstepping\t: 2\nmicrocode\t: 0xa601201\ncpu MHz\t\t: 5060.967\ncache size\t: 1024 KB\nphysical id\t: 0\nsiblings\t: 32\ncore id\t\t: 9\ncpu cores\t: 16\napicid\t\t: 18\ninitial apicid\t: 18\nfpu\t\t: yes\nfpu_exception\t: yes\ncpuid level\t: 16\nwp\t\t: yes\nflags\t\t: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good amd_lbr_v2 nopl nonstop_tsc cpuid extd_apicid aperfmperf rapl pni pclmulqdq monitor ssse3 fma cx16 sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx f16c rdrand lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw ibs skinit wdt tce topoext perfctr_core perfctr_nb bpext perfctr_llc mwaitx cpb cat_l3 cdp_l3 hw_pstate ssbd mba perfmon_v2 ibrs ibpb stibp ibrs_enhanced vmmcall fsgsbase bmi1 avx2 smep bmi2 erms invpcid cqm rdt_a avx512f avx512dq rdseed adx smap avx512ifma clflushopt clwb avx512cd sha_ni avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local user_shstk avx512_bf16 clzero irperf xsaveerptr rdpru wbnoinvd cppc arat npt lbrv svm_lock nrip_save tsc_scale vmcb_clean flushbyasid decodeassists pausefilter pfthreshold avic v_vmsave_vmload vgif x2avic v_spec_ctrl vnmi avx512vbmi umip pku ospke avx512_vbmi2 gfni vaes vpclmulqdq avx512_vnni avx512_bitalg avx512_vpopcntdq rdpid overflow_recov succor smca fsrm flush_l1d\nbugs\t\t: sysret_ss_attrs spectre_v1 spectre_v2 spec_store_bypass srso\nbogomips\t: 8983.23\nTLB size\t: 3584 4K pages\nclflush size\t: 64\ncache_alignment\t: 64\naddress sizes\t: 48 bits physical, 48 bits virtual\npower management: ts ttp tm hwpstate cpb eff_freq_ro [13] [14]\n\nprocessor\t: 10\nvendor_id\t: AuthenticAMD\ncpu family\t: 25\nmodel\t\t: 97\nmodel name\t: AMD Ryzen 9 7950X 16-Core Processor\nstepping\t: 2\nmicrocode\t: 0xa601201\ncpu MHz\t\t: 3352.555\ncache size\t: 1024 KB\nphysical id\t: 0\nsiblings\t: 32\ncore id\t\t: 10\ncpu cores\t: 16\napicid\t\t: 20\ninitial apicid\t: 20\nfpu\t\t: yes\nfpu_exception\t: yes\ncpuid level\t: 16\nwp\t\t: yes\nflags\t\t: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good amd_lbr_v2 nopl nonstop_tsc cpuid extd_apicid aperfmperf rapl pni pclmulqdq monitor ssse3 fma cx16 sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx f16c rdrand lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw ibs skinit wdt tce topoext perfctr_core perfctr_nb bpext perfctr_llc mwaitx cpb cat_l3 cdp_l3 hw_pstate ssbd mba perfmon_v2 ibrs ibpb stibp ibrs_enhanced vmmcall fsgsbase bmi1 avx2 smep bmi2 erms invpcid cqm rdt_a avx512f avx512dq rdseed adx smap avx512ifma clflushopt clwb avx512cd sha_ni avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local user_shstk avx512_bf16 clzero irperf xsaveerptr rdpru wbnoinvd cppc arat npt lbrv svm_lock nrip_save tsc_scale vmcb_clean flushbyasid decodeassists pausefilter pfthreshold avic v_vmsave_vmload vgif x2avic v_spec_ctrl vnmi avx512vbmi umip pku ospke avx512_vbmi2 gfni vaes vpclmulqdq avx512_vnni avx512_bitalg avx512_vpopcntdq rdpid overflow_recov succor smca fsrm flush_l1d\nbugs\t\t: sysret_ss_attrs spectre_v1 spectre_v2 spec_store_bypass srso\nbogomips\t: 8983.23\nTLB size\t: 3584 4K pages\nclflush size\t: 64\ncache_alignment\t: 64\naddress sizes\t: 48 bits physical, 48 bits virtual\npower management: ts ttp tm hwpstate cpb eff_freq_ro [13] [14]\n\nprocessor\t: 11\nvendor_id\t: AuthenticAMD\ncpu family\t: 25\nmodel\t\t: 97\nmodel name\t: AMD Ryzen 9 7950X 16-Core Processor\nstepping\t: 2\nmicrocode\t: 0xa601201\ncpu MHz\t\t: 5400.772\ncache size\t: 1024 KB\nphysical id\t: 0\nsiblings\t: 32\ncore id\t\t: 11\ncpu cores\t: 16\napicid\t\t: 22\ninitial apicid\t: 22\nfpu\t\t: yes\nfpu_exception\t: yes\ncpuid level\t: 16\nwp\t\t: yes\nflags\t\t: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good amd_lbr_v2 nopl nonstop_tsc cpuid extd_apicid aperfmperf rapl pni pclmulqdq monitor ssse3 fma cx16 sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx f16c rdrand lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw ibs skinit wdt tce topoext perfctr_core perfctr_nb bpext perfctr_llc mwaitx cpb cat_l3 cdp_l3 hw_pstate ssbd mba perfmon_v2 ibrs ibpb stibp ibrs_enhanced vmmcall fsgsbase bmi1 avx2 smep bmi2 erms invpcid cqm rdt_a avx512f avx512dq rdseed adx smap avx512ifma clflushopt clwb avx512cd sha_ni avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local user_shstk avx512_bf16 clzero irperf xsaveerptr rdpru wbnoinvd cppc arat npt lbrv svm_lock nrip_save tsc_scale vmcb_clean flushbyasid decodeassists pausefilter pfthreshold avic v_vmsave_vmload vgif x2avic v_spec_ctrl vnmi avx512vbmi umip pku ospke avx512_vbmi2 gfni vaes vpclmulqdq avx512_vnni avx512_bitalg avx512_vpopcntdq rdpid overflow_recov succor smca fsrm flush_l1d\nbugs\t\t: sysret_ss_attrs spectre_v1 spectre_v2 spec_store_bypass srso\nbogomips\t: 8983.23\nTLB size\t: 3584 4K pages\nclflush size\t: 64\ncache_alignment\t: 64\naddress sizes\t: 48 bits physical, 48 bits virtual\npower management: ts ttp tm hwpstate cpb eff_freq_ro [13] [14]\n\nprocessor\t: 12\nvendor_id\t: AuthenticAMD\ncpu family\t: 25\nmodel\t\t: 97\nmodel name\t: AMD Ryzen 9 7950X 16-Core Processor\nstepping\t: 2\nmicrocode\t: 0xa601201\ncpu MHz\t\t: 5415.333\ncache size\t: 1024 KB\nphysical id\t: 0\nsiblings\t: 32\ncore id\t\t: 12\ncpu cores\t: 16\napicid\t\t: 24\ninitial apicid\t: 24\nfpu\t\t: yes\nfpu_exception\t: yes\ncpuid level\t: 16\nwp\t\t: yes\nflags\t\t: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good amd_lbr_v2 nopl nonstop_tsc cpuid extd_apicid aperfmperf rapl pni pclmulqdq monitor ssse3 fma cx16 sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx f16c rdrand lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw ibs skinit wdt tce topoext perfctr_core perfctr_nb bpext perfctr_llc mwaitx cpb cat_l3 cdp_l3 hw_pstate ssbd mba perfmon_v2 ibrs ibpb stibp ibrs_enhanced vmmcall fsgsbase bmi1 avx2 smep bmi2 erms invpcid cqm rdt_a avx512f avx512dq rdseed adx smap avx512ifma clflushopt clwb avx512cd sha_ni avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local user_shstk avx512_bf16 clzero irperf xsaveerptr rdpru wbnoinvd cppc arat npt lbrv svm_lock nrip_save tsc_scale vmcb_clean flushbyasid decodeassists pausefilter pfthreshold avic v_vmsave_vmload vgif x2avic v_spec_ctrl vnmi avx512vbmi umip pku ospke avx512_vbmi2 gfni vaes vpclmulqdq avx512_vnni avx512_bitalg avx512_vpopcntdq rdpid overflow_recov succor smca fsrm flush_l1d\nbugs\t\t: sysret_ss_attrs spectre_v1 spectre_v2 spec_store_bypass srso\nbogomips\t: 8983.23\nTLB size\t: 3584 4K pages\nclflush size\t: 64\ncache_alignment\t: 64\naddress sizes\t: 48 bits physical, 48 bits virtual\npower management: ts ttp tm hwpstate cpb eff_freq_ro [13] [14]\n\nprocessor\t: 13\nvendor_id\t: AuthenticAMD\ncpu family\t: 25\nmodel\t\t: 97\nmodel name\t: AMD Ryzen 9 7950X 16-Core Processor\nstepping\t: 2\nmicrocode\t: 0xa601201\ncpu MHz\t\t: 3236.400\ncache size\t: 1024 KB\nphysical id\t: 0\nsiblings\t: 32\ncore id\t\t: 13\ncpu cores\t: 16\napicid\t\t: 26\ninitial apicid\t: 26\nfpu\t\t: yes\nfpu_exception\t: yes\ncpuid level\t: 16\nwp\t\t: yes\nflags\t\t: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good amd_lbr_v2 nopl nonstop_tsc cpuid extd_apicid aperfmperf rapl pni pclmulqdq monitor ssse3 fma cx16 sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx f16c rdrand lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw ibs skinit wdt tce topoext perfctr_core perfctr_nb bpext perfctr_llc mwaitx cpb cat_l3 cdp_l3 hw_pstate ssbd mba perfmon_v2 ibrs ibpb stibp ibrs_enhanced vmmcall fsgsbase bmi1 avx2 smep bmi2 erms invpcid cqm rdt_a avx512f avx512dq rdseed adx smap avx512ifma clflushopt clwb avx512cd sha_ni avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local user_shstk avx512_bf16 clzero irperf xsaveerptr rdpru wbnoinvd cppc arat npt lbrv svm_lock nrip_save tsc_scale vmcb_clean flushbyasid decodeassists pausefilter pfthreshold avic v_vmsave_vmload vgif x2avic v_spec_ctrl vnmi avx512vbmi umip pku ospke avx512_vbmi2 gfni vaes vpclmulqdq avx512_vnni avx512_bitalg avx512_vpopcntdq rdpid overflow_recov succor smca fsrm flush_l1d\nbugs\t\t: sysret_ss_attrs spectre_v1 spectre_v2 spec_store_bypass srso\nbogomips\t: 8983.23\nTLB size\t: 3584 4K pages\nclflush size\t: 64\ncache_alignment\t: 64\naddress sizes\t: 48 bits physical, 48 bits virtual\npower management: ts ttp tm hwpstate cpb eff_freq_ro [13] [14]\n\nprocessor\t: 14\nvendor_id\t: AuthenticAMD\ncpu family\t: 25\nmodel\t\t: 97\nmodel name\t: AMD Ryzen 9 7950X 16-Core Processor\nstepping\t: 2\nmicrocode\t: 0xa601201\ncpu MHz\t\t: 4519.257\ncache size\t: 1024 KB\nphysical id\t: 0\nsiblings\t: 32\ncore id\t\t: 14\ncpu cores\t: 16\napicid\t\t: 28\ninitial apicid\t: 28\nfpu\t\t: yes\nfpu_exception\t: yes\ncpuid level\t: 16\nwp\t\t: yes\nflags\t\t: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good amd_lbr_v2 nopl nonstop_tsc cpuid extd_apicid aperfmperf rapl pni pclmulqdq monitor ssse3 fma cx16 sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx f16c rdrand lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw ibs skinit wdt tce topoext perfctr_core perfctr_nb bpext perfctr_llc mwaitx cpb cat_l3 cdp_l3 hw_pstate ssbd mba perfmon_v2 ibrs ibpb stibp ibrs_enhanced vmmcall fsgsbase bmi1 avx2 smep bmi2 erms invpcid cqm rdt_a avx512f avx512dq rdseed adx smap avx512ifma clflushopt clwb avx512cd sha_ni avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local user_shstk avx512_bf16 clzero irperf xsaveerptr rdpru wbnoinvd cppc arat npt lbrv svm_lock nrip_save tsc_scale vmcb_clean flushbyasid decodeassists pausefilter pfthreshold avic v_vmsave_vmload vgif x2avic v_spec_ctrl vnmi avx512vbmi umip pku ospke avx512_vbmi2 gfni vaes vpclmulqdq avx512_vnni avx512_bitalg avx512_vpopcntdq rdpid overflow_recov succor smca fsrm flush_l1d\nbugs\t\t: sysret_ss_attrs spectre_v1 spectre_v2 spec_store_bypass srso\nbogomips\t: 8983.23\nTLB size\t: 3584 4K pages\nclflush size\t: 64\ncache_alignment\t: 64\naddress sizes\t: 48 bits physical, 48 bits virtual\npower management: ts ttp tm hwpstate cpb eff_freq_ro [13] [14]\n\nprocessor\t: 15\nvendor_id\t: AuthenticAMD\ncpu family\t: 25\nmodel\t\t: 97\nmodel name\t: AMD Ryzen 9 7950X 16-Core Processor\nstepping\t: 2\nmicrocode\t: 0xa601201\ncpu MHz\t\t: 5414.841\ncache size\t: 1024 KB\nphysical id\t: 0\nsiblings\t: 32\ncore id\t\t: 15\ncpu cores\t: 16\napicid\t\t: 30\ninitial apicid\t: 30\nfpu\t\t: yes\nfpu_exception\t: yes\ncpuid level\t: 16\nwp\t\t: yes\nflags\t\t: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good amd_lbr_v2 nopl nonstop_tsc cpuid extd_apicid aperfmperf rapl pni pclmulqdq monitor ssse3 fma cx16 sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx f16c rdrand lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw ibs skinit wdt tce topoext perfctr_core perfctr_nb bpext perfctr_llc mwaitx cpb cat_l3 cdp_l3 hw_pstate ssbd mba perfmon_v2 ibrs ibpb stibp ibrs_enhanced vmmcall fsgsbase bmi1 avx2 smep bmi2 erms invpcid cqm rdt_a avx512f avx512dq rdseed adx smap avx512ifma clflushopt clwb avx512cd sha_ni avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local user_shstk avx512_bf16 clzero irperf xsaveerptr rdpru wbnoinvd cppc arat npt lbrv svm_lock nrip_save tsc_scale vmcb_clean flushbyasid decodeassists pausefilter pfthreshold avic v_vmsave_vmload vgif x2avic v_spec_ctrl vnmi avx512vbmi umip pku ospke avx512_vbmi2 gfni vaes vpclmulqdq avx512_vnni avx512_bitalg avx512_vpopcntdq rdpid overflow_recov succor smca fsrm flush_l1d\nbugs\t\t: sysret_ss_attrs spectre_v1 spectre_v2 spec_store_bypass srso\nbogomips\t: 8983.23\nTLB size\t: 3584 4K pages\nclflush size\t: 64\ncache_alignment\t: 64\naddress sizes\t: 48 bits physical, 48 bits virtual\npower management: ts ttp tm hwpstate cpb eff_freq_ro [13] [14]\n\nprocessor\t: 16\nvendor_id\t: AuthenticAMD\ncpu family\t: 25\nmodel\t\t: 97\nmodel name\t: AMD Ryzen 9 7950X 16-Core Processor\nstepping\t: 2\nmicrocode\t: 0xa601201\ncpu MHz\t\t: 4738.471\ncache size\t: 1024 KB\nphysical id\t: 0\nsiblings\t: 32\ncore id\t\t: 0\ncpu cores\t: 16\napicid\t\t: 1\ninitial apicid\t: 1\nfpu\t\t: yes\nfpu_exception\t: yes\ncpuid level\t: 16\nwp\t\t: yes\nflags\t\t: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good amd_lbr_v2 nopl nonstop_tsc cpuid extd_apicid aperfmperf rapl pni pclmulqdq monitor ssse3 fma cx16 sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx f16c rdrand lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw ibs skinit wdt tce topoext perfctr_core perfctr_nb bpext perfctr_llc mwaitx cpb cat_l3 cdp_l3 hw_pstate ssbd mba perfmon_v2 ibrs ibpb stibp ibrs_enhanced vmmcall fsgsbase bmi1 avx2 smep bmi2 erms invpcid cqm rdt_a avx512f avx512dq rdseed adx smap avx512ifma clflushopt clwb avx512cd sha_ni avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local user_shstk avx512_bf16 clzero irperf xsaveerptr rdpru wbnoinvd cppc arat npt lbrv svm_lock nrip_save tsc_scale vmcb_clean flushbyasid decodeassists pausefilter pfthreshold avic v_vmsave_vmload vgif x2avic v_spec_ctrl vnmi avx512vbmi umip pku ospke avx512_vbmi2 gfni vaes vpclmulqdq avx512_vnni avx512_bitalg avx512_vpopcntdq rdpid overflow_recov succor smca fsrm flush_l1d\nbugs\t\t: sysret_ss_attrs spectre_v1 spectre_v2 spec_store_bypass srso\nbogomips\t: 8983.23\nTLB size\t: 3584 4K pages\nclflush size\t: 64\ncache_alignment\t: 64\naddress sizes\t: 48 bits physical, 48 bits virtual\npower management: ts ttp tm hwpstate cpb eff_freq_ro [13] [14]\n\nprocessor\t: 17\nvendor_id\t: AuthenticAMD\ncpu family\t: 25\nmodel\t\t: 97\nmodel name\t: AMD Ryzen 9 7950X 16-Core Processor\nstepping\t: 2\nmicrocode\t: 0xa601201\ncpu MHz\t\t: 5599.000\ncache size\t: 1024 KB\nphysical id\t: 0\nsiblings\t: 32\ncore id\t\t: 1\ncpu cores\t: 16\napicid\t\t: 3\ninitial apicid\t: 3\nfpu\t\t: yes\nfpu_exception\t: yes\ncpuid level\t: 16\nwp\t\t: yes\nflags\t\t: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good amd_lbr_v2 nopl nonstop_tsc cpuid extd_apicid aperfmperf rapl pni pclmulqdq monitor ssse3 fma cx16 sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx f16c rdrand lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw ibs skinit wdt tce topoext perfctr_core perfctr_nb bpext perfctr_llc mwaitx cpb cat_l3 cdp_l3 hw_pstate ssbd mba perfmon_v2 ibrs ibpb stibp ibrs_enhanced vmmcall fsgsbase bmi1 avx2 smep bmi2 erms invpcid cqm rdt_a avx512f avx512dq rdseed adx smap avx512ifma clflushopt clwb avx512cd sha_ni avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local user_shstk avx512_bf16 clzero irperf xsaveerptr rdpru wbnoinvd cppc arat npt lbrv svm_lock nrip_save tsc_scale vmcb_clean flushbyasid decodeassists pausefilter pfthreshold avic v_vmsave_vmload vgif x2avic v_spec_ctrl vnmi avx512vbmi umip pku ospke avx512_vbmi2 gfni vaes vpclmulqdq avx512_vnni avx512_bitalg avx512_vpopcntdq rdpid overflow_recov succor smca fsrm flush_l1d\nbugs\t\t: sysret_ss_attrs spectre_v1 spectre_v2 spec_store_bypass srso\nbogomips\t: 8983.23\nTLB size\t: 3584 4K pages\nclflush size\t: 64\ncache_alignment\t: 64\naddress sizes\t: 48 bits physical, 48 bits virtual\npower management: ts ttp tm hwpstate cpb eff_freq_ro [13] [14]\n\nprocessor\t: 18\nvendor_id\t: AuthenticAMD\ncpu family\t: 25\nmodel\t\t: 97\nmodel name\t: AMD Ryzen 9 7950X 16-Core Processor\nstepping\t: 2\nmicrocode\t: 0xa601201\ncpu MHz\t\t: 5477.067\ncache size\t: 1024 KB\nphysical id\t: 0\nsiblings\t: 32\ncore id\t\t: 2\ncpu cores\t: 16\napicid\t\t: 5\ninitial apicid\t: 5\nfpu\t\t: yes\nfpu_exception\t: yes\ncpuid level\t: 16\nwp\t\t: yes\nflags\t\t: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good amd_lbr_v2 nopl nonstop_tsc cpuid extd_apicid aperfmperf rapl pni pclmulqdq monitor ssse3 fma cx16 sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx f16c rdrand lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw ibs skinit wdt tce topoext perfctr_core perfctr_nb bpext perfctr_llc mwaitx cpb cat_l3 cdp_l3 hw_pstate ssbd mba perfmon_v2 ibrs ibpb stibp ibrs_enhanced vmmcall fsgsbase bmi1 avx2 smep bmi2 erms invpcid cqm rdt_a avx512f avx512dq rdseed adx smap avx512ifma clflushopt clwb avx512cd sha_ni avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local user_shstk avx512_bf16 clzero irperf xsaveerptr rdpru wbnoinvd cppc arat npt lbrv svm_lock nrip_save tsc_scale vmcb_clean flushbyasid decodeassists pausefilter pfthreshold avic v_vmsave_vmload vgif x2avic v_spec_ctrl vnmi avx512vbmi umip pku ospke avx512_vbmi2 gfni vaes vpclmulqdq avx512_vnni avx512_bitalg avx512_vpopcntdq rdpid overflow_recov succor smca fsrm flush_l1d\nbugs\t\t: sysret_ss_attrs spectre_v1 spectre_v2 spec_store_bypass srso\nbogomips\t: 8983.23\nTLB size\t: 3584 4K pages\nclflush size\t: 64\ncache_alignment\t: 64\naddress sizes\t: 48 bits physical, 48 bits virtual\npower management: ts ttp tm hwpstate cpb eff_freq_ro [13] [14]\n\nprocessor\t: 19\nvendor_id\t: AuthenticAMD\ncpu family\t: 25\nmodel\t\t: 97\nmodel name\t: AMD Ryzen 9 7950X 16-Core Processor\nstepping\t: 2\nmicrocode\t: 0xa601201\ncpu MHz\t\t: 5507.543\ncache size\t: 1024 KB\nphysical id\t: 0\nsiblings\t: 32\ncore id\t\t: 3\ncpu cores\t: 16\napicid\t\t: 7\ninitial apicid\t: 7\nfpu\t\t: yes\nfpu_exception\t: yes\ncpuid level\t: 16\nwp\t\t: yes\nflags\t\t: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good amd_lbr_v2 nopl nonstop_tsc cpuid extd_apicid aperfmperf rapl pni pclmulqdq monitor ssse3 fma cx16 sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx f16c rdrand lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw ibs skinit wdt tce topoext perfctr_core perfctr_nb bpext perfctr_llc mwaitx cpb cat_l3 cdp_l3 hw_pstate ssbd mba perfmon_v2 ibrs ibpb stibp ibrs_enhanced vmmcall fsgsbase bmi1 avx2 smep bmi2 erms invpcid cqm rdt_a avx512f avx512dq rdseed adx smap avx512ifma clflushopt clwb avx512cd sha_ni avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local user_shstk avx512_bf16 clzero irperf xsaveerptr rdpru wbnoinvd cppc arat npt lbrv svm_lock nrip_save tsc_scale vmcb_clean flushbyasid decodeassists pausefilter pfthreshold avic v_vmsave_vmload vgif x2avic v_spec_ctrl vnmi avx512vbmi umip pku ospke avx512_vbmi2 gfni vaes vpclmulqdq avx512_vnni avx512_bitalg avx512_vpopcntdq rdpid overflow_recov succor smca fsrm flush_l1d\nbugs\t\t: sysret_ss_attrs spectre_v1 spectre_v2 spec_store_bypass srso\nbogomips\t: 8983.23\nTLB size\t: 3584 4K pages\nclflush size\t: 64\ncache_alignment\t: 64\naddress sizes\t: 48 bits physical, 48 bits virtual\npower management: ts ttp tm hwpstate cpb eff_freq_ro [13] [14]\n\nprocessor\t: 20\nvendor_id\t: AuthenticAMD\ncpu family\t: 25\nmodel\t\t: 97\nmodel name\t: AMD Ryzen 9 7950X 16-Core Processor\nstepping\t: 2\nmicrocode\t: 0xa601201\ncpu MHz\t\t: 4401.379\ncache size\t: 1024 KB\nphysical id\t: 0\nsiblings\t: 32\ncore id\t\t: 4\ncpu cores\t: 16\napicid\t\t: 9\ninitial apicid\t: 9\nfpu\t\t: yes\nfpu_exception\t: yes\ncpuid level\t: 16\nwp\t\t: yes\nflags\t\t: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good amd_lbr_v2 nopl nonstop_tsc cpuid extd_apicid aperfmperf rapl pni pclmulqdq monitor ssse3 fma cx16 sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx f16c rdrand lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw ibs skinit wdt tce topoext perfctr_core perfctr_nb bpext perfctr_llc mwaitx cpb cat_l3 cdp_l3 hw_pstate ssbd mba perfmon_v2 ibrs ibpb stibp ibrs_enhanced vmmcall fsgsbase bmi1 avx2 smep bmi2 erms invpcid cqm rdt_a avx512f avx512dq rdseed adx smap avx512ifma clflushopt clwb avx512cd sha_ni avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local user_shstk avx512_bf16 clzero irperf xsaveerptr rdpru wbnoinvd cppc arat npt lbrv svm_lock nrip_save tsc_scale vmcb_clean flushbyasid decodeassists pausefilter pfthreshold avic v_vmsave_vmload vgif x2avic v_spec_ctrl vnmi avx512vbmi umip pku ospke avx512_vbmi2 gfni vaes vpclmulqdq avx512_vnni avx512_bitalg avx512_vpopcntdq rdpid overflow_recov succor smca fsrm flush_l1d\nbugs\t\t: sysret_ss_attrs spectre_v1 spectre_v2 spec_store_bypass srso\nbogomips\t: 8983.23\nTLB size\t: 3584 4K pages\nclflush size\t: 64\ncache_alignment\t: 64\naddress sizes\t: 48 bits physical, 48 bits virtual\npower management: ts ttp tm hwpstate cpb eff_freq_ro [13] [14]\n\nprocessor\t: 21\nvendor_id\t: AuthenticAMD\ncpu family\t: 25\nmodel\t\t: 97\nmodel name\t: AMD Ryzen 9 7950X 16-Core Processor\nstepping\t: 2\nmicrocode\t: 0xa601201\ncpu MHz\t\t: 400.000\ncache size\t: 1024 KB\nphysical id\t: 0\nsiblings\t: 32\ncore id\t\t: 5\ncpu cores\t: 16\napicid\t\t: 11\ninitial apicid\t: 11\nfpu\t\t: yes\nfpu_exception\t: yes\ncpuid level\t: 16\nwp\t\t: yes\nflags\t\t: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good amd_lbr_v2 nopl nonstop_tsc cpuid extd_apicid aperfmperf rapl pni pclmulqdq monitor ssse3 fma cx16 sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx f16c rdrand lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw ibs skinit wdt tce topoext perfctr_core perfctr_nb bpext perfctr_llc mwaitx cpb cat_l3 cdp_l3 hw_pstate ssbd mba perfmon_v2 ibrs ibpb stibp ibrs_enhanced vmmcall fsgsbase bmi1 avx2 smep bmi2 erms invpcid cqm rdt_a avx512f avx512dq rdseed adx smap avx512ifma clflushopt clwb avx512cd sha_ni avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local user_shstk avx512_bf16 clzero irperf xsaveerptr rdpru wbnoinvd cppc arat npt lbrv svm_lock nrip_save tsc_scale vmcb_clean flushbyasid decodeassists pausefilter pfthreshold avic v_vmsave_vmload vgif x2avic v_spec_ctrl vnmi avx512vbmi umip pku ospke avx512_vbmi2 gfni vaes vpclmulqdq avx512_vnni avx512_bitalg avx512_vpopcntdq rdpid overflow_recov succor smca fsrm flush_l1d\nbugs\t\t: sysret_ss_attrs spectre_v1 spectre_v2 spec_store_bypass srso\nbogomips\t: 8983.23\nTLB size\t: 3584 4K pages\nclflush size\t: 64\ncache_alignment\t: 64\naddress sizes\t: 48 bits physical, 48 bits virtual\npower management: ts ttp tm hwpstate cpb eff_freq_ro [13] [14]\n\nprocessor\t: 22\nvendor_id\t: AuthenticAMD\ncpu family\t: 25\nmodel\t\t: 97\nmodel name\t: AMD Ryzen 9 7950X 16-Core Processor\nstepping\t: 2\nmicrocode\t: 0xa601201\ncpu MHz\t\t: 5607.945\ncache size\t: 1024 KB\nphysical id\t: 0\nsiblings\t: 32\ncore id\t\t: 6\ncpu cores\t: 16\napicid\t\t: 13\ninitial apicid\t: 13\nfpu\t\t: yes\nfpu_exception\t: yes\ncpuid level\t: 16\nwp\t\t: yes\nflags\t\t: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good amd_lbr_v2 nopl nonstop_tsc cpuid extd_apicid aperfmperf rapl pni pclmulqdq monitor ssse3 fma cx16 sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx f16c rdrand lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw ibs skinit wdt tce topoext perfctr_core perfctr_nb bpext perfctr_llc mwaitx cpb cat_l3 cdp_l3 hw_pstate ssbd mba perfmon_v2 ibrs ibpb stibp ibrs_enhanced vmmcall fsgsbase bmi1 avx2 smep bmi2 erms invpcid cqm rdt_a avx512f avx512dq rdseed adx smap avx512ifma clflushopt clwb avx512cd sha_ni avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local user_shstk avx512_bf16 clzero irperf xsaveerptr rdpru wbnoinvd cppc arat npt lbrv svm_lock nrip_save tsc_scale vmcb_clean flushbyasid decodeassists pausefilter pfthreshold avic v_vmsave_vmload vgif x2avic v_spec_ctrl vnmi avx512vbmi umip pku ospke avx512_vbmi2 gfni vaes vpclmulqdq avx512_vnni avx512_bitalg avx512_vpopcntdq rdpid overflow_recov succor smca fsrm flush_l1d\nbugs\t\t: sysret_ss_attrs spectre_v1 spectre_v2 spec_store_bypass srso\nbogomips\t: 8983.23\nTLB size\t: 3584 4K pages\nclflush size\t: 64\ncache_alignment\t: 64\naddress sizes\t: 48 bits physical, 48 bits virtual\npower management: ts ttp tm hwpstate cpb eff_freq_ro [13] [14]\n\nprocessor\t: 23\nvendor_id\t: AuthenticAMD\ncpu family\t: 25\nmodel\t\t: 97\nmodel name\t: AMD Ryzen 9 7950X 16-Core Processor\nstepping\t: 2\nmicrocode\t: 0xa601201\ncpu MHz\t\t: 5280.720\ncache size\t: 1024 KB\nphysical id\t: 0\nsiblings\t: 32\ncore id\t\t: 7\ncpu cores\t: 16\napicid\t\t: 15\ninitial apicid\t: 15\nfpu\t\t: yes\nfpu_exception\t: yes\ncpuid level\t: 16\nwp\t\t: yes\nflags\t\t: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good amd_lbr_v2 nopl nonstop_tsc cpuid extd_apicid aperfmperf rapl pni pclmulqdq monitor ssse3 fma cx16 sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx f16c rdrand lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw ibs skinit wdt tce topoext perfctr_core perfctr_nb bpext perfctr_llc mwaitx cpb cat_l3 cdp_l3 hw_pstate ssbd mba perfmon_v2 ibrs ibpb stibp ibrs_enhanced vmmcall fsgsbase bmi1 avx2 smep bmi2 erms invpcid cqm rdt_a avx512f avx512dq rdseed adx smap avx512ifma clflushopt clwb avx512cd sha_ni avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local user_shstk avx512_bf16 clzero irperf xsaveerptr rdpru wbnoinvd cppc arat npt lbrv svm_lock nrip_save tsc_scale vmcb_clean flushbyasid decodeassists pausefilter pfthreshold avic v_vmsave_vmload vgif x2avic v_spec_ctrl vnmi avx512vbmi umip pku ospke avx512_vbmi2 gfni vaes vpclmulqdq avx512_vnni avx512_bitalg avx512_vpopcntdq rdpid overflow_recov succor smca fsrm flush_l1d\nbugs\t\t: sysret_ss_attrs spectre_v1 spectre_v2 spec_store_bypass srso\nbogomips\t: 8983.23\nTLB size\t: 3584 4K pages\nclflush size\t: 64\ncache_alignment\t: 64\naddress sizes\t: 48 bits physical, 48 bits virtual\npower management: ts ttp tm hwpstate cpb eff_freq_ro [13] [14]\n\nprocessor\t: 24\nvendor_id\t: AuthenticAMD\ncpu family\t: 25\nmodel\t\t: 97\nmodel name\t: AMD Ryzen 9 7950X 16-Core Processor\nstepping\t: 2\nmicrocode\t: 0xa601201\ncpu MHz\t\t: 5414.893\ncache size\t: 1024 KB\nphysical id\t: 0\nsiblings\t: 32\ncore id\t\t: 8\ncpu cores\t: 16\napicid\t\t: 17\ninitial apicid\t: 17\nfpu\t\t: yes\nfpu_exception\t: yes\ncpuid level\t: 16\nwp\t\t: yes\nflags\t\t: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good amd_lbr_v2 nopl nonstop_tsc cpuid extd_apicid aperfmperf rapl pni pclmulqdq monitor ssse3 fma cx16 sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx f16c rdrand lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw ibs skinit wdt tce topoext perfctr_core perfctr_nb bpext perfctr_llc mwaitx cpb cat_l3 cdp_l3 hw_pstate ssbd mba perfmon_v2 ibrs ibpb stibp ibrs_enhanced vmmcall fsgsbase bmi1 avx2 smep bmi2 erms invpcid cqm rdt_a avx512f avx512dq rdseed adx smap avx512ifma clflushopt clwb avx512cd sha_ni avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local user_shstk avx512_bf16 clzero irperf xsaveerptr rdpru wbnoinvd cppc arat npt lbrv svm_lock nrip_save tsc_scale vmcb_clean flushbyasid decodeassists pausefilter pfthreshold avic v_vmsave_vmload vgif x2avic v_spec_ctrl vnmi avx512vbmi umip pku ospke avx512_vbmi2 gfni vaes vpclmulqdq avx512_vnni avx512_bitalg avx512_vpopcntdq rdpid overflow_recov succor smca fsrm flush_l1d\nbugs\t\t: sysret_ss_attrs spectre_v1 spectre_v2 spec_store_bypass srso\nbogomips\t: 8983.23\nTLB size\t: 3584 4K pages\nclflush size\t: 64\ncache_alignment\t: 64\naddress sizes\t: 48 bits physical, 48 bits virtual\npower management: ts ttp tm hwpstate cpb eff_freq_ro [13] [14]\n\nprocessor\t: 25\nvendor_id\t: AuthenticAMD\ncpu family\t: 25\nmodel\t\t: 97\nmodel name\t: AMD Ryzen 9 7950X 16-Core Processor\nstepping\t: 2\nmicrocode\t: 0xa601201\ncpu MHz\t\t: 5414.888\ncache size\t: 1024 KB\nphysical id\t: 0\nsiblings\t: 32\ncore id\t\t: 9\ncpu cores\t: 16\napicid\t\t: 19\ninitial apicid\t: 19\nfpu\t\t: yes\nfpu_exception\t: yes\ncpuid level\t: 16\nwp\t\t: yes\nflags\t\t: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good amd_lbr_v2 nopl nonstop_tsc cpuid extd_apicid aperfmperf rapl pni pclmulqdq monitor ssse3 fma cx16 sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx f16c rdrand lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw ibs skinit wdt tce topoext perfctr_core perfctr_nb bpext perfctr_llc mwaitx cpb cat_l3 cdp_l3 hw_pstate ssbd mba perfmon_v2 ibrs ibpb stibp ibrs_enhanced vmmcall fsgsbase bmi1 avx2 smep bmi2 erms invpcid cqm rdt_a avx512f avx512dq rdseed adx smap avx512ifma clflushopt clwb avx512cd sha_ni avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local user_shstk avx512_bf16 clzero irperf xsaveerptr rdpru wbnoinvd cppc arat npt lbrv svm_lock nrip_save tsc_scale vmcb_clean flushbyasid decodeassists pausefilter pfthreshold avic v_vmsave_vmload vgif x2avic v_spec_ctrl vnmi avx512vbmi umip pku ospke avx512_vbmi2 gfni vaes vpclmulqdq avx512_vnni avx512_bitalg avx512_vpopcntdq rdpid overflow_recov succor smca fsrm flush_l1d\nbugs\t\t: sysret_ss_attrs spectre_v1 spectre_v2 spec_store_bypass srso\nbogomips\t: 8983.23\nTLB size\t: 3584 4K pages\nclflush size\t: 64\ncache_alignment\t: 64\naddress sizes\t: 48 bits physical, 48 bits virtual\npower management: ts ttp tm hwpstate cpb eff_freq_ro [13] [14]\n\nprocessor\t: 26\nvendor_id\t: AuthenticAMD\ncpu family\t: 25\nmodel\t\t: 97\nmodel name\t: AMD Ryzen 9 7950X 16-Core Processor\nstepping\t: 2\nmicrocode\t: 0xa601201\ncpu MHz\t\t: 5385.641\ncache size\t: 1024 KB\nphysical id\t: 0\nsiblings\t: 32\ncore id\t\t: 10\ncpu cores\t: 16\napicid\t\t: 21\ninitial apicid\t: 21\nfpu\t\t: yes\nfpu_exception\t: yes\ncpuid level\t: 16\nwp\t\t: yes\nflags\t\t: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good amd_lbr_v2 nopl nonstop_tsc cpuid extd_apicid aperfmperf rapl pni pclmulqdq monitor ssse3 fma cx16 sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx f16c rdrand lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw ibs skinit wdt tce topoext perfctr_core perfctr_nb bpext perfctr_llc mwaitx cpb cat_l3 cdp_l3 hw_pstate ssbd mba perfmon_v2 ibrs ibpb stibp ibrs_enhanced vmmcall fsgsbase bmi1 avx2 smep bmi2 erms invpcid cqm rdt_a avx512f avx512dq rdseed adx smap avx512ifma clflushopt clwb avx512cd sha_ni avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local user_shstk avx512_bf16 clzero irperf xsaveerptr rdpru wbnoinvd cppc arat npt lbrv svm_lock nrip_save tsc_scale vmcb_clean flushbyasid decodeassists pausefilter pfthreshold avic v_vmsave_vmload vgif x2avic v_spec_ctrl vnmi avx512vbmi umip pku ospke avx512_vbmi2 gfni vaes vpclmulqdq avx512_vnni avx512_bitalg avx512_vpopcntdq rdpid overflow_recov succor smca fsrm flush_l1d\nbugs\t\t: sysret_ss_attrs spectre_v1 spectre_v2 spec_store_bypass srso\nbogomips\t: 8983.23\nTLB size\t: 3584 4K pages\nclflush size\t: 64\ncache_alignment\t: 64\naddress sizes\t: 48 bits physical, 48 bits virtual\npower management: ts ttp tm hwpstate cpb eff_freq_ro [13] [14]\n\nprocessor\t: 27\nvendor_id\t: AuthenticAMD\ncpu family\t: 25\nmodel\t\t: 97\nmodel name\t: AMD Ryzen 9 7950X 16-Core Processor\nstepping\t: 2\nmicrocode\t: 0xa601201\ncpu MHz\t\t: 3130.265\ncache size\t: 1024 KB\nphysical id\t: 0\nsiblings\t: 32\ncore id\t\t: 11\ncpu cores\t: 16\napicid\t\t: 23\ninitial apicid\t: 23\nfpu\t\t: yes\nfpu_exception\t: yes\ncpuid level\t: 16\nwp\t\t: yes\nflags\t\t: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good amd_lbr_v2 nopl nonstop_tsc cpuid extd_apicid aperfmperf rapl pni pclmulqdq monitor ssse3 fma cx16 sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx f16c rdrand lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw ibs skinit wdt tce topoext perfctr_core perfctr_nb bpext perfctr_llc mwaitx cpb cat_l3 cdp_l3 hw_pstate ssbd mba perfmon_v2 ibrs ibpb stibp ibrs_enhanced vmmcall fsgsbase bmi1 avx2 smep bmi2 erms invpcid cqm rdt_a avx512f avx512dq rdseed adx smap avx512ifma clflushopt clwb avx512cd sha_ni avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local user_shstk avx512_bf16 clzero irperf xsaveerptr rdpru wbnoinvd cppc arat npt lbrv svm_lock nrip_save tsc_scale vmcb_clean flushbyasid decodeassists pausefilter pfthreshold avic v_vmsave_vmload vgif x2avic v_spec_ctrl vnmi avx512vbmi umip pku ospke avx512_vbmi2 gfni vaes vpclmulqdq avx512_vnni avx512_bitalg avx512_vpopcntdq rdpid overflow_recov succor smca fsrm flush_l1d\nbugs\t\t: sysret_ss_attrs spectre_v1 spectre_v2 spec_store_bypass srso\nbogomips\t: 8983.23\nTLB size\t: 3584 4K pages\nclflush size\t: 64\ncache_alignment\t: 64\naddress sizes\t: 48 bits physical, 48 bits virtual\npower management: ts ttp tm hwpstate cpb eff_freq_ro [13] [14]\n\nprocessor\t: 28\nvendor_id\t: AuthenticAMD\ncpu family\t: 25\nmodel\t\t: 97\nmodel name\t: AMD Ryzen 9 7950X 16-Core Processor\nstepping\t: 2\nmicrocode\t: 0xa601201\ncpu MHz\t\t: 5400.876\ncache size\t: 1024 KB\nphysical id\t: 0\nsiblings\t: 32\ncore id\t\t: 12\ncpu cores\t: 16\napicid\t\t: 25\ninitial apicid\t: 25\nfpu\t\t: yes\nfpu_exception\t: yes\ncpuid level\t: 16\nwp\t\t: yes\nflags\t\t: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good amd_lbr_v2 nopl nonstop_tsc cpuid extd_apicid aperfmperf rapl pni pclmulqdq monitor ssse3 fma cx16 sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx f16c rdrand lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw ibs skinit wdt tce topoext perfctr_core perfctr_nb bpext perfctr_llc mwaitx cpb cat_l3 cdp_l3 hw_pstate ssbd mba perfmon_v2 ibrs ibpb stibp ibrs_enhanced vmmcall fsgsbase bmi1 avx2 smep bmi2 erms invpcid cqm rdt_a avx512f avx512dq rdseed adx smap avx512ifma clflushopt clwb avx512cd sha_ni avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local user_shstk avx512_bf16 clzero irperf xsaveerptr rdpru wbnoinvd cppc arat npt lbrv svm_lock nrip_save tsc_scale vmcb_clean flushbyasid decodeassists pausefilter pfthreshold avic v_vmsave_vmload vgif x2avic v_spec_ctrl vnmi avx512vbmi umip pku ospke avx512_vbmi2 gfni vaes vpclmulqdq avx512_vnni avx512_bitalg avx512_vpopcntdq rdpid overflow_recov succor smca fsrm flush_l1d\nbugs\t\t: sysret_ss_attrs spectre_v1 spectre_v2 spec_store_bypass srso\nbogomips\t: 8983.23\nTLB size\t: 3584 4K pages\nclflush size\t: 64\ncache_alignment\t: 64\naddress sizes\t: 48 bits physical, 48 bits virtual\npower management: ts ttp tm hwpstate cpb eff_freq_ro [13] [14]\n\nprocessor\t: 29\nvendor_id\t: AuthenticAMD\ncpu family\t: 25\nmodel\t\t: 97\nmodel name\t: AMD Ryzen 9 7950X 16-Core Processor\nstepping\t: 2\nmicrocode\t: 0xa601201\ncpu MHz\t\t: 4279.794\ncache size\t: 1024 KB\nphysical id\t: 0\nsiblings\t: 32\ncore id\t\t: 13\ncpu cores\t: 16\napicid\t\t: 27\ninitial apicid\t: 27\nfpu\t\t: yes\nfpu_exception\t: yes\ncpuid level\t: 16\nwp\t\t: yes\nflags\t\t: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good amd_lbr_v2 nopl nonstop_tsc cpuid extd_apicid aperfmperf rapl pni pclmulqdq monitor ssse3 fma cx16 sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx f16c rdrand lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw ibs skinit wdt tce topoext perfctr_core perfctr_nb bpext perfctr_llc mwaitx cpb cat_l3 cdp_l3 hw_pstate ssbd mba perfmon_v2 ibrs ibpb stibp ibrs_enhanced vmmcall fsgsbase bmi1 avx2 smep bmi2 erms invpcid cqm rdt_a avx512f avx512dq rdseed adx smap avx512ifma clflushopt clwb avx512cd sha_ni avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local user_shstk avx512_bf16 clzero irperf xsaveerptr rdpru wbnoinvd cppc arat npt lbrv svm_lock nrip_save tsc_scale vmcb_clean flushbyasid decodeassists pausefilter pfthreshold avic v_vmsave_vmload vgif x2avic v_spec_ctrl vnmi avx512vbmi umip pku ospke avx512_vbmi2 gfni vaes vpclmulqdq avx512_vnni avx512_bitalg avx512_vpopcntdq rdpid overflow_recov succor smca fsrm flush_l1d\nbugs\t\t: sysret_ss_attrs spectre_v1 spectre_v2 spec_store_bypass srso\nbogomips\t: 8983.23\nTLB size\t: 3584 4K pages\nclflush size\t: 64\ncache_alignment\t: 64\naddress sizes\t: 48 bits physical, 48 bits virtual\npower management: ts ttp tm hwpstate cpb eff_freq_ro [13] [14]\n\nprocessor\t: 30\nvendor_id\t: AuthenticAMD\ncpu family\t: 25\nmodel\t\t: 97\nmodel name\t: AMD Ryzen 9 7950X 16-Core Processor\nstepping\t: 2\nmicrocode\t: 0xa601201\ncpu MHz\t\t: 3124.980\ncache size\t: 1024 KB\nphysical id\t: 0\nsiblings\t: 32\ncore id\t\t: 14\ncpu cores\t: 16\napicid\t\t: 29\ninitial apicid\t: 29\nfpu\t\t: yes\nfpu_exception\t: yes\ncpuid level\t: 16\nwp\t\t: yes\nflags\t\t: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good amd_lbr_v2 nopl nonstop_tsc cpuid extd_apicid aperfmperf rapl pni pclmulqdq monitor ssse3 fma cx16 sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx f16c rdrand lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw ibs skinit wdt tce topoext perfctr_core perfctr_nb bpext perfctr_llc mwaitx cpb cat_l3 cdp_l3 hw_pstate ssbd mba perfmon_v2 ibrs ibpb stibp ibrs_enhanced vmmcall fsgsbase bmi1 avx2 smep bmi2 erms invpcid cqm rdt_a avx512f avx512dq rdseed adx smap avx512ifma clflushopt clwb avx512cd sha_ni avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local user_shstk avx512_bf16 clzero irperf xsaveerptr rdpru wbnoinvd cppc arat npt lbrv svm_lock nrip_save tsc_scale vmcb_clean flushbyasid decodeassists pausefilter pfthreshold avic v_vmsave_vmload vgif x2avic v_spec_ctrl vnmi avx512vbmi umip pku ospke avx512_vbmi2 gfni vaes vpclmulqdq avx512_vnni avx512_bitalg avx512_vpopcntdq rdpid overflow_recov succor smca fsrm flush_l1d\nbugs\t\t: sysret_ss_attrs spectre_v1 spectre_v2 spec_store_bypass srso\nbogomips\t: 8983.23\nTLB size\t: 3584 4K pages\nclflush size\t: 64\ncache_alignment\t: 64\naddress sizes\t: 48 bits physical, 48 bits virtual\npower management: ts ttp tm hwpstate cpb eff_freq_ro [13] [14]\n\nprocessor\t: 31\nvendor_id\t: AuthenticAMD\ncpu family\t: 25\nmodel\t\t: 97\nmodel name\t: AMD Ryzen 9 7950X 16-Core Processor\nstepping\t: 2\nmicrocode\t: 0xa601201\ncpu MHz\t\t: 5389.561\ncache size\t: 1024 KB\nphysical id\t: 0\nsiblings\t: 32\ncore id\t\t: 15\ncpu cores\t: 16\napicid\t\t: 31\ninitial apicid\t: 31\nfpu\t\t: yes\nfpu_exception\t: yes\ncpuid level\t: 16\nwp\t\t: yes\nflags\t\t: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good amd_lbr_v2 nopl nonstop_tsc cpuid extd_apicid aperfmperf rapl pni pclmulqdq monitor ssse3 fma cx16 sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx f16c rdrand lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw ibs skinit wdt tce topoext perfctr_core perfctr_nb bpext perfctr_llc mwaitx cpb cat_l3 cdp_l3 hw_pstate ssbd mba perfmon_v2 ibrs ibpb stibp ibrs_enhanced vmmcall fsgsbase bmi1 avx2 smep bmi2 erms invpcid cqm rdt_a avx512f avx512dq rdseed adx smap avx512ifma clflushopt clwb avx512cd sha_ni avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local user_shstk avx512_bf16 clzero irperf xsaveerptr rdpru wbnoinvd cppc arat npt lbrv svm_lock nrip_save tsc_scale vmcb_clean flushbyasid decodeassists pausefilter pfthreshold avic v_vmsave_vmload vgif x2avic v_spec_ctrl vnmi avx512vbmi umip pku ospke avx512_vbmi2 gfni vaes vpclmulqdq avx512_vnni avx512_bitalg avx512_vpopcntdq rdpid overflow_recov succor smca fsrm flush_l1d\nbugs\t\t: sysret_ss_attrs spectre_v1 spectre_v2 spec_store_bypass srso\nbogomips\t: 8983.23\nTLB size\t: 3584 4K pages\nclflush size\t: 64\ncache_alignment\t: 64\naddress sizes\t: 48 bits physical, 48 bits virtual\npower management: ts ttp tm hwpstate cpb eff_freq_ro [13] [14]\n\n"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Detectors/Cpu/TestHelper.cs",
    "content": "﻿using System.IO;\nusing System.Reflection;\nusing JetBrains.Annotations;\nusing Perfolizer.Helpers;\nusing Perfolizer.Models;\nusing Xunit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.Tests.Detectors.Cpu;\n\npublic static class TestHelper\n{\n    public static string ReadTestFile(string name)\n    {\n        var assembly = typeof(TestHelper).GetTypeInfo().Assembly;\n        string resourceName = $\"{typeof(TestHelper).Namespace}.TestFiles.{name}\";\n\n        using var stream = assembly.GetManifestResourceStream(resourceName);\n        if (stream == null)\n            throw new FileNotFoundException($\"Resource {resourceName} not found in {assembly.FullName}\");\n\n        using var reader = new StreamReader(stream);\n        return reader.ReadToEnd();\n    }\n\n    [AssertionMethod]\n    public static void AssertEqual(this ITestOutputHelper output, CpuInfo expected, CpuInfo actual)\n    {\n        output.WriteLine($\"Expected : {expected.ToFullBrandName()}\");\n        output.WriteLine($\"Actual   : {actual.ToFullBrandName()}\");\n        Assert.Equal(expected.ProcessorName, actual.ProcessorName);\n        Assert.Equal(expected.PhysicalProcessorCount, actual.PhysicalProcessorCount);\n        Assert.Equal(expected.PhysicalCoreCount, actual.PhysicalCoreCount);\n        Assert.Equal(expected.LogicalCoreCount, actual.LogicalCoreCount);\n        Assert.Equal(expected.NominalFrequency(), actual.NominalFrequency());\n        Assert.Equal(expected.MaxFrequency(), actual.MaxFrequency());\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Detectors/Cpu/VerifiedFiles/CpuInfoFormatterTests.FormatTest.verified.txt",
    "content": "﻿Unknown processor\nUnknown processor\nUnknown processor, 1 logical core\nUnknown processor, 2 logical cores\nUnknown processor\nUnknown processor\nUnknown processor, 1 logical core\nUnknown processor, 2 logical cores\nUnknown processor, 1 physical core\nUnknown processor, 1 physical core\nUnknown processor, 1 logical core and 1 physical core\nUnknown processor, 2 logical cores and 1 physical core\nUnknown processor, 2 physical cores\nUnknown processor, 2 physical cores\nUnknown processor, 1 logical core and 2 physical cores\nUnknown processor, 2 logical and 2 physical cores\nUnknown processor\nUnknown processor\nUnknown processor, 1 logical core\nUnknown processor, 2 logical cores\nUnknown processor\nUnknown processor\nUnknown processor, 1 logical core\nUnknown processor, 2 logical cores\nUnknown processor, 1 physical core\nUnknown processor, 1 physical core\nUnknown processor, 1 logical core and 1 physical core\nUnknown processor, 2 logical cores and 1 physical core\nUnknown processor, 2 physical cores\nUnknown processor, 2 physical cores\nUnknown processor, 1 logical core and 2 physical cores\nUnknown processor, 2 logical and 2 physical cores\nUnknown processor, 1 CPU\nUnknown processor, 1 CPU\nUnknown processor, 1 CPU, 1 logical core\nUnknown processor, 1 CPU, 2 logical cores\nUnknown processor, 1 CPU\nUnknown processor, 1 CPU\nUnknown processor, 1 CPU, 1 logical core\nUnknown processor, 1 CPU, 2 logical cores\nUnknown processor, 1 CPU, 1 physical core\nUnknown processor, 1 CPU, 1 physical core\nUnknown processor, 1 CPU, 1 logical core and 1 physical core\nUnknown processor, 1 CPU, 2 logical cores and 1 physical core\nUnknown processor, 1 CPU, 2 physical cores\nUnknown processor, 1 CPU, 2 physical cores\nUnknown processor, 1 CPU, 1 logical core and 2 physical cores\nUnknown processor, 1 CPU, 2 logical and 2 physical cores\nUnknown processor, 2 CPU\nUnknown processor, 2 CPU\nUnknown processor, 2 CPU, 1 logical core\nUnknown processor, 2 CPU, 2 logical cores\nUnknown processor, 2 CPU\nUnknown processor, 2 CPU\nUnknown processor, 2 CPU, 1 logical core\nUnknown processor, 2 CPU, 2 logical cores\nUnknown processor, 2 CPU, 1 physical core\nUnknown processor, 2 CPU, 1 physical core\nUnknown processor, 2 CPU, 1 logical core and 1 physical core\nUnknown processor, 2 CPU, 2 logical cores and 1 physical core\nUnknown processor, 2 CPU, 2 physical cores\nUnknown processor, 2 CPU, 2 physical cores\nUnknown processor, 2 CPU, 1 logical core and 2 physical cores\nUnknown processor, 2 CPU, 2 logical and 2 physical cores\nUnknown processor\nUnknown processor\nUnknown processor, 1 logical core\nUnknown processor, 2 logical cores\nUnknown processor\nUnknown processor\nUnknown processor, 1 logical core\nUnknown processor, 2 logical cores\nUnknown processor, 1 physical core\nUnknown processor, 1 physical core\nUnknown processor, 1 logical core and 1 physical core\nUnknown processor, 2 logical cores and 1 physical core\nUnknown processor, 2 physical cores\nUnknown processor, 2 physical cores\nUnknown processor, 1 logical core and 2 physical cores\nUnknown processor, 2 logical and 2 physical cores\nUnknown processor\nUnknown processor\nUnknown processor, 1 logical core\nUnknown processor, 2 logical cores\nUnknown processor\nUnknown processor\nUnknown processor, 1 logical core\nUnknown processor, 2 logical cores\nUnknown processor, 1 physical core\nUnknown processor, 1 physical core\nUnknown processor, 1 logical core and 1 physical core\nUnknown processor, 2 logical cores and 1 physical core\nUnknown processor, 2 physical cores\nUnknown processor, 2 physical cores\nUnknown processor, 1 logical core and 2 physical cores\nUnknown processor, 2 logical and 2 physical cores\nUnknown processor, 1 CPU\nUnknown processor, 1 CPU\nUnknown processor, 1 CPU, 1 logical core\nUnknown processor, 1 CPU, 2 logical cores\nUnknown processor, 1 CPU\nUnknown processor, 1 CPU\nUnknown processor, 1 CPU, 1 logical core\nUnknown processor, 1 CPU, 2 logical cores\nUnknown processor, 1 CPU, 1 physical core\nUnknown processor, 1 CPU, 1 physical core\nUnknown processor, 1 CPU, 1 logical core and 1 physical core\nUnknown processor, 1 CPU, 2 logical cores and 1 physical core\nUnknown processor, 1 CPU, 2 physical cores\nUnknown processor, 1 CPU, 2 physical cores\nUnknown processor, 1 CPU, 1 logical core and 2 physical cores\nUnknown processor, 1 CPU, 2 logical and 2 physical cores\nUnknown processor, 2 CPU\nUnknown processor, 2 CPU\nUnknown processor, 2 CPU, 1 logical core\nUnknown processor, 2 CPU, 2 logical cores\nUnknown processor, 2 CPU\nUnknown processor, 2 CPU\nUnknown processor, 2 CPU, 1 logical core\nUnknown processor, 2 CPU, 2 logical cores\nUnknown processor, 2 CPU, 1 physical core\nUnknown processor, 2 CPU, 1 physical core\nUnknown processor, 2 CPU, 1 logical core and 1 physical core\nUnknown processor, 2 CPU, 2 logical cores and 1 physical core\nUnknown processor, 2 CPU, 2 physical cores\nUnknown processor, 2 CPU, 2 physical cores\nUnknown processor, 2 CPU, 1 logical core and 2 physical cores\nUnknown processor, 2 CPU, 2 logical and 2 physical cores\nIntel\nIntel\nIntel, 1 logical core\nIntel, 2 logical cores\nIntel\nIntel\nIntel, 1 logical core\nIntel, 2 logical cores\nIntel, 1 physical core\nIntel, 1 physical core\nIntel, 1 logical core and 1 physical core\nIntel, 2 logical cores and 1 physical core\nIntel, 2 physical cores\nIntel, 2 physical cores\nIntel, 1 logical core and 2 physical cores\nIntel, 2 logical and 2 physical cores\nIntel\nIntel\nIntel, 1 logical core\nIntel, 2 logical cores\nIntel\nIntel\nIntel, 1 logical core\nIntel, 2 logical cores\nIntel, 1 physical core\nIntel, 1 physical core\nIntel, 1 logical core and 1 physical core\nIntel, 2 logical cores and 1 physical core\nIntel, 2 physical cores\nIntel, 2 physical cores\nIntel, 1 logical core and 2 physical cores\nIntel, 2 logical and 2 physical cores\nIntel, 1 CPU\nIntel, 1 CPU\nIntel, 1 CPU, 1 logical core\nIntel, 1 CPU, 2 logical cores\nIntel, 1 CPU\nIntel, 1 CPU\nIntel, 1 CPU, 1 logical core\nIntel, 1 CPU, 2 logical cores\nIntel, 1 CPU, 1 physical core\nIntel, 1 CPU, 1 physical core\nIntel, 1 CPU, 1 logical core and 1 physical core\nIntel, 1 CPU, 2 logical cores and 1 physical core\nIntel, 1 CPU, 2 physical cores\nIntel, 1 CPU, 2 physical cores\nIntel, 1 CPU, 1 logical core and 2 physical cores\nIntel, 1 CPU, 2 logical and 2 physical cores\nIntel, 2 CPU\nIntel, 2 CPU\nIntel, 2 CPU, 1 logical core\nIntel, 2 CPU, 2 logical cores\nIntel, 2 CPU\nIntel, 2 CPU\nIntel, 2 CPU, 1 logical core\nIntel, 2 CPU, 2 logical cores\nIntel, 2 CPU, 1 physical core\nIntel, 2 CPU, 1 physical core\nIntel, 2 CPU, 1 logical core and 1 physical core\nIntel, 2 CPU, 2 logical cores and 1 physical core\nIntel, 2 CPU, 2 physical cores\nIntel, 2 CPU, 2 physical cores\nIntel, 2 CPU, 1 logical core and 2 physical cores\nIntel, 2 CPU, 2 logical and 2 physical cores\n"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Detectors/Cpu/WmicCpuInfoParserTests.cs",
    "content": "﻿using BenchmarkDotNet.Detectors.Cpu.Windows;\nusing Perfolizer.Models;\nusing Xunit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.Tests.Detectors.Cpu;\n\n// ReSharper disable StringLiteralTypo\npublic class WmicCpuInfoParserTests(ITestOutputHelper output)\n{\n    private ITestOutputHelper Output { get; } = output;\n\n    [Fact]\n    public void EmptyTest()\n    {\n        var actual = WmicCpuInfoParser.Parse(string.Empty);\n        var expected = new CpuInfo();\n        Output.AssertEqual(expected, actual);\n    }\n\n    [Fact]\n    public void MalformedTest()\n    {\n        var actual = WmicCpuInfoParser.Parse(\"malformedkey=malformedvalue\\n\\nmalformedkey2=malformedvalue2\");\n        var expected = new CpuInfo();\n        Output.AssertEqual(expected, actual);\n    }\n\n    [Fact]\n    public void RealTwoProcessorEightCoresTest()\n    {\n        const string cpuInfo = @\"\n\nMaxClockSpeed=2400\nName=Intel(R) Xeon(R) CPU E5-2630 v3 @ 2.40GHz\nNumberOfCores=8\nNumberOfLogicalProcessors=16\n\n\nMaxClockSpeed=2400\nName=Intel(R) Xeon(R) CPU E5-2630 v3 @ 2.40GHz\nNumberOfCores=8\nNumberOfLogicalProcessors=16\n\n\";\n        var actual = WmicCpuInfoParser.Parse(cpuInfo);\n        var expected = new CpuInfo\n        {\n            ProcessorName = \"Intel(R) Xeon(R) CPU E5-2630 v3 @ 2.40GHz\",\n            PhysicalProcessorCount = 2,\n            PhysicalCoreCount = 16,\n            LogicalCoreCount = 32,\n            NominalFrequencyHz = 2_400_000_000,\n            MaxFrequencyHz = 2_400_000_000,\n        };\n        Output.AssertEqual(expected, actual);\n    }\n\n    [Fact]\n    public void RealTwoProcessorEightCoresWithWmicBugTest()\n    {\n        const string cpuInfo =\n            \"\\r\\r\\n\" +\n            \"\\r\\r\\n\" +\n            \"MaxClockSpeed=3111\\r\\r\\n\" +\n            \"Name=Intel(R) Xeon(R) CPU E5-2687W 0 @ 3.10GHz\\r\\r\\n\" +\n            \"NumberOfCores=8\\r\\r\\n\" +\n            \"NumberOfLogicalProcessors=16\\r\\r\\n\" +\n            \"\\r\\r\\n\" +\n            \"\\r\\r\\n\" +\n            \"MaxClockSpeed=3111\\r\\r\\n\" +\n            \"Name=Intel(R) Xeon(R) CPU E5-2687W 0 @ 3.10GHz\\r\\r\\n\" +\n            \"NumberOfCores=8\\r\\r\\n\" +\n            \"NumberOfLogicalProcessors=16\\r\\r\\n\" +\n            \"\\r\\r\\n\" +\n            \"\\r\\r\\n\" +\n            \"\\r\\r\\n\";\n        var actual = WmicCpuInfoParser.Parse(cpuInfo);\n        var expected = new CpuInfo\n        {\n            ProcessorName = \"Intel(R) Xeon(R) CPU E5-2687W 0 @ 3.10GHz\",\n            PhysicalProcessorCount = 2,\n            PhysicalCoreCount = 16,\n            LogicalCoreCount = 32,\n            NominalFrequencyHz = 3_111_000_000,\n            MaxFrequencyHz = 3_111_000_000,\n        };\n        Output.AssertEqual(expected, actual);\n    }\n\n    [Fact]\n    public void RealOneProcessorFourCoresTest()\n    {\n        const string cpuInfo = @\"\n\nMaxClockSpeed=2500\nName=Intel(R) Core(TM) i7-4710MQ CPU @ 2.50GHz\nNumberOfCores=4\nNumberOfLogicalProcessors=8\n\n\";\n\n        var actual = WmicCpuInfoParser.Parse(cpuInfo);\n        var expected = new CpuInfo\n        {\n            ProcessorName = \"Intel(R) Core(TM) i7-4710MQ CPU @ 2.50GHz\",\n            PhysicalProcessorCount = 1,\n            PhysicalCoreCount = 4,\n            LogicalCoreCount = 8,\n            NominalFrequencyHz = 2_500_000_000,\n            MaxFrequencyHz = 2_500_000_000,\n        };\n        Output.AssertEqual(expected, actual);\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Disassemblers/GithubMarkdownDisassemblyExporterMultiCorerunTest.cs",
    "content": "using System.Collections.Immutable;\nusing System.Linq;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Diagnosers;\nusing BenchmarkDotNet.Disassemblers;\nusing BenchmarkDotNet.Disassemblers.Exporters;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Tests.Mocks;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests.Disassemblers\n{\n    public class GithubMarkdownDisassemblyExporterMultiCorerunTest\n    {\n        #region ExportToLog Tests\n\n        /// <summary>\n        /// Tests that GithubMarkdownDisassemblyExporter includes Job info in headers.\n        /// </summary>\n        [Fact]\n        public void ExportToLog_IncludesJobInfoInHeader()\n        {\n            // Arrange\n            var logger = new AccumulationLogger();\n            var config = new DisassemblyDiagnoserConfig();\n            var summary = MockFactory.CreateSummary(typeof(MockFactory.MockBenchmarkClass));\n            var results = summary.BenchmarksCases.ToImmutableDictionary(\n                bc => bc,\n                bc => new DisassemblyResult { Methods = [], Errors = [] });\n            var exporter = new GithubMarkdownDisassemblyExporter(results, config);\n\n            // Act\n            exporter.ExportToLog(summary, logger);\n\n            // Assert\n            var output = logger.GetLog();\n            Assert.Contains(\"(Job:\", output);\n        }\n\n        [Fact]\n        public void ExportToLog_FormatsHeaderWithJobDisplayInfo()\n        {\n            // Arrange\n            var logger = new AccumulationLogger();\n            var config = new DisassemblyDiagnoserConfig();\n            var summary = MockFactory.CreateSummary(typeof(MockFactory.MockBenchmarkClass));\n            var results = summary.BenchmarksCases.ToImmutableDictionary(\n                bc => bc,\n                bc => new DisassemblyResult { Methods = [], Errors = [] });\n            var exporter = new GithubMarkdownDisassemblyExporter(results, config);\n\n            // Act\n            exporter.ExportToLog(summary, logger);\n\n            // Assert\n            var output = logger.GetLog();\n            var lines = output.Split('\\n');\n            var headers = lines.Where(line => line.StartsWith(\"##\")).ToArray();\n            Assert.NotEmpty(headers);\n            Assert.All(headers, header => Assert.Contains(\"(Job:\", header));\n        }\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Engine/EngineActualStageTests.cs",
    "content": "﻿using System;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Tests.Mocks;\nusing Perfolizer.Horology;\nusing Xunit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.Tests.Engine\n{\n    public class EngineActualStageTests\n    {\n        private const int MinIterationCount = EngineResolver.DefaultMinWorkloadIterationCount;\n        private const int MaxIterationCount = EngineResolver.DefaultMaxWorkloadIterationCount;\n        private const int MaxOverheadIterationCount = EngineActualStage.MaxOverheadIterationCount;\n\n        private readonly ITestOutputHelper output;\n\n        public EngineActualStageTests(ITestOutputHelper output)\n        {\n            this.output = output;\n        }\n\n        [Fact]\n        public void AutoTest_SteadyState() => AutoTest(data => TimeInterval.Second, MinIterationCount);\n\n        [Fact]\n        public void AutoTest_InfiniteIncrease() => AutoTest(data => TimeInterval.Second * data.index, MaxIterationCount);\n\n        [Fact]\n        public void AutoTest_InfiniteIncreaseOverhead() => AutoTest(data => TimeInterval.Second * data.index, MaxOverheadIterationCount,\n            iterationMode: IterationMode.Overhead);\n\n        private void AutoTest(Func<IterationData, TimeInterval> measure, int min, int max = -1, IterationMode iterationMode = IterationMode.Workload)\n        {\n            if (max == -1)\n                max = min;\n            var job = Job.Default;\n            var engine = new MockEngine(output, job, measure);\n            var stage = iterationMode == IterationMode.Overhead\n                ? EngineActualStage.GetOverhead(1, 1, engine.Parameters)\n                : EngineActualStage.GetWorkload(RunStrategy.Throughput, 1, 1, engine.Parameters);\n            var measurements = engine.Run(stage);\n            int count = measurements.Count;\n            output.WriteLine($\"MeasurementCount = {count} (Min= {min}, Max = {max})\");\n            Assert.InRange(count, min, max);\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Engine/EnginePilotStageTests.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Tests.Mocks;\nusing Perfolizer.Horology;\nusing Xunit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.Tests.Engine\n{\n    public class EnginePilotStageTests\n    {\n        private const long MaxPossibleInvokeCount = EnginePilotStage.MaxInvokeCount;\n        private readonly ITestOutputHelper output;\n\n        public EnginePilotStageTests(ITestOutputHelper output)\n        {\n            this.output = output;\n        }\n\n        [Fact]\n        public void AutoTest_BigResolution() => AutoTest(\n            TimeInterval.Millisecond.ToFrequency(),\n            TimeInterval.Millisecond,\n            0.01,\n            200);\n\n        [Fact]\n        public void AutoTest_ImpossibleResolution() => AutoTest(\n            TimeInterval.Second.ToFrequency(),\n            TimeInterval.Millisecond,\n            0,\n            EnginePilotStage.MaxInvokeCount);\n\n        [Fact]\n        public void SpecificTest_Simple() => SpecificTest(\n            TimeInterval.Millisecond * 100,\n            TimeInterval.Millisecond,\n            64,\n            128);\n\n        private void AutoTest(Frequency clockFrequency, TimeInterval operationTime, double maxRelativeError, long minInvokeCount)\n        {\n            var job = new Job\n            {\n                Infrastructure = { Clock = new MockClock(clockFrequency) },\n                Accuracy = { MaxRelativeError = maxRelativeError }\n            }.Freeze();\n            var engine = new MockEngine(output, job, data => data.invokeCount * operationTime);\n            var pilotStage = EnginePilotStage.GetStage(1, 1, 1, engine.Parameters);\n            engine.Run(pilotStage);\n            var invokeCount = pilotStage.invokeCount;\n            output.WriteLine($\"InvokeCount = {invokeCount} (Min= {minInvokeCount}, Max = {MaxPossibleInvokeCount})\");\n            Assert.InRange(invokeCount, minInvokeCount, MaxPossibleInvokeCount);\n        }\n\n        private void SpecificTest(TimeInterval iterationTime, TimeInterval operationTime, long minInvokeCount, long maxInvokeCount)\n        {\n            var job = new Job\n            {\n                Infrastructure = { Clock = new MockClock(Frequency.MHz) },\n                Run = { IterationTime = iterationTime }\n            }.Freeze();\n            var engine = new MockEngine(output, job, data => data.invokeCount * operationTime);\n            var pilotStage = EnginePilotStage.GetStage(1, 1, 1, engine.Parameters);\n            engine.Run(pilotStage);\n            var invokeCount = pilotStage.invokeCount;\n            output.WriteLine($\"InvokeCount = {invokeCount} (Min= {minInvokeCount}, Max = {maxInvokeCount})\");\n            Assert.InRange(invokeCount, minInvokeCount, maxInvokeCount);\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Engine/EngineResultStageTests.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Linq;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Reports;\nusing JetBrains.Annotations;\nusing Perfolizer.Mathematics.OutlierDetection;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests.Engine\n{\n    public class EngineResultStageTests\n    {\n        [Fact]\n        public void OutliersTest()\n        {\n            var measurements = new List<Measurement>();\n            Add(measurements, 100);\n            Add(measurements, 101);\n            Add(measurements, 102);\n            Add(measurements, 103);\n            Add(measurements, 104);\n            Add(measurements, 500); // It's an outlier\n\n            CheckResults(5, measurements, OutlierMode.RemoveUpper);\n            CheckResults(5, measurements, OutlierMode.RemoveAll);\n\n            CheckResults(6, measurements, OutlierMode.DontRemove);\n            CheckResults(6, measurements, OutlierMode.RemoveLower);\n        }\n\n        [AssertionMethod]\n        private static void CheckResults(int expectedResultCount, List<Measurement> measurements, OutlierMode outlierMode)\n        {\n            Assert.Equal(expectedResultCount, new RunResults(measurements, outlierMode, default).GetWorkloadResultMeasurements().Count());\n        }\n\n        private static void Add(List<Measurement> measurements, int time)\n        {\n            measurements.Add(new Measurement(1, IterationMode.Workload, IterationStage.Actual, measurements.Count + 1, 1, time));\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Engine/EngineWarmupStageTests.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Tests.Mocks;\nusing Perfolizer.Horology;\nusing Xunit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.Tests.Engine\n{\n    public class EngineWarmupStageTests\n    {\n        private const int MinIterationCount = EngineResolver.DefaultMinWarmupIterationCount;\n        private const int MaxIterationCount = EngineResolver.DefaultMaxWarmupIterationCount;\n        private const int MaxOverheadIterationCount = EngineWarmupStage.MaxOverheadIterationCount;\n\n        private readonly ITestOutputHelper output;\n\n        public EngineWarmupStageTests(ITestOutputHelper output)\n        {\n            this.output = output;\n        }\n\n        [Fact]\n        public void AutoTest_SteadyState()\n        {\n            AutoTest(data => TimeInterval.Millisecond, MinIterationCount);\n        }\n\n        [Fact]\n        public void AutoTest_InfiniteIncrease()\n        {\n            AutoTest(data => TimeInterval.Millisecond * data.index, MaxIterationCount);\n        }\n\n        [Fact]\n        public void AutoTest_Alternation()\n        {\n            AutoTest(data => TimeInterval.Millisecond * (data.index % 2), MinIterationCount, MaxIterationCount);\n        }\n\n        [Fact]\n        public void AutoTest_TenSteps()\n        {\n            AutoTest(data => TimeInterval.Millisecond * Math.Max(0, 10 - data.index), 10, MaxIterationCount);\n        }\n\n        [Fact]\n        public void AutoTest_WithoutSteadyStateOverhead()\n        {\n            AutoTest(data => TimeInterval.Millisecond * data.index, MaxOverheadIterationCount, mode: IterationMode.Overhead);\n        }\n\n        [Fact]\n        public void MinAndMaxWarmupCountAttributesCanForceAutoWarmup()\n        {\n            const int explicitWarmupCount = 1;\n\n            var warmupCountEqualOne = DefaultConfig.Instance.AddJob(Job.Default.WithWarmupCount(explicitWarmupCount));\n\n            var benchmarkRunInfo = BenchmarkConverter.TypeToBenchmarks(typeof(WithForceAutoWarmup), warmupCountEqualOne);\n\n            var mergedJob = benchmarkRunInfo.BenchmarksCases.Single().Job;\n\n            Assert.Equal(EngineResolver.ForceAutoWarmup, mergedJob.Run.WarmupCount);\n            Assert.Equal(2, mergedJob.Run.MinWarmupIterationCount);\n            Assert.Equal(4, mergedJob.Run.MaxWarmupIterationCount);\n\n            AutoTest(data => TimeInterval.Millisecond * (data.index % 2), 2, 4, job: mergedJob);\n        }\n\n        [MinWarmupCount(2, forceAutoWarmup: true)]\n        [MaxWarmupCount(4, forceAutoWarmup: true)]\n        public class WithForceAutoWarmup\n        {\n            [Benchmark]\n            public void Method() { }\n        }\n\n        private void AutoTest(Func<IterationData, TimeInterval> measure, int min, int max = -1, IterationMode mode = IterationMode.Workload, Job? job = null)\n        {\n            if (max == -1)\n                max = min;\n            job ??= Job.Default;\n            var engine = new MockEngine(output, job, measure);\n            var stage = mode == IterationMode.Overhead\n                ? EngineWarmupStage.GetOverhead(1, 1, engine.Parameters)\n                : EngineWarmupStage.GetWorkload(RunStrategy.Throughput, 1, 1, engine.Parameters);\n            var measurements = engine.Run(stage);\n            int count = measurements.Count;\n            output.WriteLine($\"MeasurementCount = {count} (Min= {min}, Max = {max})\");\n            Assert.InRange(count, min, max);\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Engine/EnumerateStagesTests.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Reports;\nusing JetBrains.Annotations;\nusing Perfolizer.Horology;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests.Engine\n{\n    public class EnumerateStagesTests\n    {\n        private static TimeSpan IterationTime => TimeSpan.FromMilliseconds(EngineResolver.Instance.Resolve(Job.Default, RunMode.IterationTimeCharacteristic).ToMilliseconds());\n        private static TimeInterval IterationTimeInternal => TimeInterval.FromMilliseconds(IterationTime.Milliseconds);\n\n        private static readonly Dictionary<string, Job> JobsWhichDontRequireJitting = new Dictionary<string, Job>\n        {\n            { \"Dry\", Job.Dry },\n            { \"ColdStart\", Job.Default.WithStrategy(RunStrategy.ColdStart) },\n            { \"Monitoring\", Job.Default.WithStrategy(RunStrategy.Monitoring) }\n        };\n\n        [UsedImplicitly]\n        public static TheoryData<string> JobsWhichDontRequireJittingNames => TheoryDataHelper.Create(JobsWhichDontRequireJitting.Keys);\n\n        [Theory]\n        [MemberData(nameof(JobsWhichDontRequireJittingNames))]\n        public void JobsThatDontRequireJittingSkipJitStage(string jobName)\n        {\n            var job = JobsWhichDontRequireJitting[jobName];\n            var engineParameters = CreateEngineParameters(job);\n\n            bool didRunStages = false;\n            foreach (var stage in EngineStage.EnumerateStages(engineParameters))\n            {\n                Assert.True(stage is not EngineJitStage);\n                didRunStages = true;\n                break;\n            }\n\n            Assert.True(didRunStages);\n        }\n\n        [Fact]\n        public void DefaultSettingsVeryTimeConsumingBenchmarksAreExecutedOncePerIterationWithoutOverheadDeduction()\n        {\n            var engineParameters = CreateEngineParameters(Job.Default);\n\n            bool didRunActualStage = false;\n            foreach (var stage in EngineStage.EnumerateStages(engineParameters))\n            {\n                Assert.NotEqual(IterationMode.Overhead, stage.Mode);\n\n                var stageMeasurements = stage.GetMeasurementList();\n                while (stage.GetShouldRunIteration(stageMeasurements, out var iterationData))\n                {\n                    var measurement = new Measurement(0, iterationData.mode, iterationData.stage, iterationData.index, 1, IterationTimeInternal.Nanoseconds);\n                    stageMeasurements.Add(measurement);\n                }\n\n                if (stage is EngineActualStage { Mode: IterationMode.Workload } actualStage)\n                {\n                    Assert.Equal(1, actualStage.invokeCount);\n                    Assert.Equal(1, actualStage.unrollFactor);\n                    didRunActualStage = true;\n                    break;\n                }\n            }\n\n            Assert.True(didRunActualStage);\n        }\n\n        [Theory]\n        [InlineData(120, 120)] // 120 ms as in the bug report\n        [InlineData(250, 250)] // 250 ms as configured in dotnet/performance repo\n        [InlineData(EngineResolver.DefaultIterationTime, EngineResolver.DefaultIterationTime)] // 500 ms - the default BDN setting\n        [InlineData(EngineResolver.DefaultIterationTime, 20000)] // 20 seconds - twice the cutoff threshold of the old jit stage heuristic #2004\n        public void BenchmarksThatRunLongerThanIterationTimeOnlyDuringFirstInvocationAreInvokedMoreThanOncePerIteration(int iterationTime, int callTime)\n        {\n            var callTimeInterval = TimeInterval.FromMilliseconds(callTime);\n            var engineParameters = CreateEngineParameters(Job.Default.WithIterationTime(TimeInterval.FromMilliseconds(iterationTime)));\n\n            bool didRunActualStage = false;\n            foreach (var stage in EngineStage.EnumerateStages(engineParameters))\n            {\n                var stageMeasurements = stage.GetMeasurementList();\n                while (stage.GetShouldRunIteration(stageMeasurements, out var iterationData))\n                {\n                    var measurement = new Measurement(0, iterationData.mode, iterationData.stage, iterationData.index, 1, callTimeInterval.Nanoseconds);\n                    stageMeasurements.Add(measurement);\n                    callTimeInterval = TimeInterval.FromNanoseconds(1);\n                }\n\n                if (stage is EngineActualStage { Mode: IterationMode.Workload } actualStage)\n                {\n                    Assert.True(actualStage.invokeCount > 1);\n                    didRunActualStage = true;\n                    break;\n                }\n            }\n\n            Assert.True(didRunActualStage);\n        }\n\n        [Fact]\n        public void JobWithExplicitUnrollFactorUnrolls()\n            => AssertUnroll(Job.Default.WithUnrollFactor(16));\n\n        [Fact]\n        public void JobWithExplicitInvocationCountUnrolls()\n            => AssertUnroll(Job.Default.WithInvocationCount(100));\n\n        [Fact]\n        public void DefaultJobUnrolls()\n            => AssertUnroll(Job.Default);\n\n        private void AssertUnroll(Job job)\n        {\n            var engineParameters = CreateEngineParameters(job);\n\n            bool didRunUnroll = false;\n            foreach (var stage in EngineStage.EnumerateStages(engineParameters))\n            {\n                var stageMeasurements = stage.GetMeasurementList();\n                while (stage.GetShouldRunIteration(stageMeasurements, out var iterationData))\n                {\n                    didRunUnroll |= iterationData.unrollFactor > 1;\n                    var measurement = new Measurement(0, iterationData.mode, iterationData.stage, iterationData.index, 1, 1);\n                    stageMeasurements.Add(measurement);\n                }\n            }\n\n            Assert.True(didRunUnroll);\n        }\n\n        [Fact]\n        public void MediumTimeConsumingBenchmarksStartPilotFrom2AndIncrementItWithEveryStep()\n        {\n            const int times = 5; // how many times we should invoke the benchmark per iteration\n\n            var mediumTime = TimeInterval.FromMilliseconds(IterationTime.TotalMilliseconds / times);\n\n            var engineParameters = CreateEngineParameters(Job.Default);\n\n            bool didRunPilotStage = false;\n            foreach (var stage in EngineStage.EnumerateStages(engineParameters))\n            {\n                var stageMeasurements = stage.GetMeasurementList();\n                while (stage.GetShouldRunIteration(stageMeasurements, out var iterationData))\n                {\n                    var measurement = new Measurement(0, iterationData.mode, iterationData.stage, iterationData.index, 1, mediumTime.Nanoseconds);\n                    stageMeasurements.Add(measurement);\n                }\n\n                if (stage is EnginePilotStageInitial pilotStage)\n                {\n                    Assert.Equal(1, pilotStage.unrollFactor);\n                    // We start from two (we know that 1 is not enough, the default is 4 so we need to override it).\n                    Assert.Equal(2, pilotStage.minInvokeCount);\n                    Assert.True(pilotStage.needsFurtherPilot);\n                    Assert.False(pilotStage.evaluateOverhead);\n\n                    didRunPilotStage = true;\n                    break;\n                }\n            }\n\n            Assert.True(didRunPilotStage);\n        }\n\n        private EngineParameters CreateEngineParameters(Job job)\n        {\n            var host = new NoAcknowledgementConsoleHost();\n            return new()\n            {\n                GlobalSetupAction = () => { },\n                GlobalCleanupAction = () => { },\n                Host = host,\n                OverheadActionUnroll = _ => { },\n                OverheadActionNoUnroll = _ => { },\n                IterationCleanupAction = () => { },\n                IterationSetupAction = () => { },\n                WorkloadActionUnroll = _ => { },\n                WorkloadActionNoUnroll = _ => { },\n                TargetJob = job,\n                BenchmarkName = \"\",\n                InProcessDiagnoserHandler = new([], host, Diagnosers.RunMode.None, null!)\n            };\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Environments/HostEnvironmentInfoTests.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Linq;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Portability;\nusing BenchmarkDotNet.Tests.Builders;\nusing JetBrains.Annotations;\nusing Perfolizer.Helpers;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests.Environments\n{\n    public class HostEnvironmentInfoTests\n    {\n        [Theory]\n        [MemberData(nameof(HypervisorNames))]\n        public void ReturnsHypervisorNameWhenItsDetected(string hypervisorName)\n        {\n            var hypervisor = Hypervisors[hypervisorName];\n            var info = new HostEnvironmentInfoBuilder()\n                .WithVMHypervisor(hypervisor)\n                .Build();\n\n            string line = info.ToFormattedString().First();\n\n            string expected = $\"{HostEnvironmentInfo.BenchmarkDotNetCaption} v{info.BenchmarkDotNetVersion}, \" +\n                              $\"{info.Os.Value.ToBrandString()} ({hypervisor.Name})\";\n            Assert.Equal(expected, line);\n        }\n\n        private static readonly IDictionary<string, VirtualMachineHypervisor> Hypervisors = new Dictionary<string, VirtualMachineHypervisor>\n        {\n            { HyperV.Default.Name, HyperV.Default },\n            { VirtualBox.Default.Name, VirtualBox.Default },\n            { VMware.Default.Name, VMware.Default }\n        };\n\n        [UsedImplicitly]\n        public static TheoryData<string> HypervisorNames => TheoryDataHelper.Create(Hypervisors.Keys);\n\n        [Fact]\n        public void DoesntReturnHypervisorNameWhenItsNotDetected()\n        {\n            var info = new HostEnvironmentInfoBuilder()\n                .WithoutVMHypervisor()\n                .Build();\n\n            string line = info.ToFormattedString().First();\n\n            string expected = $\"{HostEnvironmentInfo.BenchmarkDotNetCaption} v{info.BenchmarkDotNetVersion}, \" +\n                              $\"{info.Os.Value.ToBrandString()}\";\n            Assert.Equal(expected, line);\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/EventPipeProfilerTests.cs",
    "content": "﻿using BenchmarkDotNet.Diagnosers;\nusing BenchmarkDotNet.Engines;\nusing Microsoft.Diagnostics.NETCore.Client;\nusing Microsoft.Diagnostics.Tracing.Parsers;\nusing System.Diagnostics.Tracing;\nusing System.Linq;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests\n{\n    public class EventPipeProfilerTests\n    {\n        private static readonly EventPipeProvider SampleProfiler = new EventPipeProvider(\"Microsoft-DotNETCore-SampleProfiler\", EventLevel.Informational);\n        private static readonly EventPipeProvider Mandatory = new EventPipeProvider(EngineEventSource.SourceName, EventLevel.Informational, long.MaxValue);\n\n        [Theory]\n        [InlineData(EventPipeProfile.CpuSampling)]\n        [InlineData(EventPipeProfile.GcCollect)]\n        [InlineData(EventPipeProfile.GcVerbose)]\n        [InlineData(EventPipeProfile.Jit)]\n        public void MandatorySettingsAreAlwaysEnabled(EventPipeProfile eventPipeProfile)\n        {\n            var result = EventPipeProfiler.MapToProviders(eventPipeProfile, null);\n\n            Assert.Contains(Mandatory, result);\n        }\n\n        [Fact]\n        public void UserSettingsOverrideDefaultSettings()\n        {\n            const string DotNetRuntime = \"Microsoft-Windows-DotNETRuntime\";\n\n            var defaultSettings = new EventPipeProvider(\n                DotNetRuntime,\n                EventLevel.Informational,\n                (long)ClrTraceEventParser.Keywords.Default);\n\n            var userSettings = new EventPipeProvider(\n                DotNetRuntime,\n                EventLevel.Verbose,\n                (long) (ClrTraceEventParser.Keywords.Default | ClrTraceEventParser.Keywords.JitTracing));\n\n            var result = EventPipeProfiler.MapToProviders(EventPipeProfile.CpuSampling, [userSettings]);\n\n            var final = result.Single(x => x.Name == userSettings.Name);\n            Assert.Equal(userSettings.EventLevel, final.EventLevel);\n            Assert.Equal(userSettings.Keywords, final.Keywords);\n\n            Assert.Contains(SampleProfiler, result);\n        }\n    }\n}\n"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Exporters/CommonExporterVerifyTests.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Globalization;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing BenchmarkDotNet.Columns;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Diagnosers;\nusing BenchmarkDotNet.Exporters;\nusing BenchmarkDotNet.Exporters.Json;\nusing BenchmarkDotNet.Exporters.OpenMetrics;\nusing BenchmarkDotNet.Exporters.Xml;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Tests.Infra;\nusing BenchmarkDotNet.Tests.Mocks;\nusing BenchmarkDotNet.Tests.Reports;\nusing BenchmarkDotNet.Tests.XUnit;\nusing JetBrains.Annotations;\nusing VerifyXunit;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests.Exporters\n{\n    [Collection(\"VerifyTests\")]\n    public class CommonExporterVerifyTests : IDisposable\n    {\n        private readonly CultureInfo initCulture;\n\n        public CommonExporterVerifyTests()\n        {\n            initCulture = Thread.CurrentThread.CurrentCulture;\n        }\n\n        private static readonly Dictionary<string, CultureInfo> CultureInfos = new Dictionary<string, CultureInfo>\n        {\n            { \"\", CultureInfo.InvariantCulture },\n            { \"ru-RU\", new CultureInfo(\"ru-RU\") },\n            { \"en-US\", new CultureInfo(\"en-US\") }\n        };\n\n        [UsedImplicitly]\n        public static TheoryData<string> CultureInfoNames => TheoryDataHelper.Create(CultureInfos.Keys);\n\n        [TheoryEnvSpecific(\".NET SDK is skipped in Framework, so the exported result does not match the verified file.\", EnvRequirement.DotNetCoreOnly)]\n        [MemberData(nameof(CultureInfoNames))]\n        public Task Exporters(string cultureInfoName)\n        {\n            var cultureInfo = CultureInfos[cultureInfoName];\n            Thread.CurrentThread.CurrentCulture = cultureInfo;\n\n            var logger = new AccumulationLogger();\n\n            var exporters = GetExporters();\n            foreach (var exporter in exporters)\n            {\n                PrintTitle(logger, exporter);\n                exporter.ExportToLog(\n                    MockFactory.CreateSummary(\n                        config.WithCultureInfo(cultureInfo),\n                        hugeSd: false,\n                        [new Metric(new FakeMetricDescriptor(\"CacheMisses\", \"Hardware counter 'CacheMisses' per single operation\", \"N0\"), 7)]),\n                    logger);\n            }\n\n            var settings = VerifyHelper.Create();\n            settings.UseTextForParameters(GetName(cultureInfo));\n            return Verifier.Verify(logger.GetLog(), settings);\n        }\n\n        private static void PrintTitle(AccumulationLogger logger, IExporter exporter)\n        {\n            logger.WriteLine(\"############################################\");\n            logger.WriteLine($\"{exporter.Name}\");\n            logger.WriteLine(\"############################################\");\n        }\n\n        private static string GetName(CultureInfo cultureInfo)\n        {\n            if (cultureInfo.Name == string.Empty)\n                return \"Invariant\";\n            return cultureInfo.Name;\n        }\n\n        private static IEnumerable<IExporter> GetExporters()\n        {\n            //todo add CsvExporter and CsvMeasurementsExporter (need to mock RuntimeInformation)\n            yield return AsciiDocExporter.Default;\n            yield return HtmlExporter.Default;\n            yield return JsonExporter.Brief;\n            yield return JsonExporter.BriefCompressed;\n            yield return JsonExporter.Full;\n            yield return JsonExporter.FullCompressed;\n            yield return MarkdownExporter.Default;\n            yield return MarkdownExporter.Atlassian;\n            yield return MarkdownExporter.Console;\n            yield return MarkdownExporter.GitHub;\n            yield return MarkdownExporter.StackOverflow;\n            yield return OpenMetricsExporter.Default;\n            yield return PlainExporter.Default;\n            yield return XmlExporter.Brief;\n            yield return XmlExporter.BriefCompressed;\n            yield return XmlExporter.Full;\n            yield return XmlExporter.FullCompressed;\n        }\n\n        private static readonly IConfig config = ManualConfig.Create(DefaultConfig.Instance)\n            .AddColumn(StatisticColumn.Mean)\n            .AddColumn(StatisticColumn.StdDev)\n            .AddColumn(StatisticColumn.P67)\n            .AddHardwareCounters(HardwareCounter.CacheMisses)\n            .AddColumnProvider(DefaultColumnProviders.Metrics)\n            .AddDiagnoser(Diagnosers.MemoryDiagnoser.Default);\n\n        public void Dispose()\n        {\n            Thread.CurrentThread.CurrentCulture = initCulture;\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Exporters/MarkdownExporterVerifyTests.cs",
    "content": "﻿using System;\nusing System.Diagnostics.CodeAnalysis;\nusing System.Globalization;\nusing System.Linq;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing BenchmarkDotNet.Exporters;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Tests.Mocks;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Tests.Infra;\nusing BenchmarkDotNet.Validators;\nusing JetBrains.Annotations;\nusing VerifyXunit;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests.Exporters\n{\n    [Collection(\"VerifyTests\")]\n    public class MarkdownExporterVerifyTests : IDisposable\n    {\n        private readonly CultureInfo initCulture = Thread.CurrentThread.CurrentCulture;\n\n        [UsedImplicitly]\n        public static TheoryData<Type> GetGroupBenchmarkTypes()\n        {\n            var data = new TheoryData<Type>();\n            foreach (var type in typeof(BaselinesBenchmarks).GetNestedTypes())\n                data.Add(type);\n            return data;\n        }\n\n        [Theory]\n        [MemberData(nameof(GetGroupBenchmarkTypes))]\n        public Task GroupExporterTest(Type benchmarkType)\n        {\n            Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;\n\n            var logger = new AccumulationLogger();\n            logger.WriteLine(\"=== \" + benchmarkType.Name + \" ===\");\n\n            var exporter = MarkdownExporter.Mock;\n            var summary = MockFactory.CreateSummary(benchmarkType);\n            exporter.ExportToLog(summary, logger);\n\n            var validator = BaselineValidator.FailOnError;\n            var errors = validator.Validate(new ValidationParameters(summary.BenchmarksCases, summary.BenchmarksCases.First().Config)).ToList();\n            logger.WriteLine();\n            logger.WriteLine(\"Errors: \" + errors.Count);\n            foreach (var error in errors)\n                logger.WriteLineError(\"* \" + error.Message);\n\n            var settings = VerifyHelper.Create();\n            settings.UseTextForParameters(benchmarkType.Name);\n            return Verifier.Verify(logger.GetLog(), settings);\n        }\n\n        public void Dispose() => Thread.CurrentThread.CurrentCulture = initCulture;\n\n        [SuppressMessage(\"ReSharper\", \"InconsistentNaming\")]\n        public static class BaselinesBenchmarks\n        {\n            /* NoBaseline */\n\n            [RankColumn, LogicalGroupColumn, BaselineColumn]\n            [SimpleJob(id: \"Job1\"), SimpleJob(id: \"Job2\")]\n            public class NoBaseline_MethodsParamsJobs\n            {\n                [Params(2, 10), UsedImplicitly] public int Param;\n\n                [Benchmark] public void Base() { }\n                [Benchmark] public void Foo() { }\n                [Benchmark] public void Bar() { }\n            }\n\n            [RankColumn, LogicalGroupColumn, BaselineColumn]\n            [SimpleJob(id: \"Job1\"), SimpleJob(id: \"Job2\")]\n            [GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByMethod)]\n            public class NoBaseline_MethodsParamsJobs_GroupByMethod\n            {\n                [Params(2, 10), UsedImplicitly] public int Param;\n\n                [Benchmark, BenchmarkCategory(\"CatA\")] public void Base() { }\n                [Benchmark, BenchmarkCategory(\"CatB\")] public void Foo() { }\n                [Benchmark, BenchmarkCategory(\"CatB\")] public void Bar() { }\n            }\n\n            [RankColumn, LogicalGroupColumn, BaselineColumn]\n            [SimpleJob(id: \"Job1\"), SimpleJob(id: \"Job2\")]\n            [GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByJob)]\n            public class NoBaseline_MethodsParamsJobs_GroupByJob\n            {\n                [Params(2, 10), UsedImplicitly] public int Param;\n\n                [Benchmark, BenchmarkCategory(\"CatA\")] public void Base() { }\n                [Benchmark, BenchmarkCategory(\"CatB\")] public void Foo() { }\n                [Benchmark, BenchmarkCategory(\"CatB\")] public void Bar() { }\n            }\n\n            [RankColumn, LogicalGroupColumn, BaselineColumn]\n            [SimpleJob(id: \"Job1\"), SimpleJob(id: \"Job2\")]\n            [GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByParams)]\n            public class NoBaseline_MethodsParamsJobs_GroupByParams\n            {\n                [Params(2, 10), UsedImplicitly] public int Param;\n\n                [Benchmark, BenchmarkCategory(\"CatA\")] public void Base() { }\n                [Benchmark, BenchmarkCategory(\"CatB\")] public void Foo() { }\n                [Benchmark, BenchmarkCategory(\"CatB\")] public void Bar() { }\n            }\n\n            [RankColumn, LogicalGroupColumn, BaselineColumn]\n            [SimpleJob(id: \"Job1\"), SimpleJob(id: \"Job2\")]\n            [GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByCategory)]\n            public class NoBaseline_MethodsParamsJobs_GroupByCategory\n            {\n                [Params(2, 10), UsedImplicitly] public int Param;\n\n                [Benchmark(Baseline = true), BenchmarkCategory(\"CatA\")]\n                public void A1() { }\n\n                [Benchmark, BenchmarkCategory(\"CatA\")] public void A2() { }\n\n                [Benchmark(Baseline = true), BenchmarkCategory(\"CatB\")]\n                public void B1() { }\n\n                [Benchmark, BenchmarkCategory(\"CatB\")] public void B2() { }\n            }\n\n            [RankColumn, LogicalGroupColumn, BaselineColumn]\n            [SimpleJob(id: \"Job1\"), SimpleJob(id: \"Job2\")]\n            [GroupBenchmarksBy(\n                BenchmarkLogicalGroupRule.ByMethod,\n                BenchmarkLogicalGroupRule.ByJob,\n                BenchmarkLogicalGroupRule.ByParams,\n                BenchmarkLogicalGroupRule.ByCategory)]\n            public class NoBaseline_MethodsParamsJobs_GroupByAll\n            {\n                [Params(2, 10), UsedImplicitly] public int Param;\n\n                [Benchmark(Baseline = true), BenchmarkCategory(\"CatA\")]\n                public void A1() { }\n\n                [Benchmark, BenchmarkCategory(\"CatA\")] public void A2() { }\n\n                [Benchmark(Baseline = true), BenchmarkCategory(\"CatB\")]\n                public void B1() { }\n\n                [Benchmark, BenchmarkCategory(\"CatB\")] public void B2() { }\n            }\n\n            /* MethodBaseline */\n\n            [RankColumn, LogicalGroupColumn, BaselineColumn]\n            public class MethodBaseline_Methods\n            {\n                [Benchmark(Baseline = true)] public void Base() { }\n                [Benchmark] public void Foo() { }\n                [Benchmark] public void Bar() { }\n            }\n\n            [RankColumn, LogicalGroupColumn, BaselineColumn]\n            public class MethodBaseline_MethodsParams\n            {\n                [Params(2, 10), UsedImplicitly] public int Param;\n\n                [Benchmark(Baseline = true)] public void Base() { }\n                [Benchmark] public void Foo() { }\n                [Benchmark] public void Bar() { }\n            }\n\n            [RankColumn, LogicalGroupColumn, BaselineColumn]\n            [SimpleJob(id: \"Job1\"), SimpleJob(id: \"Job2\")]\n            public class MethodBaseline_MethodsJobs\n            {\n                [Benchmark(Baseline = true)] public void Base() { }\n                [Benchmark] public void Foo() { }\n                [Benchmark] public void Bar() { }\n            }\n\n            [RankColumn, LogicalGroupColumn, BaselineColumn]\n            [SimpleJob(id: \"Job1\"), SimpleJob(id: \"Job2\")]\n            public class MethodBaseline_MethodsParamsJobs\n            {\n                [Params(2, 10), UsedImplicitly] public int Param;\n\n                [Benchmark(Baseline = true)] public void Base() { }\n                [Benchmark] public void Foo() { }\n                [Benchmark] public void Bar() { }\n            }\n\n            /* JobBaseline */\n\n            [RankColumn, LogicalGroupColumn, BaselineColumn]\n            [SimpleJob(id: \"Job1\", baseline: true), SimpleJob(id: \"Job2\")]\n            public class JobBaseline_MethodsJobs\n            {\n                [Benchmark] public void Base() { }\n                [Benchmark] public void Foo() { }\n                [Benchmark] public void Bar() { }\n            }\n\n            [RankColumn, LogicalGroupColumn, BaselineColumn]\n            [SimpleJob(id: \"Job1\", baseline: true), SimpleJob(id: \"Job2\")]\n            public class JobBaseline_MethodsParamsJobs\n            {\n                [Params(2, 10), UsedImplicitly] public int Param;\n\n                [Benchmark] public void Base() { }\n                [Benchmark] public void Foo() { }\n                [Benchmark] public void Bar() { }\n            }\n\n            /* MethodJobBaseline */\n\n            [RankColumn, LogicalGroupColumn, BaselineColumn]\n            [SimpleJob(id: \"Job1\", baseline: true), SimpleJob(id: \"Job2\")]\n            public class MethodJobBaseline_MethodsJobs\n            {\n                [Benchmark(Baseline = true)] public void Foo() {}\n                [Benchmark] public void Bar() {}\n            }\n\n            [RankColumn, LogicalGroupColumn, BaselineColumn]\n            [SimpleJob(id: \"Job1\", baseline: true), SimpleJob(id: \"Job2\")]\n            public class MethodJobBaseline_MethodsJobsParams\n            {\n                [Params(2, 10), UsedImplicitly] public int Param;\n\n                [Benchmark(Baseline = true)] public void Foo() {}\n                [Benchmark] public void Bar() {}\n            }\n\n            /* Invalid */\n\n#pragma warning disable BDN1107\n            [RankColumn, LogicalGroupColumn, BaselineColumn]\n            public class Invalid_TwoMethodBaselines\n            {\n                [Benchmark(Baseline = true)] public void Foo() {}\n                [Benchmark(Baseline = true)] public void Bar() {}\n            }\n#pragma warning restore BDN1107\n\n            [RankColumn, LogicalGroupColumn, BaselineColumn]\n            [SimpleJob(id: \"Job1\", baseline: true), SimpleJob(id: \"Job2\", baseline: true)]\n            public class Invalid_TwoJobBaselines\n            {\n                [Benchmark] public void Foo() {}\n                [Benchmark] public void Bar() {}\n            }\n\n            /* Escape Params */\n\n            public class Escape_ParamsAndArguments\n            {\n                [Params(\"\\t\", \"\\n\"), UsedImplicitly] public required string StringParam;\n\n                [Arguments('\\t')] [Arguments('\\n')]\n                [Benchmark] public void Foo(char charArg) {}\n                [Benchmark] public void Bar() {}\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Exporters/OpenMetricsExporterTests.cs",
    "content": "using System.Threading.Tasks;\nusing System;\nusing System.Collections.Generic;\nusing System.Collections.Immutable;\nusing System.Globalization;\nusing BenchmarkDotNet.Columns;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Exporters.OpenMetrics;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Parameters;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Tests.Infra;\nusing BenchmarkDotNet.Tests.Mocks;\nusing BenchmarkDotNet.Tests.Reports;\nusing BenchmarkDotNet.Toolchains.Results;\nusing BenchmarkDotNet.Validators;\nusing VerifyXunit;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests.Exporters\n{\n    [Collection(\"VerifyTests\")]\n    public class OpenMetricsExporterTests\n    {\n        [Fact]\n        public Task SingleBenchmark_ProducesHelpAndTypeOnce()\n        {\n            var summary = new Summary(\n                \"SingleBenchmarkSummary\",\n                [\n                    new BenchmarkReport(\n                        success: true,\n                        benchmarkCase: new BenchmarkCase(\n                            new Descriptor(MockFactory.MockType, MockFactory.MockMethodInfo),\n                            Job.Dry,\n                            new ParameterInstances([\n                                new ParameterInstance(new ParameterDefinition(\"param1\", false, [\"Parameter 1\"], true, typeof(string), 0 ), \"value1\", SummaryStyle.Default),\n                            ]),\n                            ImmutableConfigBuilder.Create(new ManualConfig())),\n                        null!,\n                        null!,\n                        [\n                            new ExecuteResult([\n                                new Measurement(0, IterationMode.Workload, IterationStage.Result, 1, 10, 1)\n                            ])\n                        ],\n                        [\n                            new(new FakeMetricDescriptor(\"label\", \"label\"), 42.0)\n                        ]),\n                    new BenchmarkReport(\n                        success: true,\n                        benchmarkCase: new BenchmarkCase(\n                            new Descriptor(MockFactory.MockType, MockFactory.MockMethodInfo),\n                            Job.Dry,\n                            new ParameterInstances([\n                                new ParameterInstance(new ParameterDefinition(\"param1\", false, [\"Parameter 1\"], true, typeof(string), 0 ), \"value2\", SummaryStyle.Default),\n                            ]),\n                            ImmutableConfigBuilder.Create(new ManualConfig())),\n                        null!,\n                        null!,\n                        [\n                            new ExecuteResult([\n                                new Measurement(0, IterationMode.Workload, IterationStage.Result, 1, 10, 1)\n                            ])\n                        ],\n                        [\n                            new(new FakeMetricDescriptor(\"label\", \"label\"), 42.0)\n                        ]),\n                    new BenchmarkReport(\n                        success: true,\n                        benchmarkCase: new BenchmarkCase(\n                            new Descriptor(MockFactory.MockType, MockFactory.MockMethodInfo),\n                            Job.Dry,\n                            new ParameterInstances([\n                                new ParameterInstance(new ParameterDefinition(\"param1\", false, [\"Parameter 1\"], true, typeof(string), 0 ), \"value3\", SummaryStyle.Default),\n                            ]),\n                            ImmutableConfigBuilder.Create(new ManualConfig())),\n                        null!,\n                        null!,\n                        [\n                            new ExecuteResult([\n                                new Measurement(0, IterationMode.Workload, IterationStage.Result, 1, 10, 1)\n                            ])\n                        ],\n                        [\n                            new(new FakeMetricDescriptor(\"label\", \"label\"), 42.0)\n                        ])\n                ],\n                HostEnvironmentInfo.GetCurrent(),\n                \"\",\n                \"\",\n                TimeSpan.Zero,\n                CultureInfo.InvariantCulture,\n                [],\n                []);\n\n            var logger = new AccumulationLogger();\n\n            OpenMetricsExporter.Default.ExportToLog(summary, logger);\n\n            var settings = VerifyHelper.Create();\n            return Verifier.Verify(logger.GetLog(), settings);\n        }\n\n        [Fact]\n        public Task ParametrizedBenchmarks_LabelExpansion()\n        {\nvar summary = new Summary(\n                \"SingleBenchmarkSummary\",\n                [\n                    new BenchmarkReport(\n                        success: true,\n                        benchmarkCase: new BenchmarkCase(\n                            new Descriptor(MockFactory.MockType, MockFactory.MockMethodInfo),\n                            Job.Dry,\n                            new ParameterInstances([\n                                new ParameterInstance(new ParameterDefinition(\"param1\", false, [\"Parameter 1\"], true, typeof(string), 0 ), \"value1\", SummaryStyle.Default),\n                                new ParameterInstance(new ParameterDefinition(\"param2\", false, [\"Parameter 2\"], true, typeof(string), 0 ), \"value1\", SummaryStyle.Default),\n                                new ParameterInstance(new ParameterDefinition(\"param3\", false, [\"Parameter 3\"], true, typeof(string), 0 ), \"value1\", SummaryStyle.Default)\n                            ]),\n                            ImmutableConfigBuilder.Create(new ManualConfig())),\n                        null!,\n                        null!,\n                        [\n                            new ExecuteResult([\n                                new Measurement(0, IterationMode.Workload, IterationStage.Result, 1, 10, 1)\n                            ])\n                        ],\n                        [\n                            new(new FakeMetricDescriptor(\"label\", \"label\"), 42.0)\n                        ]),\n                    new BenchmarkReport(\n                        success: true,\n                        benchmarkCase: new BenchmarkCase(\n                            new Descriptor(MockFactory.MockType, MockFactory.MockMethodInfo),\n                            Job.Dry,\n                            new ParameterInstances([\n                                new ParameterInstance(new ParameterDefinition(\"param1\", false, [\"Parameter 1\"], true, typeof(string), 0 ), \"value2\", SummaryStyle.Default),\n                                new ParameterInstance(new ParameterDefinition(\"param2\", false, [\"Parameter 2\"], true, typeof(string), 0 ), \"value2\", SummaryStyle.Default),\n                                new ParameterInstance(new ParameterDefinition(\"param3\", false, [\"Parameter 3\"], true, typeof(string), 0 ), \"value2\", SummaryStyle.Default)                            ]),\n                            ImmutableConfigBuilder.Create(new ManualConfig())),\n                        null!,\n                        null!,\n                        [\n                            new ExecuteResult([\n                                new Measurement(0, IterationMode.Workload, IterationStage.Result, 1, 10, 1)\n                            ])\n                        ],\n                        [\n                            new(new FakeMetricDescriptor(\"label\", \"label\"), 42.0)\n                        ]),\n                    new BenchmarkReport(\n                        success: true,\n                        benchmarkCase: new BenchmarkCase(\n                            new Descriptor(MockFactory.MockType, MockFactory.MockMethodInfo),\n                            Job.Dry,\n                            new ParameterInstances([\n                                new ParameterInstance(new ParameterDefinition(\"param1\", false, [\"Parameter 1\"], true, typeof(string), 0 ), \"value3\", SummaryStyle.Default),\n                                new ParameterInstance(new ParameterDefinition(\"param2\", false, [\"Parameter 2\"], true, typeof(string), 0 ), \"value3\", SummaryStyle.Default),\n                                new ParameterInstance(new ParameterDefinition(\"param3\", false, [\"Parameter 3\"], true, typeof(string), 0 ), \"value3\", SummaryStyle.Default)                            ]),\n                            ImmutableConfigBuilder.Create(new ManualConfig())),\n                        null!,\n                        null!,\n                        [\n                            new ExecuteResult([\n                                new Measurement(0, IterationMode.Workload, IterationStage.Result, 1, 10, 1)\n                            ])\n                        ],\n                        [\n                            new(new FakeMetricDescriptor(\"label\", \"label\"), 42.0)\n                        ])\n                ],\n                HostEnvironmentInfo.GetCurrent(),\n                \"\",\n                \"\",\n                TimeSpan.Zero,\n                CultureInfo.InvariantCulture,\n                [],\n                []);\n            var logger = new AccumulationLogger();\n\n            OpenMetricsExporter.Default.ExportToLog(summary, logger);\n\n            var settings = VerifyHelper.Create();\n            return Verifier.Verify(logger.GetLog(), settings);\n        }\n\n        [Fact]\n        public Task LabelsAreEscapedCorrectly()\n        {\n            var summary = new Summary(\n                \"\",\n                [\n                    new BenchmarkReport(\n                        true,\n                        new BenchmarkCase(\n                            new Descriptor(MockFactory.MockType, MockFactory.MockMethodInfo),\n                            Job.Dry,\n                            new ParameterInstances([]),\n                            ImmutableConfigBuilder.Create(new ManualConfig())),\n                        null!,\n                        null!,\n                        [\n                            new ExecuteResult([\n                                new Measurement(0, IterationMode.Workload, IterationStage.Result, 1, 10, 1)\n                            ])\n                        ],\n                        [\n                            new(new FakeMetricDescriptor(\"label_with_underscore\", \"label with underscore\"), 42.0),\n                            new(new FakeMetricDescriptor(\"label_with-dash\", \"label with dash\"), 84.0),\n                            new(new FakeMetricDescriptor(\"label with space\", \"label with space\"), 126.0),\n                            new(new FakeMetricDescriptor(\"label.with.dot\", \"label with dot\"), 168.0),\n                            new(new FakeMetricDescriptor(\"label with special chars !@#$%^&*()\", \"label with special chars !@#$%^&*()\"), 210.0),\n                            new(new FakeMetricDescriptor(\"label with special !@#$%^&*() chars\", \"label with special !@#$%^&*() chars\"), 210.0),\n                            new(new FakeMetricDescriptor(\"label with special !@#$%^&*()chars in the middle\", \"label with special !@#$%^&*()chars in the middle\"), 210.0)\n                        ])\n                ],\n                HostEnvironmentInfo.GetCurrent(),\n                \"\",\n                \"\",\n                TimeSpan.Zero,\n                CultureInfo.InvariantCulture,\n                [],\n                []);\n            var logger = new AccumulationLogger();\n\n            OpenMetricsExporter.Default.ExportToLog(summary, logger);\n\n            var settings = VerifyHelper.Create();\n            return Verifier.Verify(logger.GetLog(), settings);\n        }\n\n        [Fact]\n        public Task DecimalSeparator_UsesInvariantCulture()\n        {\n            var originalCulture = CultureInfo.CurrentCulture;\n            try\n            {\n                CultureInfo.CurrentCulture = new CultureInfo(\"de-DE\"); // Uses comma as decimal separator\n\n                var summary = new Summary(\n                    \"DecimalSeparatorTest\",\n                    [\n                        new BenchmarkReport(\n                            success: true,\n                            benchmarkCase: new BenchmarkCase(\n                                new Descriptor(MockFactory.MockType, MockFactory.MockMethodInfo),\n                                Job.Dry,\n                                new ParameterInstances([]),\n                                ImmutableConfigBuilder.Create(new ManualConfig())),\n                            null!,\n                            null!,\n                            [\n                                new ExecuteResult([\n                                    new Measurement(0, IterationMode.Workload, IterationStage.Result, 1, 1, 10.5)\n                                ])\n                            ],\n                            [])\n                    ],\n                    HostEnvironmentInfo.GetCurrent(),\n                    \"\",\n                    \"\",\n                    TimeSpan.Zero,\n                    CultureInfo.InvariantCulture,\n                    [],\n                    []);\n\n                var logger = new AccumulationLogger();\n\n                OpenMetricsExporter.Default.ExportToLog(summary, logger);\n\n                var log = logger.GetLog();\n                // Verify that the value uses a period, not a comma\n                Assert.Contains(\"10.5\", log);\n                Assert.DoesNotContain(\"10,5\", log);\n            }\n            finally\n            {\n                CultureInfo.CurrentCulture = originalCulture;\n            }\n\n            return Task.CompletedTask;\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Exporters/VerifiedFiles/CommonExporterVerifyTests.Exporters_Invariant.verified.txt",
    "content": "﻿############################################\nAsciiDocExporter\n############################################\n....\nBenchmarkDotNet v0.10.x-mock, Microsoft Windows NT 10.0.x.mock (Hyper-V)\nMockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\nFrequency: 2531248 Hz, Resolution: 395.062 ns, Timer: TSC\n.NET Core SDK 1.0.x.mock\n  [Host] : Clr 4.0.x.mock, 64mock RyuJIT-v4.6.x.mock CONFIGURATION\n\nJob=LongRun  IterationCount=100  LaunchCount=3  \nWarmupCount=15  \n....\n[options=\"header\"]\n|===\n|Method  |Mean      |Error     |StdDev    |P67       |CacheMisses  \n|Foo     |  1.000 ns|  0.000 ns|  0.000 ns|  1.000 ns|            7\n|Bar     |  1.000 ns|  0.000 ns|  0.000 ns|  1.000 ns|            7\n|===\n############################################\nHtmlExporter\n############################################\n<!DOCTYPE html>\n<html lang='en'>\n<head>\n<meta charset='utf-8' />\n<title>MockSummary</title>\n\n<style type=\"text/css\">\n\ttable { border-collapse: collapse; display: block; width: 100%; overflow: auto; }\n\ttd, th { padding: 6px 13px; border: 1px solid #ddd; text-align: right; }\n\ttr { background-color: #fff; border-top: 1px solid #ccc; }\n\ttr:nth-child(even) { background: #f8f8f8; }\n</style>\n</head>\n<body>\n<pre><code>\nBenchmarkDotNet v0.10.x-mock, Microsoft Windows NT 10.0.x.mock (Hyper-V)\nMockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\nFrequency: 2531248 Hz, Resolution: 395.062 ns, Timer: TSC\n.NET Core SDK 1.0.x.mock\n  [Host] : Clr 4.0.x.mock, 64mock RyuJIT-v4.6.x.mock CONFIGURATION\n</code></pre>\n<pre><code>Job=LongRun  IterationCount=100  LaunchCount=3  \nWarmupCount=15  \n</code></pre>\n\n<table>\n<thead><tr><th>Method</th><th>Mean</th><th>Error</th><th>StdDev</th><th>P67</th><th>CacheMisses</th>\n</tr>\n</thead><tbody><tr><td>Foo</td><td>1.000 ns</td><td>0.000 ns</td><td>0.000 ns</td><td>1.000 ns</td><td>7</td>\n</tr><tr><td>Bar</td><td>1.000 ns</td><td>0.000 ns</td><td>0.000 ns</td><td>1.000 ns</td><td>7</td>\n</tr></tbody></table>\n</body>\n</html>\n############################################\nJsonExporter-brief\n############################################\n{\n  \"Title\": \"MockSummary\",\n  \"HostEnvironmentInfo\": {\n    \"BenchmarkDotNetCaption\": \"BenchmarkDotNet\",\n    \"BenchmarkDotNetVersion\": \"0.10.x-mock\",\n    \"OsVersion\": \"Microsoft Windows NT 10.0.x.mock\",\n    \"ProcessorName\": \"MockIntel Core i7-6700HQ CPU 2.60GHz\",\n    \"PhysicalProcessorCount\": 1,\n    \"PhysicalCoreCount\": 4,\n    \"LogicalCoreCount\": 8,\n    \"RuntimeVersion\": \"Clr 4.0.x.mock\",\n    \"Architecture\": \"64mock\",\n    \"HasAttachedDebugger\": false,\n    \"HasRyuJit\": true,\n    \"Configuration\": \"CONFIGURATION\",\n    \"DotNetCliVersion\": \"1.0.x.mock\",\n    \"ChronometerFrequency\": {\n      \"Hertz\": 2531248\n    },\n    \"HardwareTimerKind\": \"Tsc\"\n  },\n  \"Benchmarks\": [\n    {\n      \"DisplayInfo\": \"MockBenchmarkClass.Foo: LongRun(IterationCount=100, LaunchCount=3, WarmupCount=15)\",\n      \"Namespace\": \"BenchmarkDotNet.Tests.Mocks\",\n      \"Type\": \"MockBenchmarkClass\",\n      \"Method\": \"Foo\",\n      \"MethodTitle\": \"Foo\",\n      \"Parameters\": \"\",\n      \"FullName\": \"BenchmarkDotNet.Tests.Mocks.MockFactory+MockBenchmarkClass.Foo\",\n      \"HardwareIntrinsics\": \"\",\n      \"Statistics\": {\n        \"OriginalValues\": [\n          1,\n          1,\n          1,\n          1,\n          1,\n          1\n        ],\n        \"N\": 6,\n        \"Min\": 1,\n        \"LowerFence\": 1,\n        \"Q1\": 1,\n        \"Median\": 1,\n        \"Mean\": 1,\n        \"Q3\": 1,\n        \"UpperFence\": 1,\n        \"Max\": 1,\n        \"InterquartileRange\": 0,\n        \"LowerOutliers\": [],\n        \"UpperOutliers\": [],\n        \"AllOutliers\": [],\n        \"StandardError\": 0,\n        \"Variance\": 0,\n        \"StandardDeviation\": 0,\n        \"Skewness\": \"\",\n        \"Kurtosis\": \"\",\n        \"ConfidenceInterval\": {\n          \"N\": 6,\n          \"Mean\": 1,\n          \"StandardError\": 0,\n          \"Level\": 12,\n          \"Margin\": 0,\n          \"Lower\": 1,\n          \"Upper\": 1\n        },\n        \"Percentiles\": {\n          \"P0\": 1,\n          \"P25\": 1,\n          \"P50\": 1,\n          \"P67\": 1,\n          \"P80\": 1,\n          \"P85\": 1,\n          \"P90\": 1,\n          \"P95\": 1,\n          \"P100\": 1\n        }\n      },\n      \"Memory\": {\n        \"Gen0Collections\": 0,\n        \"Gen1Collections\": 0,\n        \"Gen2Collections\": 0,\n        \"TotalOperations\": 0,\n        \"BytesAllocatedPerOperation\": null\n      }\n    },\n    {\n      \"DisplayInfo\": \"MockBenchmarkClass.Bar: LongRun(IterationCount=100, LaunchCount=3, WarmupCount=15)\",\n      \"Namespace\": \"BenchmarkDotNet.Tests.Mocks\",\n      \"Type\": \"MockBenchmarkClass\",\n      \"Method\": \"Bar\",\n      \"MethodTitle\": \"Bar\",\n      \"Parameters\": \"\",\n      \"FullName\": \"BenchmarkDotNet.Tests.Mocks.MockFactory+MockBenchmarkClass.Bar\",\n      \"HardwareIntrinsics\": \"\",\n      \"Statistics\": {\n        \"OriginalValues\": [\n          1,\n          1,\n          1,\n          1,\n          1,\n          1\n        ],\n        \"N\": 6,\n        \"Min\": 1,\n        \"LowerFence\": 1,\n        \"Q1\": 1,\n        \"Median\": 1,\n        \"Mean\": 1,\n        \"Q3\": 1,\n        \"UpperFence\": 1,\n        \"Max\": 1,\n        \"InterquartileRange\": 0,\n        \"LowerOutliers\": [],\n        \"UpperOutliers\": [],\n        \"AllOutliers\": [],\n        \"StandardError\": 0,\n        \"Variance\": 0,\n        \"StandardDeviation\": 0,\n        \"Skewness\": \"\",\n        \"Kurtosis\": \"\",\n        \"ConfidenceInterval\": {\n          \"N\": 6,\n          \"Mean\": 1,\n          \"StandardError\": 0,\n          \"Level\": 12,\n          \"Margin\": 0,\n          \"Lower\": 1,\n          \"Upper\": 1\n        },\n        \"Percentiles\": {\n          \"P0\": 1,\n          \"P25\": 1,\n          \"P50\": 1,\n          \"P67\": 1,\n          \"P80\": 1,\n          \"P85\": 1,\n          \"P90\": 1,\n          \"P95\": 1,\n          \"P100\": 1\n        }\n      },\n      \"Memory\": {\n        \"Gen0Collections\": 0,\n        \"Gen1Collections\": 0,\n        \"Gen2Collections\": 0,\n        \"TotalOperations\": 0,\n        \"BytesAllocatedPerOperation\": null\n      }\n    }\n  ]\n}\n############################################\nJsonExporter-brief-compressed\n############################################\n{\"Title\":\"MockSummary\",\"HostEnvironmentInfo\":{\"BenchmarkDotNetCaption\":\"BenchmarkDotNet\",\"BenchmarkDotNetVersion\":\"0.10.x-mock\",\"OsVersion\":\"Microsoft Windows NT 10.0.x.mock\",\"ProcessorName\":\"MockIntel Core i7-6700HQ CPU 2.60GHz\",\"PhysicalProcessorCount\":1,\"PhysicalCoreCount\":4,\"LogicalCoreCount\":8,\"RuntimeVersion\":\"Clr 4.0.x.mock\",\"Architecture\":\"64mock\",\"HasAttachedDebugger\":false,\"HasRyuJit\":true,\"Configuration\":\"CONFIGURATION\",\"DotNetCliVersion\":\"1.0.x.mock\",\"ChronometerFrequency\":{\"Hertz\":2531248},\"HardwareTimerKind\":\"Tsc\"},\"Benchmarks\":[{\"DisplayInfo\":\"MockBenchmarkClass.Foo: LongRun(IterationCount=100, LaunchCount=3, WarmupCount=15)\",\"Namespace\":\"BenchmarkDotNet.Tests.Mocks\",\"Type\":\"MockBenchmarkClass\",\"Method\":\"Foo\",\"MethodTitle\":\"Foo\",\"Parameters\":\"\",\"FullName\":\"BenchmarkDotNet.Tests.Mocks.MockFactory+MockBenchmarkClass.Foo\",\"HardwareIntrinsics\":\"\",\"Statistics\":{\"OriginalValues\":[1,1,1,1,1,1],\"N\":6,\"Min\":1,\"LowerFence\":1,\"Q1\":1,\"Median\":1,\"Mean\":1,\"Q3\":1,\"UpperFence\":1,\"Max\":1,\"InterquartileRange\":0,\"LowerOutliers\":[],\"UpperOutliers\":[],\"AllOutliers\":[],\"StandardError\":0,\"Variance\":0,\"StandardDeviation\":0,\"Skewness\":\"\",\"Kurtosis\":\"\",\"ConfidenceInterval\":{\"N\":6,\"Mean\":1,\"StandardError\":0,\"Level\":12,\"Margin\":0,\"Lower\":1,\"Upper\":1},\"Percentiles\":{\"P0\":1,\"P25\":1,\"P50\":1,\"P67\":1,\"P80\":1,\"P85\":1,\"P90\":1,\"P95\":1,\"P100\":1}},\"Memory\":{\"Gen0Collections\":0,\"Gen1Collections\":0,\"Gen2Collections\":0,\"TotalOperations\":0,\"BytesAllocatedPerOperation\":null}},{\"DisplayInfo\":\"MockBenchmarkClass.Bar: LongRun(IterationCount=100, LaunchCount=3, WarmupCount=15)\",\"Namespace\":\"BenchmarkDotNet.Tests.Mocks\",\"Type\":\"MockBenchmarkClass\",\"Method\":\"Bar\",\"MethodTitle\":\"Bar\",\"Parameters\":\"\",\"FullName\":\"BenchmarkDotNet.Tests.Mocks.MockFactory+MockBenchmarkClass.Bar\",\"HardwareIntrinsics\":\"\",\"Statistics\":{\"OriginalValues\":[1,1,1,1,1,1],\"N\":6,\"Min\":1,\"LowerFence\":1,\"Q1\":1,\"Median\":1,\"Mean\":1,\"Q3\":1,\"UpperFence\":1,\"Max\":1,\"InterquartileRange\":0,\"LowerOutliers\":[],\"UpperOutliers\":[],\"AllOutliers\":[],\"StandardError\":0,\"Variance\":0,\"StandardDeviation\":0,\"Skewness\":\"\",\"Kurtosis\":\"\",\"ConfidenceInterval\":{\"N\":6,\"Mean\":1,\"StandardError\":0,\"Level\":12,\"Margin\":0,\"Lower\":1,\"Upper\":1},\"Percentiles\":{\"P0\":1,\"P25\":1,\"P50\":1,\"P67\":1,\"P80\":1,\"P85\":1,\"P90\":1,\"P95\":1,\"P100\":1}},\"Memory\":{\"Gen0Collections\":0,\"Gen1Collections\":0,\"Gen2Collections\":0,\"TotalOperations\":0,\"BytesAllocatedPerOperation\":null}}]}\n############################################\nJsonExporter-full\n############################################\n{\n  \"Title\": \"MockSummary\",\n  \"HostEnvironmentInfo\": {\n    \"BenchmarkDotNetCaption\": \"BenchmarkDotNet\",\n    \"BenchmarkDotNetVersion\": \"0.10.x-mock\",\n    \"OsVersion\": \"Microsoft Windows NT 10.0.x.mock\",\n    \"ProcessorName\": \"MockIntel Core i7-6700HQ CPU 2.60GHz\",\n    \"PhysicalProcessorCount\": 1,\n    \"PhysicalCoreCount\": 4,\n    \"LogicalCoreCount\": 8,\n    \"RuntimeVersion\": \"Clr 4.0.x.mock\",\n    \"Architecture\": \"64mock\",\n    \"HasAttachedDebugger\": false,\n    \"HasRyuJit\": true,\n    \"Configuration\": \"CONFIGURATION\",\n    \"DotNetCliVersion\": \"1.0.x.mock\",\n    \"ChronometerFrequency\": {\n      \"Hertz\": 2531248\n    },\n    \"HardwareTimerKind\": \"Tsc\"\n  },\n  \"Benchmarks\": [\n    {\n      \"DisplayInfo\": \"MockBenchmarkClass.Foo: LongRun(IterationCount=100, LaunchCount=3, WarmupCount=15)\",\n      \"Namespace\": \"BenchmarkDotNet.Tests.Mocks\",\n      \"Type\": \"MockBenchmarkClass\",\n      \"Method\": \"Foo\",\n      \"MethodTitle\": \"Foo\",\n      \"Parameters\": \"\",\n      \"FullName\": \"BenchmarkDotNet.Tests.Mocks.MockFactory+MockBenchmarkClass.Foo\",\n      \"HardwareIntrinsics\": \"\",\n      \"Statistics\": {\n        \"OriginalValues\": [\n          1,\n          1,\n          1,\n          1,\n          1,\n          1\n        ],\n        \"N\": 6,\n        \"Min\": 1,\n        \"LowerFence\": 1,\n        \"Q1\": 1,\n        \"Median\": 1,\n        \"Mean\": 1,\n        \"Q3\": 1,\n        \"UpperFence\": 1,\n        \"Max\": 1,\n        \"InterquartileRange\": 0,\n        \"LowerOutliers\": [],\n        \"UpperOutliers\": [],\n        \"AllOutliers\": [],\n        \"StandardError\": 0,\n        \"Variance\": 0,\n        \"StandardDeviation\": 0,\n        \"Skewness\": \"\",\n        \"Kurtosis\": \"\",\n        \"ConfidenceInterval\": {\n          \"N\": 6,\n          \"Mean\": 1,\n          \"StandardError\": 0,\n          \"Level\": 12,\n          \"Margin\": 0,\n          \"Lower\": 1,\n          \"Upper\": 1\n        },\n        \"Percentiles\": {\n          \"P0\": 1,\n          \"P25\": 1,\n          \"P50\": 1,\n          \"P67\": 1,\n          \"P80\": 1,\n          \"P85\": 1,\n          \"P90\": 1,\n          \"P95\": 1,\n          \"P100\": 1\n        }\n      },\n      \"Memory\": {\n        \"Gen0Collections\": 0,\n        \"Gen1Collections\": 0,\n        \"Gen2Collections\": 0,\n        \"TotalOperations\": 0,\n        \"BytesAllocatedPerOperation\": null\n      },\n      \"Measurements\": [\n        {\n          \"IterationMode\": \"Workload\",\n          \"IterationStage\": \"Result\",\n          \"LaunchIndex\": 1,\n          \"IterationIndex\": 1,\n          \"Operations\": 1,\n          \"Nanoseconds\": 1\n        },\n        {\n          \"IterationMode\": \"Workload\",\n          \"IterationStage\": \"Result\",\n          \"LaunchIndex\": 1,\n          \"IterationIndex\": 2,\n          \"Operations\": 1,\n          \"Nanoseconds\": 1\n        },\n        {\n          \"IterationMode\": \"Workload\",\n          \"IterationStage\": \"Result\",\n          \"LaunchIndex\": 1,\n          \"IterationIndex\": 3,\n          \"Operations\": 1,\n          \"Nanoseconds\": 1\n        },\n        {\n          \"IterationMode\": \"Workload\",\n          \"IterationStage\": \"Result\",\n          \"LaunchIndex\": 1,\n          \"IterationIndex\": 4,\n          \"Operations\": 1,\n          \"Nanoseconds\": 1\n        },\n        {\n          \"IterationMode\": \"Workload\",\n          \"IterationStage\": \"Result\",\n          \"LaunchIndex\": 1,\n          \"IterationIndex\": 5,\n          \"Operations\": 1,\n          \"Nanoseconds\": 1\n        },\n        {\n          \"IterationMode\": \"Workload\",\n          \"IterationStage\": \"Result\",\n          \"LaunchIndex\": 1,\n          \"IterationIndex\": 6,\n          \"Operations\": 1,\n          \"Nanoseconds\": 1\n        }\n      ],\n      \"Metrics\": [\n        {\n          \"Value\": 7,\n          \"Descriptor\": {\n            \"Id\": \"CacheMisses\",\n            \"DisplayName\": \"CacheMisses\",\n            \"Legend\": \"Hardware counter 'CacheMisses' per single operation\",\n            \"NumberFormat\": \"N0\",\n            \"UnitType\": 0,\n            \"Unit\": \"\",\n            \"TheGreaterTheBetter\": false,\n            \"PriorityInCategory\": 0\n          }\n        }\n      ]\n    },\n    {\n      \"DisplayInfo\": \"MockBenchmarkClass.Bar: LongRun(IterationCount=100, LaunchCount=3, WarmupCount=15)\",\n      \"Namespace\": \"BenchmarkDotNet.Tests.Mocks\",\n      \"Type\": \"MockBenchmarkClass\",\n      \"Method\": \"Bar\",\n      \"MethodTitle\": \"Bar\",\n      \"Parameters\": \"\",\n      \"FullName\": \"BenchmarkDotNet.Tests.Mocks.MockFactory+MockBenchmarkClass.Bar\",\n      \"HardwareIntrinsics\": \"\",\n      \"Statistics\": {\n        \"OriginalValues\": [\n          1,\n          1,\n          1,\n          1,\n          1,\n          1\n        ],\n        \"N\": 6,\n        \"Min\": 1,\n        \"LowerFence\": 1,\n        \"Q1\": 1,\n        \"Median\": 1,\n        \"Mean\": 1,\n        \"Q3\": 1,\n        \"UpperFence\": 1,\n        \"Max\": 1,\n        \"InterquartileRange\": 0,\n        \"LowerOutliers\": [],\n        \"UpperOutliers\": [],\n        \"AllOutliers\": [],\n        \"StandardError\": 0,\n        \"Variance\": 0,\n        \"StandardDeviation\": 0,\n        \"Skewness\": \"\",\n        \"Kurtosis\": \"\",\n        \"ConfidenceInterval\": {\n          \"N\": 6,\n          \"Mean\": 1,\n          \"StandardError\": 0,\n          \"Level\": 12,\n          \"Margin\": 0,\n          \"Lower\": 1,\n          \"Upper\": 1\n        },\n        \"Percentiles\": {\n          \"P0\": 1,\n          \"P25\": 1,\n          \"P50\": 1,\n          \"P67\": 1,\n          \"P80\": 1,\n          \"P85\": 1,\n          \"P90\": 1,\n          \"P95\": 1,\n          \"P100\": 1\n        }\n      },\n      \"Memory\": {\n        \"Gen0Collections\": 0,\n        \"Gen1Collections\": 0,\n        \"Gen2Collections\": 0,\n        \"TotalOperations\": 0,\n        \"BytesAllocatedPerOperation\": null\n      },\n      \"Measurements\": [\n        {\n          \"IterationMode\": \"Workload\",\n          \"IterationStage\": \"Result\",\n          \"LaunchIndex\": 1,\n          \"IterationIndex\": 1,\n          \"Operations\": 1,\n          \"Nanoseconds\": 1\n        },\n        {\n          \"IterationMode\": \"Workload\",\n          \"IterationStage\": \"Result\",\n          \"LaunchIndex\": 1,\n          \"IterationIndex\": 2,\n          \"Operations\": 1,\n          \"Nanoseconds\": 1\n        },\n        {\n          \"IterationMode\": \"Workload\",\n          \"IterationStage\": \"Result\",\n          \"LaunchIndex\": 1,\n          \"IterationIndex\": 3,\n          \"Operations\": 1,\n          \"Nanoseconds\": 1\n        },\n        {\n          \"IterationMode\": \"Workload\",\n          \"IterationStage\": \"Result\",\n          \"LaunchIndex\": 1,\n          \"IterationIndex\": 4,\n          \"Operations\": 1,\n          \"Nanoseconds\": 1\n        },\n        {\n          \"IterationMode\": \"Workload\",\n          \"IterationStage\": \"Result\",\n          \"LaunchIndex\": 1,\n          \"IterationIndex\": 5,\n          \"Operations\": 1,\n          \"Nanoseconds\": 1\n        },\n        {\n          \"IterationMode\": \"Workload\",\n          \"IterationStage\": \"Result\",\n          \"LaunchIndex\": 1,\n          \"IterationIndex\": 6,\n          \"Operations\": 1,\n          \"Nanoseconds\": 1\n        }\n      ],\n      \"Metrics\": [\n        {\n          \"Value\": 7,\n          \"Descriptor\": {\n            \"Id\": \"CacheMisses\",\n            \"DisplayName\": \"CacheMisses\",\n            \"Legend\": \"Hardware counter 'CacheMisses' per single operation\",\n            \"NumberFormat\": \"N0\",\n            \"UnitType\": 0,\n            \"Unit\": \"\",\n            \"TheGreaterTheBetter\": false,\n            \"PriorityInCategory\": 0\n          }\n        }\n      ]\n    }\n  ]\n}\n############################################\nJsonExporter-full-compressed\n############################################\n{\"Title\":\"MockSummary\",\"HostEnvironmentInfo\":{\"BenchmarkDotNetCaption\":\"BenchmarkDotNet\",\"BenchmarkDotNetVersion\":\"0.10.x-mock\",\"OsVersion\":\"Microsoft Windows NT 10.0.x.mock\",\"ProcessorName\":\"MockIntel Core i7-6700HQ CPU 2.60GHz\",\"PhysicalProcessorCount\":1,\"PhysicalCoreCount\":4,\"LogicalCoreCount\":8,\"RuntimeVersion\":\"Clr 4.0.x.mock\",\"Architecture\":\"64mock\",\"HasAttachedDebugger\":false,\"HasRyuJit\":true,\"Configuration\":\"CONFIGURATION\",\"DotNetCliVersion\":\"1.0.x.mock\",\"ChronometerFrequency\":{\"Hertz\":2531248},\"HardwareTimerKind\":\"Tsc\"},\"Benchmarks\":[{\"DisplayInfo\":\"MockBenchmarkClass.Foo: LongRun(IterationCount=100, LaunchCount=3, WarmupCount=15)\",\"Namespace\":\"BenchmarkDotNet.Tests.Mocks\",\"Type\":\"MockBenchmarkClass\",\"Method\":\"Foo\",\"MethodTitle\":\"Foo\",\"Parameters\":\"\",\"FullName\":\"BenchmarkDotNet.Tests.Mocks.MockFactory+MockBenchmarkClass.Foo\",\"HardwareIntrinsics\":\"\",\"Statistics\":{\"OriginalValues\":[1,1,1,1,1,1],\"N\":6,\"Min\":1,\"LowerFence\":1,\"Q1\":1,\"Median\":1,\"Mean\":1,\"Q3\":1,\"UpperFence\":1,\"Max\":1,\"InterquartileRange\":0,\"LowerOutliers\":[],\"UpperOutliers\":[],\"AllOutliers\":[],\"StandardError\":0,\"Variance\":0,\"StandardDeviation\":0,\"Skewness\":\"\",\"Kurtosis\":\"\",\"ConfidenceInterval\":{\"N\":6,\"Mean\":1,\"StandardError\":0,\"Level\":12,\"Margin\":0,\"Lower\":1,\"Upper\":1},\"Percentiles\":{\"P0\":1,\"P25\":1,\"P50\":1,\"P67\":1,\"P80\":1,\"P85\":1,\"P90\":1,\"P95\":1,\"P100\":1}},\"Memory\":{\"Gen0Collections\":0,\"Gen1Collections\":0,\"Gen2Collections\":0,\"TotalOperations\":0,\"BytesAllocatedPerOperation\":null},\"Measurements\":[{\"IterationMode\":\"Workload\",\"IterationStage\":\"Result\",\"LaunchIndex\":1,\"IterationIndex\":1,\"Operations\":1,\"Nanoseconds\":1},{\"IterationMode\":\"Workload\",\"IterationStage\":\"Result\",\"LaunchIndex\":1,\"IterationIndex\":2,\"Operations\":1,\"Nanoseconds\":1},{\"IterationMode\":\"Workload\",\"IterationStage\":\"Result\",\"LaunchIndex\":1,\"IterationIndex\":3,\"Operations\":1,\"Nanoseconds\":1},{\"IterationMode\":\"Workload\",\"IterationStage\":\"Result\",\"LaunchIndex\":1,\"IterationIndex\":4,\"Operations\":1,\"Nanoseconds\":1},{\"IterationMode\":\"Workload\",\"IterationStage\":\"Result\",\"LaunchIndex\":1,\"IterationIndex\":5,\"Operations\":1,\"Nanoseconds\":1},{\"IterationMode\":\"Workload\",\"IterationStage\":\"Result\",\"LaunchIndex\":1,\"IterationIndex\":6,\"Operations\":1,\"Nanoseconds\":1}],\"Metrics\":[{\"Value\":7,\"Descriptor\":{\"Id\":\"CacheMisses\",\"DisplayName\":\"CacheMisses\",\"Legend\":\"Hardware counter 'CacheMisses' per single operation\",\"NumberFormat\":\"N0\",\"UnitType\":0,\"Unit\":\"\",\"TheGreaterTheBetter\":false,\"PriorityInCategory\":0}}]},{\"DisplayInfo\":\"MockBenchmarkClass.Bar: LongRun(IterationCount=100, LaunchCount=3, WarmupCount=15)\",\"Namespace\":\"BenchmarkDotNet.Tests.Mocks\",\"Type\":\"MockBenchmarkClass\",\"Method\":\"Bar\",\"MethodTitle\":\"Bar\",\"Parameters\":\"\",\"FullName\":\"BenchmarkDotNet.Tests.Mocks.MockFactory+MockBenchmarkClass.Bar\",\"HardwareIntrinsics\":\"\",\"Statistics\":{\"OriginalValues\":[1,1,1,1,1,1],\"N\":6,\"Min\":1,\"LowerFence\":1,\"Q1\":1,\"Median\":1,\"Mean\":1,\"Q3\":1,\"UpperFence\":1,\"Max\":1,\"InterquartileRange\":0,\"LowerOutliers\":[],\"UpperOutliers\":[],\"AllOutliers\":[],\"StandardError\":0,\"Variance\":0,\"StandardDeviation\":0,\"Skewness\":\"\",\"Kurtosis\":\"\",\"ConfidenceInterval\":{\"N\":6,\"Mean\":1,\"StandardError\":0,\"Level\":12,\"Margin\":0,\"Lower\":1,\"Upper\":1},\"Percentiles\":{\"P0\":1,\"P25\":1,\"P50\":1,\"P67\":1,\"P80\":1,\"P85\":1,\"P90\":1,\"P95\":1,\"P100\":1}},\"Memory\":{\"Gen0Collections\":0,\"Gen1Collections\":0,\"Gen2Collections\":0,\"TotalOperations\":0,\"BytesAllocatedPerOperation\":null},\"Measurements\":[{\"IterationMode\":\"Workload\",\"IterationStage\":\"Result\",\"LaunchIndex\":1,\"IterationIndex\":1,\"Operations\":1,\"Nanoseconds\":1},{\"IterationMode\":\"Workload\",\"IterationStage\":\"Result\",\"LaunchIndex\":1,\"IterationIndex\":2,\"Operations\":1,\"Nanoseconds\":1},{\"IterationMode\":\"Workload\",\"IterationStage\":\"Result\",\"LaunchIndex\":1,\"IterationIndex\":3,\"Operations\":1,\"Nanoseconds\":1},{\"IterationMode\":\"Workload\",\"IterationStage\":\"Result\",\"LaunchIndex\":1,\"IterationIndex\":4,\"Operations\":1,\"Nanoseconds\":1},{\"IterationMode\":\"Workload\",\"IterationStage\":\"Result\",\"LaunchIndex\":1,\"IterationIndex\":5,\"Operations\":1,\"Nanoseconds\":1},{\"IterationMode\":\"Workload\",\"IterationStage\":\"Result\",\"LaunchIndex\":1,\"IterationIndex\":6,\"Operations\":1,\"Nanoseconds\":1}],\"Metrics\":[{\"Value\":7,\"Descriptor\":{\"Id\":\"CacheMisses\",\"DisplayName\":\"CacheMisses\",\"Legend\":\"Hardware counter 'CacheMisses' per single operation\",\"NumberFormat\":\"N0\",\"UnitType\":0,\"Unit\":\"\",\"TheGreaterTheBetter\":false,\"PriorityInCategory\":0}}]}]}\n############################################\nMarkdownExporter-default\n############################################\n\nBenchmarkDotNet v0.10.x-mock, Microsoft Windows NT 10.0.x.mock (Hyper-V)\nMockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\nFrequency: 2531248 Hz, Resolution: 395.062 ns, Timer: TSC\n.NET Core SDK 1.0.x.mock\n  [Host] : Clr 4.0.x.mock, 64mock RyuJIT-v4.6.x.mock CONFIGURATION\n\nJob=LongRun  IterationCount=100  LaunchCount=3  \nWarmupCount=15  \n\n Method | Mean     | Error    | StdDev   | P67      | CacheMisses |\n------- |---------:|---------:|---------:|---------:|------------:|\n Foo    | 1.000 ns | 0.000 ns | 0.000 ns | 1.000 ns |           7 |\n Bar    | 1.000 ns | 0.000 ns | 0.000 ns | 1.000 ns |           7 |\n############################################\nMarkdownExporter-atlassian\n############################################\n{noformat}\n\nBenchmarkDotNet v0.10.x-mock, Microsoft Windows NT 10.0.x.mock (Hyper-V)\nMockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\nFrequency: 2531248 Hz, Resolution: 395.062 ns, Timer: TSC\n.NET Core SDK 1.0.x.mock\n  [Host] : Clr 4.0.x.mock, 64mock RyuJIT-v4.6.x.mock CONFIGURATION\n\nJob=LongRun  IterationCount=100  LaunchCount=3  \nWarmupCount=15  \n\n{noformat}\n||Method ||Mean     ||Error    ||StdDev   ||P67      ||CacheMisses ||\n| Foo    | 1.000 ns | 0.000 ns | 0.000 ns | 1.000 ns |           7 |\n| Bar    | 1.000 ns | 0.000 ns | 0.000 ns | 1.000 ns |           7 |\n############################################\nMarkdownExporter-console\n############################################\n\nBenchmarkDotNet v0.10.x-mock, Microsoft Windows NT 10.0.x.mock (Hyper-V)\nMockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\nFrequency: 2531248 Hz, Resolution: 395.062 ns, Timer: TSC\n.NET Core SDK 1.0.x.mock\n  [Host] : Clr 4.0.x.mock, 64mock RyuJIT-v4.6.x.mock CONFIGURATION\n\nJob=LongRun  IterationCount=100  LaunchCount=3  \nWarmupCount=15  \n\n| Method | Mean     | Error    | StdDev   | P67      | CacheMisses |\n|------- |---------:|---------:|---------:|---------:|------------:|\n| Foo    | 1.000 ns | 0.000 ns | 0.000 ns | 1.000 ns |           7 |\n| Bar    | 1.000 ns | 0.000 ns | 0.000 ns | 1.000 ns |           7 |\n############################################\nMarkdownExporter-github\n############################################\n```\n\nBenchmarkDotNet v0.10.x-mock, Microsoft Windows NT 10.0.x.mock (Hyper-V)\nMockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\nFrequency: 2531248 Hz, Resolution: 395.062 ns, Timer: TSC\n.NET Core SDK 1.0.x.mock\n  [Host] : Clr 4.0.x.mock, 64mock RyuJIT-v4.6.x.mock CONFIGURATION\n\nJob=LongRun  IterationCount=100  LaunchCount=3  \nWarmupCount=15  \n\n```\n| Method | Mean     | Error    | StdDev   | P67      | CacheMisses |\n|------- |---------:|---------:|---------:|---------:|------------:|\n| Foo    | 1.000 ns | 0.000 ns | 0.000 ns | 1.000 ns |           7 |\n| Bar    | 1.000 ns | 0.000 ns | 0.000 ns | 1.000 ns |           7 |\n############################################\nMarkdownExporter-stackoverflow\n############################################\n\n    BenchmarkDotNet v0.10.x-mock, Microsoft Windows NT 10.0.x.mock (Hyper-V)\n    MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n    Frequency: 2531248 Hz, Resolution: 395.062 ns, Timer: TSC\n    .NET Core SDK 1.0.x.mock\n      [Host] : Clr 4.0.x.mock, 64mock RyuJIT-v4.6.x.mock CONFIGURATION\n\n    Job=LongRun  IterationCount=100  LaunchCount=3  \n    WarmupCount=15  \n\n     Method | Mean     | Error    | StdDev   | P67      | CacheMisses |\n    ------- |---------:|---------:|---------:|---------:|------------:|\n     Foo    | 1.000 ns | 0.000 ns | 0.000 ns | 1.000 ns |           7 |\n     Bar    | 1.000 ns | 0.000 ns | 0.000 ns | 1.000 ns |           7 |\n############################################\nOpenMetricsExporter\n############################################\n# HELP benchmark_cachemisses Additional metric CacheMisses\n# TYPE benchmark_cachemisses gauge\nbenchmark_cachemisses{method=\"Foo\", type=\"MockBenchmarkClass\"} 7\nbenchmark_cachemisses{method=\"Bar\", type=\"MockBenchmarkClass\"} 7\n# HELP benchmark_error_nanoseconds Standard error of the mean execution time in nanoseconds.\n# TYPE benchmark_error_nanoseconds gauge\n# UNIT benchmark_error_nanoseconds nanoseconds\nbenchmark_error_nanoseconds{method=\"Foo\", type=\"MockBenchmarkClass\"} 0\nbenchmark_error_nanoseconds{method=\"Bar\", type=\"MockBenchmarkClass\"} 0\n# HELP benchmark_execution_time_nanoseconds Mean execution time in nanoseconds.\n# TYPE benchmark_execution_time_nanoseconds gauge\n# UNIT benchmark_execution_time_nanoseconds nanoseconds\nbenchmark_execution_time_nanoseconds{method=\"Foo\", type=\"MockBenchmarkClass\"} 1\nbenchmark_execution_time_nanoseconds{method=\"Bar\", type=\"MockBenchmarkClass\"} 1\n# HELP benchmark_gc_gen0_collections_total Total number of Gen 0 garbage collections during the benchmark execution.\n# TYPE benchmark_gc_gen0_collections_total counter\nbenchmark_gc_gen0_collections_total{method=\"Foo\", type=\"MockBenchmarkClass\"} 0\nbenchmark_gc_gen0_collections_total{method=\"Bar\", type=\"MockBenchmarkClass\"} 0\n# HELP benchmark_gc_gen1_collections_total Total number of Gen 1 garbage collections during the benchmark execution.\n# TYPE benchmark_gc_gen1_collections_total counter\nbenchmark_gc_gen1_collections_total{method=\"Foo\", type=\"MockBenchmarkClass\"} 0\nbenchmark_gc_gen1_collections_total{method=\"Bar\", type=\"MockBenchmarkClass\"} 0\n# HELP benchmark_gc_gen2_collections_total Total number of Gen 2 garbage collections during the benchmark execution.\n# TYPE benchmark_gc_gen2_collections_total counter\nbenchmark_gc_gen2_collections_total{method=\"Foo\", type=\"MockBenchmarkClass\"} 0\nbenchmark_gc_gen2_collections_total{method=\"Bar\", type=\"MockBenchmarkClass\"} 0\n# HELP benchmark_gc_total_operations_total Total number of garbage collection operations during the benchmark execution.\n# TYPE benchmark_gc_total_operations_total counter\nbenchmark_gc_total_operations_total{method=\"Foo\", type=\"MockBenchmarkClass\"} 0\nbenchmark_gc_total_operations_total{method=\"Bar\", type=\"MockBenchmarkClass\"} 0\n# HELP benchmark_p90_nanoseconds 90th percentile execution time in nanoseconds.\n# TYPE benchmark_p90_nanoseconds gauge\n# UNIT benchmark_p90_nanoseconds nanoseconds\nbenchmark_p90_nanoseconds{method=\"Foo\", type=\"MockBenchmarkClass\"} 1\nbenchmark_p90_nanoseconds{method=\"Bar\", type=\"MockBenchmarkClass\"} 1\n# HELP benchmark_p95_nanoseconds 95th percentile execution time in nanoseconds.\n# TYPE benchmark_p95_nanoseconds gauge\n# UNIT benchmark_p95_nanoseconds nanoseconds\nbenchmark_p95_nanoseconds{method=\"Foo\", type=\"MockBenchmarkClass\"} 1\nbenchmark_p95_nanoseconds{method=\"Bar\", type=\"MockBenchmarkClass\"} 1\n# HELP benchmark_stddev_nanoseconds Standard deviation of execution time in nanoseconds.\n# TYPE benchmark_stddev_nanoseconds gauge\n# UNIT benchmark_stddev_nanoseconds nanoseconds\nbenchmark_stddev_nanoseconds{method=\"Foo\", type=\"MockBenchmarkClass\"} 0\nbenchmark_stddev_nanoseconds{method=\"Bar\", type=\"MockBenchmarkClass\"} 0\n# EOF\n############################################\nPlainExporter\n############################################\n*** MockBenchmarkClass.Foo: LongRun(IterationCount=100, LaunchCount=3, WarmupCount=15) ***\n* Raw *\nWorkloadResult   1: 1 op, 1.00 ns, 1.0000 ns/op\nWorkloadResult   2: 1 op, 1.00 ns, 1.0000 ns/op\nWorkloadResult   3: 1 op, 1.00 ns, 1.0000 ns/op\nWorkloadResult   4: 1 op, 1.00 ns, 1.0000 ns/op\nWorkloadResult   5: 1 op, 1.00 ns, 1.0000 ns/op\nWorkloadResult   6: 1 op, 1.00 ns, 1.0000 ns/op\n\n* Statistics for WorkloadResult\nMean = 1.000 ns, StdErr = 0.000 ns (0.00%), N = 6, StdDev = 0.000 ns\nMin = 1.000 ns, Q1 = 1.000 ns, Median = 1.000 ns, Q3 = 1.000 ns, Max = 1.000 ns\nIQR = 0.000 ns, LowerFence = 1.000 ns, UpperFence = 1.000 ns\nConfidenceInterval = [1.000 ns; 1.000 ns] (CI 99.9%), Margin = 0.000 ns (0.00% of Mean)\nSkewness = NaN, Kurtosis = NaN, MValue = 2\n-------------------- Histogram --------------------\n[0.500 ns ; 1.500 ns) | @@@@@@\n---------------------------------------------------\n*** MockBenchmarkClass.Bar: LongRun(IterationCount=100, LaunchCount=3, WarmupCount=15) ***\n* Raw *\nWorkloadResult   1: 1 op, 1.00 ns, 1.0000 ns/op\nWorkloadResult   2: 1 op, 1.00 ns, 1.0000 ns/op\nWorkloadResult   3: 1 op, 1.00 ns, 1.0000 ns/op\nWorkloadResult   4: 1 op, 1.00 ns, 1.0000 ns/op\nWorkloadResult   5: 1 op, 1.00 ns, 1.0000 ns/op\nWorkloadResult   6: 1 op, 1.00 ns, 1.0000 ns/op\n\n* Statistics for WorkloadResult\nMean = 1.000 ns, StdErr = 0.000 ns (0.00%), N = 6, StdDev = 0.000 ns\nMin = 1.000 ns, Q1 = 1.000 ns, Median = 1.000 ns, Q3 = 1.000 ns, Max = 1.000 ns\nIQR = 0.000 ns, LowerFence = 1.000 ns, UpperFence = 1.000 ns\nConfidenceInterval = [1.000 ns; 1.000 ns] (CI 99.9%), Margin = 0.000 ns (0.00% of Mean)\nSkewness = NaN, Kurtosis = NaN, MValue = 2\n-------------------- Histogram --------------------\n[0.500 ns ; 1.500 ns) | @@@@@@\n---------------------------------------------------\n############################################\nXmlExporter-brief\n############################################\n<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Summary>\n  <Title>MockSummary</Title>\n  <HostEnvironmentInfo>\n    <BenchmarkDotNetCaption>BenchmarkDotNet</BenchmarkDotNetCaption>\n    <BenchmarkDotNetVersion>0.10.x-mock</BenchmarkDotNetVersion>\n    <OsVersion>Microsoft Windows NT 10.0.x.mock</OsVersion>\n    <ProcessorName>MockIntel Core i7-6700HQ CPU 2.60GHz</ProcessorName>\n    <PhysicalProcessorCount>1</PhysicalProcessorCount>\n    <PhysicalCoreCount>4</PhysicalCoreCount>\n    <LogicalCoreCount>8</LogicalCoreCount>\n    <RuntimeVersion>Clr 4.0.x.mock</RuntimeVersion>\n    <Architecture>64mock</Architecture>\n    <HasAttachedDebugger>False</HasAttachedDebugger>\n    <HasRyuJit>True</HasRyuJit>\n    <Configuration>CONFIGURATION</Configuration>\n    <DotNetSdkVersion>1.0.x.mock</DotNetSdkVersion>\n    <ChronometerFrequency>\n      <Hertz>2531248</Hertz>\n    </ChronometerFrequency>\n    <HardwareTimerKind>Tsc</HardwareTimerKind>\n  </HostEnvironmentInfo>\n  <Benchmarks>\n    <BenchmarkCase>\n      <DisplayInfo>MockBenchmarkClass.Foo: LongRun(IterationCount=100, LaunchCount=3, WarmupCount=15)</DisplayInfo>\n      <Namespace>BenchmarkDotNet.Tests.Mocks</Namespace>\n      <Type>MockBenchmarkClass</Type>\n      <Method>Foo</Method>\n      <MethodTitle>Foo</MethodTitle>\n      <Statistics>\n        <OriginalValues>\n          <Item>1</Item>\n          <Item>1</Item>\n          <Item>1</Item>\n          <Item>1</Item>\n          <Item>1</Item>\n          <Item>1</Item>\n        </OriginalValues>\n        <N>6</N>\n        <Min>1</Min>\n        <LowerFence>1</LowerFence>\n        <Q1>1</Q1>\n        <Median>1</Median>\n        <Mean>1</Mean>\n        <Q3>1</Q3>\n        <UpperFence>1</UpperFence>\n        <Max>1</Max>\n        <InterquartileRange>0</InterquartileRange>\n        <StandardError>0</StandardError>\n        <Variance>0</Variance>\n        <StandardDeviation>0</StandardDeviation>\n        <Skewness>NaN</Skewness>\n        <Kurtosis>NaN</Kurtosis>\n        <ConfidenceInterval>\n          <N>6</N>\n          <Mean>1</Mean>\n          <StandardError>0</StandardError>\n          <Level>L999</Level>\n          <Margin>0</Margin>\n          <Lower>1</Lower>\n          <Upper>1</Upper>\n        </ConfidenceInterval>\n        <Percentiles>\n          <P0>1</P0>\n          <P25>1</P25>\n          <P50>1</P50>\n          <P67>1</P67>\n          <P80>1</P80>\n          <P85>1</P85>\n          <P90>1</P90>\n          <P95>1</P95>\n          <P100>1</P100>\n        </Percentiles>\n      </Statistics>\n      <Metrics>\n        <Item>\n          <Value>7</Value>\n          <Descriptor>\n            <Id>CacheMisses</Id>\n            <DisplayName>CacheMisses</DisplayName>\n            <Legend>Hardware counter 'CacheMisses' per single operation</Legend>\n            <NumberFormat>N0</NumberFormat>\n            <UnitType>Dimensionless</UnitType>\n            <TheGreaterTheBetter>False</TheGreaterTheBetter>\n            <PriorityInCategory>0</PriorityInCategory>\n          </Descriptor>\n        </Item>\n      </Metrics>\n      <Memory>\n        <Gen0Collections>0</Gen0Collections>\n        <Gen1Collections>0</Gen1Collections>\n        <Gen2Collections>0</Gen2Collections>\n        <TotalOperations>0</TotalOperations>\n        <BytesAllocatedPerOperation />\n      </Memory>\n    </BenchmarkCase>\n    <BenchmarkCase>\n      <DisplayInfo>MockBenchmarkClass.Bar: LongRun(IterationCount=100, LaunchCount=3, WarmupCount=15)</DisplayInfo>\n      <Namespace>BenchmarkDotNet.Tests.Mocks</Namespace>\n      <Type>MockBenchmarkClass</Type>\n      <Method>Bar</Method>\n      <MethodTitle>Bar</MethodTitle>\n      <Statistics>\n        <OriginalValues>\n          <Item>1</Item>\n          <Item>1</Item>\n          <Item>1</Item>\n          <Item>1</Item>\n          <Item>1</Item>\n          <Item>1</Item>\n        </OriginalValues>\n        <N>6</N>\n        <Min>1</Min>\n        <LowerFence>1</LowerFence>\n        <Q1>1</Q1>\n        <Median>1</Median>\n        <Mean>1</Mean>\n        <Q3>1</Q3>\n        <UpperFence>1</UpperFence>\n        <Max>1</Max>\n        <InterquartileRange>0</InterquartileRange>\n        <StandardError>0</StandardError>\n        <Variance>0</Variance>\n        <StandardDeviation>0</StandardDeviation>\n        <Skewness>NaN</Skewness>\n        <Kurtosis>NaN</Kurtosis>\n        <ConfidenceInterval>\n          <N>6</N>\n          <Mean>1</Mean>\n          <StandardError>0</StandardError>\n          <Level>L999</Level>\n          <Margin>0</Margin>\n          <Lower>1</Lower>\n          <Upper>1</Upper>\n        </ConfidenceInterval>\n        <Percentiles>\n          <P0>1</P0>\n          <P25>1</P25>\n          <P50>1</P50>\n          <P67>1</P67>\n          <P80>1</P80>\n          <P85>1</P85>\n          <P90>1</P90>\n          <P95>1</P95>\n          <P100>1</P100>\n        </Percentiles>\n      </Statistics>\n      <Metrics>\n        <Item>\n          <Value>7</Value>\n          <Descriptor>\n            <Id>CacheMisses</Id>\n            <DisplayName>CacheMisses</DisplayName>\n            <Legend>Hardware counter 'CacheMisses' per single operation</Legend>\n            <NumberFormat>N0</NumberFormat>\n            <UnitType>Dimensionless</UnitType>\n            <TheGreaterTheBetter>False</TheGreaterTheBetter>\n            <PriorityInCategory>0</PriorityInCategory>\n          </Descriptor>\n        </Item>\n      </Metrics>\n      <Memory>\n        <Gen0Collections>0</Gen0Collections>\n        <Gen1Collections>0</Gen1Collections>\n        <Gen2Collections>0</Gen2Collections>\n        <TotalOperations>0</TotalOperations>\n        <BytesAllocatedPerOperation />\n      </Memory>\n    </BenchmarkCase>\n  </Benchmarks>\n</Summary>\n############################################\nXmlExporter-brief-compressed\n############################################\n<?xml version=\"1.0\" encoding=\"utf-8\"?><Summary><Title>MockSummary</Title><HostEnvironmentInfo><BenchmarkDotNetCaption>BenchmarkDotNet</BenchmarkDotNetCaption><BenchmarkDotNetVersion>0.10.x-mock</BenchmarkDotNetVersion><OsVersion>Microsoft Windows NT 10.0.x.mock</OsVersion><ProcessorName>MockIntel Core i7-6700HQ CPU 2.60GHz</ProcessorName><PhysicalProcessorCount>1</PhysicalProcessorCount><PhysicalCoreCount>4</PhysicalCoreCount><LogicalCoreCount>8</LogicalCoreCount><RuntimeVersion>Clr 4.0.x.mock</RuntimeVersion><Architecture>64mock</Architecture><HasAttachedDebugger>False</HasAttachedDebugger><HasRyuJit>True</HasRyuJit><Configuration>CONFIGURATION</Configuration><DotNetSdkVersion>1.0.x.mock</DotNetSdkVersion><ChronometerFrequency><Hertz>2531248</Hertz></ChronometerFrequency><HardwareTimerKind>Tsc</HardwareTimerKind></HostEnvironmentInfo><Benchmarks><BenchmarkCase><DisplayInfo>MockBenchmarkClass.Foo: LongRun(IterationCount=100, LaunchCount=3, WarmupCount=15)</DisplayInfo><Namespace>BenchmarkDotNet.Tests.Mocks</Namespace><Type>MockBenchmarkClass</Type><Method>Foo</Method><MethodTitle>Foo</MethodTitle><Statistics><OriginalValues><Item>1</Item><Item>1</Item><Item>1</Item><Item>1</Item><Item>1</Item><Item>1</Item></OriginalValues><N>6</N><Min>1</Min><LowerFence>1</LowerFence><Q1>1</Q1><Median>1</Median><Mean>1</Mean><Q3>1</Q3><UpperFence>1</UpperFence><Max>1</Max><InterquartileRange>0</InterquartileRange><StandardError>0</StandardError><Variance>0</Variance><StandardDeviation>0</StandardDeviation><Skewness>NaN</Skewness><Kurtosis>NaN</Kurtosis><ConfidenceInterval><N>6</N><Mean>1</Mean><StandardError>0</StandardError><Level>L999</Level><Margin>0</Margin><Lower>1</Lower><Upper>1</Upper></ConfidenceInterval><Percentiles><P0>1</P0><P25>1</P25><P50>1</P50><P67>1</P67><P80>1</P80><P85>1</P85><P90>1</P90><P95>1</P95><P100>1</P100></Percentiles></Statistics><Metrics><Item><Value>7</Value><Descriptor><Id>CacheMisses</Id><DisplayName>CacheMisses</DisplayName><Legend>Hardware counter 'CacheMisses' per single operation</Legend><NumberFormat>N0</NumberFormat><UnitType>Dimensionless</UnitType><TheGreaterTheBetter>False</TheGreaterTheBetter><PriorityInCategory>0</PriorityInCategory></Descriptor></Item></Metrics><Memory><Gen0Collections>0</Gen0Collections><Gen1Collections>0</Gen1Collections><Gen2Collections>0</Gen2Collections><TotalOperations>0</TotalOperations><BytesAllocatedPerOperation /></Memory></BenchmarkCase><BenchmarkCase><DisplayInfo>MockBenchmarkClass.Bar: LongRun(IterationCount=100, LaunchCount=3, WarmupCount=15)</DisplayInfo><Namespace>BenchmarkDotNet.Tests.Mocks</Namespace><Type>MockBenchmarkClass</Type><Method>Bar</Method><MethodTitle>Bar</MethodTitle><Statistics><OriginalValues><Item>1</Item><Item>1</Item><Item>1</Item><Item>1</Item><Item>1</Item><Item>1</Item></OriginalValues><N>6</N><Min>1</Min><LowerFence>1</LowerFence><Q1>1</Q1><Median>1</Median><Mean>1</Mean><Q3>1</Q3><UpperFence>1</UpperFence><Max>1</Max><InterquartileRange>0</InterquartileRange><StandardError>0</StandardError><Variance>0</Variance><StandardDeviation>0</StandardDeviation><Skewness>NaN</Skewness><Kurtosis>NaN</Kurtosis><ConfidenceInterval><N>6</N><Mean>1</Mean><StandardError>0</StandardError><Level>L999</Level><Margin>0</Margin><Lower>1</Lower><Upper>1</Upper></ConfidenceInterval><Percentiles><P0>1</P0><P25>1</P25><P50>1</P50><P67>1</P67><P80>1</P80><P85>1</P85><P90>1</P90><P95>1</P95><P100>1</P100></Percentiles></Statistics><Metrics><Item><Value>7</Value><Descriptor><Id>CacheMisses</Id><DisplayName>CacheMisses</DisplayName><Legend>Hardware counter 'CacheMisses' per single operation</Legend><NumberFormat>N0</NumberFormat><UnitType>Dimensionless</UnitType><TheGreaterTheBetter>False</TheGreaterTheBetter><PriorityInCategory>0</PriorityInCategory></Descriptor></Item></Metrics><Memory><Gen0Collections>0</Gen0Collections><Gen1Collections>0</Gen1Collections><Gen2Collections>0</Gen2Collections><TotalOperations>0</TotalOperations><BytesAllocatedPerOperation /></Memory></BenchmarkCase></Benchmarks></Summary>\n############################################\nXmlExporter-full\n############################################\n<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Summary>\n  <Title>MockSummary</Title>\n  <HostEnvironmentInfo>\n    <BenchmarkDotNetCaption>BenchmarkDotNet</BenchmarkDotNetCaption>\n    <BenchmarkDotNetVersion>0.10.x-mock</BenchmarkDotNetVersion>\n    <OsVersion>Microsoft Windows NT 10.0.x.mock</OsVersion>\n    <ProcessorName>MockIntel Core i7-6700HQ CPU 2.60GHz</ProcessorName>\n    <PhysicalProcessorCount>1</PhysicalProcessorCount>\n    <PhysicalCoreCount>4</PhysicalCoreCount>\n    <LogicalCoreCount>8</LogicalCoreCount>\n    <RuntimeVersion>Clr 4.0.x.mock</RuntimeVersion>\n    <Architecture>64mock</Architecture>\n    <HasAttachedDebugger>False</HasAttachedDebugger>\n    <HasRyuJit>True</HasRyuJit>\n    <Configuration>CONFIGURATION</Configuration>\n    <DotNetSdkVersion>1.0.x.mock</DotNetSdkVersion>\n    <ChronometerFrequency>\n      <Hertz>2531248</Hertz>\n    </ChronometerFrequency>\n    <HardwareTimerKind>Tsc</HardwareTimerKind>\n  </HostEnvironmentInfo>\n  <Benchmarks>\n    <BenchmarkCase>\n      <DisplayInfo>MockBenchmarkClass.Foo: LongRun(IterationCount=100, LaunchCount=3, WarmupCount=15)</DisplayInfo>\n      <Namespace>BenchmarkDotNet.Tests.Mocks</Namespace>\n      <Type>MockBenchmarkClass</Type>\n      <Method>Foo</Method>\n      <MethodTitle>Foo</MethodTitle>\n      <Statistics>\n        <OriginalValues>\n          <Item>1</Item>\n          <Item>1</Item>\n          <Item>1</Item>\n          <Item>1</Item>\n          <Item>1</Item>\n          <Item>1</Item>\n        </OriginalValues>\n        <N>6</N>\n        <Min>1</Min>\n        <LowerFence>1</LowerFence>\n        <Q1>1</Q1>\n        <Median>1</Median>\n        <Mean>1</Mean>\n        <Q3>1</Q3>\n        <UpperFence>1</UpperFence>\n        <Max>1</Max>\n        <InterquartileRange>0</InterquartileRange>\n        <StandardError>0</StandardError>\n        <Variance>0</Variance>\n        <StandardDeviation>0</StandardDeviation>\n        <Skewness>NaN</Skewness>\n        <Kurtosis>NaN</Kurtosis>\n        <ConfidenceInterval>\n          <N>6</N>\n          <Mean>1</Mean>\n          <StandardError>0</StandardError>\n          <Level>L999</Level>\n          <Margin>0</Margin>\n          <Lower>1</Lower>\n          <Upper>1</Upper>\n        </ConfidenceInterval>\n        <Percentiles>\n          <P0>1</P0>\n          <P25>1</P25>\n          <P50>1</P50>\n          <P67>1</P67>\n          <P80>1</P80>\n          <P85>1</P85>\n          <P90>1</P90>\n          <P95>1</P95>\n          <P100>1</P100>\n        </Percentiles>\n      </Statistics>\n      <Metrics>\n        <Item>\n          <Value>7</Value>\n          <Descriptor>\n            <Id>CacheMisses</Id>\n            <DisplayName>CacheMisses</DisplayName>\n            <Legend>Hardware counter 'CacheMisses' per single operation</Legend>\n            <NumberFormat>N0</NumberFormat>\n            <UnitType>Dimensionless</UnitType>\n            <TheGreaterTheBetter>False</TheGreaterTheBetter>\n            <PriorityInCategory>0</PriorityInCategory>\n          </Descriptor>\n        </Item>\n      </Metrics>\n      <Memory>\n        <Gen0Collections>0</Gen0Collections>\n        <Gen1Collections>0</Gen1Collections>\n        <Gen2Collections>0</Gen2Collections>\n        <TotalOperations>0</TotalOperations>\n        <BytesAllocatedPerOperation />\n      </Memory>\n      <Measurements>\n        <Measurement>\n          <IterationMode>Workload</IterationMode>\n          <IterationStage>Result</IterationStage>\n          <LaunchIndex>1</LaunchIndex>\n          <IterationIndex>1</IterationIndex>\n          <Operations>1</Operations>\n          <Nanoseconds>1</Nanoseconds>\n        </Measurement>\n        <Measurement>\n          <IterationMode>Workload</IterationMode>\n          <IterationStage>Result</IterationStage>\n          <LaunchIndex>1</LaunchIndex>\n          <IterationIndex>2</IterationIndex>\n          <Operations>1</Operations>\n          <Nanoseconds>1</Nanoseconds>\n        </Measurement>\n        <Measurement>\n          <IterationMode>Workload</IterationMode>\n          <IterationStage>Result</IterationStage>\n          <LaunchIndex>1</LaunchIndex>\n          <IterationIndex>3</IterationIndex>\n          <Operations>1</Operations>\n          <Nanoseconds>1</Nanoseconds>\n        </Measurement>\n        <Measurement>\n          <IterationMode>Workload</IterationMode>\n          <IterationStage>Result</IterationStage>\n          <LaunchIndex>1</LaunchIndex>\n          <IterationIndex>4</IterationIndex>\n          <Operations>1</Operations>\n          <Nanoseconds>1</Nanoseconds>\n        </Measurement>\n        <Measurement>\n          <IterationMode>Workload</IterationMode>\n          <IterationStage>Result</IterationStage>\n          <LaunchIndex>1</LaunchIndex>\n          <IterationIndex>5</IterationIndex>\n          <Operations>1</Operations>\n          <Nanoseconds>1</Nanoseconds>\n        </Measurement>\n        <Measurement>\n          <IterationMode>Workload</IterationMode>\n          <IterationStage>Result</IterationStage>\n          <LaunchIndex>1</LaunchIndex>\n          <IterationIndex>6</IterationIndex>\n          <Operations>1</Operations>\n          <Nanoseconds>1</Nanoseconds>\n        </Measurement>\n      </Measurements>\n    </BenchmarkCase>\n    <BenchmarkCase>\n      <DisplayInfo>MockBenchmarkClass.Bar: LongRun(IterationCount=100, LaunchCount=3, WarmupCount=15)</DisplayInfo>\n      <Namespace>BenchmarkDotNet.Tests.Mocks</Namespace>\n      <Type>MockBenchmarkClass</Type>\n      <Method>Bar</Method>\n      <MethodTitle>Bar</MethodTitle>\n      <Statistics>\n        <OriginalValues>\n          <Item>1</Item>\n          <Item>1</Item>\n          <Item>1</Item>\n          <Item>1</Item>\n          <Item>1</Item>\n          <Item>1</Item>\n        </OriginalValues>\n        <N>6</N>\n        <Min>1</Min>\n        <LowerFence>1</LowerFence>\n        <Q1>1</Q1>\n        <Median>1</Median>\n        <Mean>1</Mean>\n        <Q3>1</Q3>\n        <UpperFence>1</UpperFence>\n        <Max>1</Max>\n        <InterquartileRange>0</InterquartileRange>\n        <StandardError>0</StandardError>\n        <Variance>0</Variance>\n        <StandardDeviation>0</StandardDeviation>\n        <Skewness>NaN</Skewness>\n        <Kurtosis>NaN</Kurtosis>\n        <ConfidenceInterval>\n          <N>6</N>\n          <Mean>1</Mean>\n          <StandardError>0</StandardError>\n          <Level>L999</Level>\n          <Margin>0</Margin>\n          <Lower>1</Lower>\n          <Upper>1</Upper>\n        </ConfidenceInterval>\n        <Percentiles>\n          <P0>1</P0>\n          <P25>1</P25>\n          <P50>1</P50>\n          <P67>1</P67>\n          <P80>1</P80>\n          <P85>1</P85>\n          <P90>1</P90>\n          <P95>1</P95>\n          <P100>1</P100>\n        </Percentiles>\n      </Statistics>\n      <Metrics>\n        <Item>\n          <Value>7</Value>\n          <Descriptor>\n            <Id>CacheMisses</Id>\n            <DisplayName>CacheMisses</DisplayName>\n            <Legend>Hardware counter 'CacheMisses' per single operation</Legend>\n            <NumberFormat>N0</NumberFormat>\n            <UnitType>Dimensionless</UnitType>\n            <TheGreaterTheBetter>False</TheGreaterTheBetter>\n            <PriorityInCategory>0</PriorityInCategory>\n          </Descriptor>\n        </Item>\n      </Metrics>\n      <Memory>\n        <Gen0Collections>0</Gen0Collections>\n        <Gen1Collections>0</Gen1Collections>\n        <Gen2Collections>0</Gen2Collections>\n        <TotalOperations>0</TotalOperations>\n        <BytesAllocatedPerOperation />\n      </Memory>\n      <Measurements>\n        <Measurement>\n          <IterationMode>Workload</IterationMode>\n          <IterationStage>Result</IterationStage>\n          <LaunchIndex>1</LaunchIndex>\n          <IterationIndex>1</IterationIndex>\n          <Operations>1</Operations>\n          <Nanoseconds>1</Nanoseconds>\n        </Measurement>\n        <Measurement>\n          <IterationMode>Workload</IterationMode>\n          <IterationStage>Result</IterationStage>\n          <LaunchIndex>1</LaunchIndex>\n          <IterationIndex>2</IterationIndex>\n          <Operations>1</Operations>\n          <Nanoseconds>1</Nanoseconds>\n        </Measurement>\n        <Measurement>\n          <IterationMode>Workload</IterationMode>\n          <IterationStage>Result</IterationStage>\n          <LaunchIndex>1</LaunchIndex>\n          <IterationIndex>3</IterationIndex>\n          <Operations>1</Operations>\n          <Nanoseconds>1</Nanoseconds>\n        </Measurement>\n        <Measurement>\n          <IterationMode>Workload</IterationMode>\n          <IterationStage>Result</IterationStage>\n          <LaunchIndex>1</LaunchIndex>\n          <IterationIndex>4</IterationIndex>\n          <Operations>1</Operations>\n          <Nanoseconds>1</Nanoseconds>\n        </Measurement>\n        <Measurement>\n          <IterationMode>Workload</IterationMode>\n          <IterationStage>Result</IterationStage>\n          <LaunchIndex>1</LaunchIndex>\n          <IterationIndex>5</IterationIndex>\n          <Operations>1</Operations>\n          <Nanoseconds>1</Nanoseconds>\n        </Measurement>\n        <Measurement>\n          <IterationMode>Workload</IterationMode>\n          <IterationStage>Result</IterationStage>\n          <LaunchIndex>1</LaunchIndex>\n          <IterationIndex>6</IterationIndex>\n          <Operations>1</Operations>\n          <Nanoseconds>1</Nanoseconds>\n        </Measurement>\n      </Measurements>\n    </BenchmarkCase>\n  </Benchmarks>\n</Summary>\n############################################\nXmlExporter-full-compressed\n############################################\n<?xml version=\"1.0\" encoding=\"utf-8\"?><Summary><Title>MockSummary</Title><HostEnvironmentInfo><BenchmarkDotNetCaption>BenchmarkDotNet</BenchmarkDotNetCaption><BenchmarkDotNetVersion>0.10.x-mock</BenchmarkDotNetVersion><OsVersion>Microsoft Windows NT 10.0.x.mock</OsVersion><ProcessorName>MockIntel Core i7-6700HQ CPU 2.60GHz</ProcessorName><PhysicalProcessorCount>1</PhysicalProcessorCount><PhysicalCoreCount>4</PhysicalCoreCount><LogicalCoreCount>8</LogicalCoreCount><RuntimeVersion>Clr 4.0.x.mock</RuntimeVersion><Architecture>64mock</Architecture><HasAttachedDebugger>False</HasAttachedDebugger><HasRyuJit>True</HasRyuJit><Configuration>CONFIGURATION</Configuration><DotNetSdkVersion>1.0.x.mock</DotNetSdkVersion><ChronometerFrequency><Hertz>2531248</Hertz></ChronometerFrequency><HardwareTimerKind>Tsc</HardwareTimerKind></HostEnvironmentInfo><Benchmarks><BenchmarkCase><DisplayInfo>MockBenchmarkClass.Foo: LongRun(IterationCount=100, LaunchCount=3, WarmupCount=15)</DisplayInfo><Namespace>BenchmarkDotNet.Tests.Mocks</Namespace><Type>MockBenchmarkClass</Type><Method>Foo</Method><MethodTitle>Foo</MethodTitle><Statistics><OriginalValues><Item>1</Item><Item>1</Item><Item>1</Item><Item>1</Item><Item>1</Item><Item>1</Item></OriginalValues><N>6</N><Min>1</Min><LowerFence>1</LowerFence><Q1>1</Q1><Median>1</Median><Mean>1</Mean><Q3>1</Q3><UpperFence>1</UpperFence><Max>1</Max><InterquartileRange>0</InterquartileRange><StandardError>0</StandardError><Variance>0</Variance><StandardDeviation>0</StandardDeviation><Skewness>NaN</Skewness><Kurtosis>NaN</Kurtosis><ConfidenceInterval><N>6</N><Mean>1</Mean><StandardError>0</StandardError><Level>L999</Level><Margin>0</Margin><Lower>1</Lower><Upper>1</Upper></ConfidenceInterval><Percentiles><P0>1</P0><P25>1</P25><P50>1</P50><P67>1</P67><P80>1</P80><P85>1</P85><P90>1</P90><P95>1</P95><P100>1</P100></Percentiles></Statistics><Metrics><Item><Value>7</Value><Descriptor><Id>CacheMisses</Id><DisplayName>CacheMisses</DisplayName><Legend>Hardware counter 'CacheMisses' per single operation</Legend><NumberFormat>N0</NumberFormat><UnitType>Dimensionless</UnitType><TheGreaterTheBetter>False</TheGreaterTheBetter><PriorityInCategory>0</PriorityInCategory></Descriptor></Item></Metrics><Memory><Gen0Collections>0</Gen0Collections><Gen1Collections>0</Gen1Collections><Gen2Collections>0</Gen2Collections><TotalOperations>0</TotalOperations><BytesAllocatedPerOperation /></Memory><Measurements><Measurement><IterationMode>Workload</IterationMode><IterationStage>Result</IterationStage><LaunchIndex>1</LaunchIndex><IterationIndex>1</IterationIndex><Operations>1</Operations><Nanoseconds>1</Nanoseconds></Measurement><Measurement><IterationMode>Workload</IterationMode><IterationStage>Result</IterationStage><LaunchIndex>1</LaunchIndex><IterationIndex>2</IterationIndex><Operations>1</Operations><Nanoseconds>1</Nanoseconds></Measurement><Measurement><IterationMode>Workload</IterationMode><IterationStage>Result</IterationStage><LaunchIndex>1</LaunchIndex><IterationIndex>3</IterationIndex><Operations>1</Operations><Nanoseconds>1</Nanoseconds></Measurement><Measurement><IterationMode>Workload</IterationMode><IterationStage>Result</IterationStage><LaunchIndex>1</LaunchIndex><IterationIndex>4</IterationIndex><Operations>1</Operations><Nanoseconds>1</Nanoseconds></Measurement><Measurement><IterationMode>Workload</IterationMode><IterationStage>Result</IterationStage><LaunchIndex>1</LaunchIndex><IterationIndex>5</IterationIndex><Operations>1</Operations><Nanoseconds>1</Nanoseconds></Measurement><Measurement><IterationMode>Workload</IterationMode><IterationStage>Result</IterationStage><LaunchIndex>1</LaunchIndex><IterationIndex>6</IterationIndex><Operations>1</Operations><Nanoseconds>1</Nanoseconds></Measurement></Measurements></BenchmarkCase><BenchmarkCase><DisplayInfo>MockBenchmarkClass.Bar: LongRun(IterationCount=100, LaunchCount=3, WarmupCount=15)</DisplayInfo><Namespace>BenchmarkDotNet.Tests.Mocks</Namespace><Type>MockBenchmarkClass</Type><Method>Bar</Method><MethodTitle>Bar</MethodTitle><Statistics><OriginalValues><Item>1</Item><Item>1</Item><Item>1</Item><Item>1</Item><Item>1</Item><Item>1</Item></OriginalValues><N>6</N><Min>1</Min><LowerFence>1</LowerFence><Q1>1</Q1><Median>1</Median><Mean>1</Mean><Q3>1</Q3><UpperFence>1</UpperFence><Max>1</Max><InterquartileRange>0</InterquartileRange><StandardError>0</StandardError><Variance>0</Variance><StandardDeviation>0</StandardDeviation><Skewness>NaN</Skewness><Kurtosis>NaN</Kurtosis><ConfidenceInterval><N>6</N><Mean>1</Mean><StandardError>0</StandardError><Level>L999</Level><Margin>0</Margin><Lower>1</Lower><Upper>1</Upper></ConfidenceInterval><Percentiles><P0>1</P0><P25>1</P25><P50>1</P50><P67>1</P67><P80>1</P80><P85>1</P85><P90>1</P90><P95>1</P95><P100>1</P100></Percentiles></Statistics><Metrics><Item><Value>7</Value><Descriptor><Id>CacheMisses</Id><DisplayName>CacheMisses</DisplayName><Legend>Hardware counter 'CacheMisses' per single operation</Legend><NumberFormat>N0</NumberFormat><UnitType>Dimensionless</UnitType><TheGreaterTheBetter>False</TheGreaterTheBetter><PriorityInCategory>0</PriorityInCategory></Descriptor></Item></Metrics><Memory><Gen0Collections>0</Gen0Collections><Gen1Collections>0</Gen1Collections><Gen2Collections>0</Gen2Collections><TotalOperations>0</TotalOperations><BytesAllocatedPerOperation /></Memory><Measurements><Measurement><IterationMode>Workload</IterationMode><IterationStage>Result</IterationStage><LaunchIndex>1</LaunchIndex><IterationIndex>1</IterationIndex><Operations>1</Operations><Nanoseconds>1</Nanoseconds></Measurement><Measurement><IterationMode>Workload</IterationMode><IterationStage>Result</IterationStage><LaunchIndex>1</LaunchIndex><IterationIndex>2</IterationIndex><Operations>1</Operations><Nanoseconds>1</Nanoseconds></Measurement><Measurement><IterationMode>Workload</IterationMode><IterationStage>Result</IterationStage><LaunchIndex>1</LaunchIndex><IterationIndex>3</IterationIndex><Operations>1</Operations><Nanoseconds>1</Nanoseconds></Measurement><Measurement><IterationMode>Workload</IterationMode><IterationStage>Result</IterationStage><LaunchIndex>1</LaunchIndex><IterationIndex>4</IterationIndex><Operations>1</Operations><Nanoseconds>1</Nanoseconds></Measurement><Measurement><IterationMode>Workload</IterationMode><IterationStage>Result</IterationStage><LaunchIndex>1</LaunchIndex><IterationIndex>5</IterationIndex><Operations>1</Operations><Nanoseconds>1</Nanoseconds></Measurement><Measurement><IterationMode>Workload</IterationMode><IterationStage>Result</IterationStage><LaunchIndex>1</LaunchIndex><IterationIndex>6</IterationIndex><Operations>1</Operations><Nanoseconds>1</Nanoseconds></Measurement></Measurements></BenchmarkCase></Benchmarks></Summary>\n"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Exporters/VerifiedFiles/CommonExporterVerifyTests.Exporters_en-US.verified.txt",
    "content": "﻿############################################\nAsciiDocExporter\n############################################\n....\nBenchmarkDotNet v0.10.x-mock, Microsoft Windows NT 10.0.x.mock (Hyper-V)\nMockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\nFrequency: 2531248 Hz, Resolution: 395.062 ns, Timer: TSC\n.NET Core SDK 1.0.x.mock\n  [Host] : Clr 4.0.x.mock, 64mock RyuJIT-v4.6.x.mock CONFIGURATION\n\nJob=LongRun  IterationCount=100  LaunchCount=3  \nWarmupCount=15  \n....\n[options=\"header\"]\n|===\n|Method  |Mean      |Error     |StdDev    |P67       |CacheMisses  \n|Foo     |  1.000 ns|  0.000 ns|  0.000 ns|  1.000 ns|            7\n|Bar     |  1.000 ns|  0.000 ns|  0.000 ns|  1.000 ns|            7\n|===\n############################################\nHtmlExporter\n############################################\n<!DOCTYPE html>\n<html lang='en'>\n<head>\n<meta charset='utf-8' />\n<title>MockSummary</title>\n\n<style type=\"text/css\">\n\ttable { border-collapse: collapse; display: block; width: 100%; overflow: auto; }\n\ttd, th { padding: 6px 13px; border: 1px solid #ddd; text-align: right; }\n\ttr { background-color: #fff; border-top: 1px solid #ccc; }\n\ttr:nth-child(even) { background: #f8f8f8; }\n</style>\n</head>\n<body>\n<pre><code>\nBenchmarkDotNet v0.10.x-mock, Microsoft Windows NT 10.0.x.mock (Hyper-V)\nMockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\nFrequency: 2531248 Hz, Resolution: 395.062 ns, Timer: TSC\n.NET Core SDK 1.0.x.mock\n  [Host] : Clr 4.0.x.mock, 64mock RyuJIT-v4.6.x.mock CONFIGURATION\n</code></pre>\n<pre><code>Job=LongRun  IterationCount=100  LaunchCount=3  \nWarmupCount=15  \n</code></pre>\n\n<table>\n<thead><tr><th>Method</th><th>Mean</th><th>Error</th><th>StdDev</th><th>P67</th><th>CacheMisses</th>\n</tr>\n</thead><tbody><tr><td>Foo</td><td>1.000 ns</td><td>0.000 ns</td><td>0.000 ns</td><td>1.000 ns</td><td>7</td>\n</tr><tr><td>Bar</td><td>1.000 ns</td><td>0.000 ns</td><td>0.000 ns</td><td>1.000 ns</td><td>7</td>\n</tr></tbody></table>\n</body>\n</html>\n############################################\nJsonExporter-brief\n############################################\n{\n  \"Title\": \"MockSummary\",\n  \"HostEnvironmentInfo\": {\n    \"BenchmarkDotNetCaption\": \"BenchmarkDotNet\",\n    \"BenchmarkDotNetVersion\": \"0.10.x-mock\",\n    \"OsVersion\": \"Microsoft Windows NT 10.0.x.mock\",\n    \"ProcessorName\": \"MockIntel Core i7-6700HQ CPU 2.60GHz\",\n    \"PhysicalProcessorCount\": 1,\n    \"PhysicalCoreCount\": 4,\n    \"LogicalCoreCount\": 8,\n    \"RuntimeVersion\": \"Clr 4.0.x.mock\",\n    \"Architecture\": \"64mock\",\n    \"HasAttachedDebugger\": false,\n    \"HasRyuJit\": true,\n    \"Configuration\": \"CONFIGURATION\",\n    \"DotNetCliVersion\": \"1.0.x.mock\",\n    \"ChronometerFrequency\": {\n      \"Hertz\": 2531248\n    },\n    \"HardwareTimerKind\": \"Tsc\"\n  },\n  \"Benchmarks\": [\n    {\n      \"DisplayInfo\": \"MockBenchmarkClass.Foo: LongRun(IterationCount=100, LaunchCount=3, WarmupCount=15)\",\n      \"Namespace\": \"BenchmarkDotNet.Tests.Mocks\",\n      \"Type\": \"MockBenchmarkClass\",\n      \"Method\": \"Foo\",\n      \"MethodTitle\": \"Foo\",\n      \"Parameters\": \"\",\n      \"FullName\": \"BenchmarkDotNet.Tests.Mocks.MockFactory+MockBenchmarkClass.Foo\",\n      \"HardwareIntrinsics\": \"\",\n      \"Statistics\": {\n        \"OriginalValues\": [\n          1,\n          1,\n          1,\n          1,\n          1,\n          1\n        ],\n        \"N\": 6,\n        \"Min\": 1,\n        \"LowerFence\": 1,\n        \"Q1\": 1,\n        \"Median\": 1,\n        \"Mean\": 1,\n        \"Q3\": 1,\n        \"UpperFence\": 1,\n        \"Max\": 1,\n        \"InterquartileRange\": 0,\n        \"LowerOutliers\": [],\n        \"UpperOutliers\": [],\n        \"AllOutliers\": [],\n        \"StandardError\": 0,\n        \"Variance\": 0,\n        \"StandardDeviation\": 0,\n        \"Skewness\": \"\",\n        \"Kurtosis\": \"\",\n        \"ConfidenceInterval\": {\n          \"N\": 6,\n          \"Mean\": 1,\n          \"StandardError\": 0,\n          \"Level\": 12,\n          \"Margin\": 0,\n          \"Lower\": 1,\n          \"Upper\": 1\n        },\n        \"Percentiles\": {\n          \"P0\": 1,\n          \"P25\": 1,\n          \"P50\": 1,\n          \"P67\": 1,\n          \"P80\": 1,\n          \"P85\": 1,\n          \"P90\": 1,\n          \"P95\": 1,\n          \"P100\": 1\n        }\n      },\n      \"Memory\": {\n        \"Gen0Collections\": 0,\n        \"Gen1Collections\": 0,\n        \"Gen2Collections\": 0,\n        \"TotalOperations\": 0,\n        \"BytesAllocatedPerOperation\": null\n      }\n    },\n    {\n      \"DisplayInfo\": \"MockBenchmarkClass.Bar: LongRun(IterationCount=100, LaunchCount=3, WarmupCount=15)\",\n      \"Namespace\": \"BenchmarkDotNet.Tests.Mocks\",\n      \"Type\": \"MockBenchmarkClass\",\n      \"Method\": \"Bar\",\n      \"MethodTitle\": \"Bar\",\n      \"Parameters\": \"\",\n      \"FullName\": \"BenchmarkDotNet.Tests.Mocks.MockFactory+MockBenchmarkClass.Bar\",\n      \"HardwareIntrinsics\": \"\",\n      \"Statistics\": {\n        \"OriginalValues\": [\n          1,\n          1,\n          1,\n          1,\n          1,\n          1\n        ],\n        \"N\": 6,\n        \"Min\": 1,\n        \"LowerFence\": 1,\n        \"Q1\": 1,\n        \"Median\": 1,\n        \"Mean\": 1,\n        \"Q3\": 1,\n        \"UpperFence\": 1,\n        \"Max\": 1,\n        \"InterquartileRange\": 0,\n        \"LowerOutliers\": [],\n        \"UpperOutliers\": [],\n        \"AllOutliers\": [],\n        \"StandardError\": 0,\n        \"Variance\": 0,\n        \"StandardDeviation\": 0,\n        \"Skewness\": \"\",\n        \"Kurtosis\": \"\",\n        \"ConfidenceInterval\": {\n          \"N\": 6,\n          \"Mean\": 1,\n          \"StandardError\": 0,\n          \"Level\": 12,\n          \"Margin\": 0,\n          \"Lower\": 1,\n          \"Upper\": 1\n        },\n        \"Percentiles\": {\n          \"P0\": 1,\n          \"P25\": 1,\n          \"P50\": 1,\n          \"P67\": 1,\n          \"P80\": 1,\n          \"P85\": 1,\n          \"P90\": 1,\n          \"P95\": 1,\n          \"P100\": 1\n        }\n      },\n      \"Memory\": {\n        \"Gen0Collections\": 0,\n        \"Gen1Collections\": 0,\n        \"Gen2Collections\": 0,\n        \"TotalOperations\": 0,\n        \"BytesAllocatedPerOperation\": null\n      }\n    }\n  ]\n}\n############################################\nJsonExporter-brief-compressed\n############################################\n{\"Title\":\"MockSummary\",\"HostEnvironmentInfo\":{\"BenchmarkDotNetCaption\":\"BenchmarkDotNet\",\"BenchmarkDotNetVersion\":\"0.10.x-mock\",\"OsVersion\":\"Microsoft Windows NT 10.0.x.mock\",\"ProcessorName\":\"MockIntel Core i7-6700HQ CPU 2.60GHz\",\"PhysicalProcessorCount\":1,\"PhysicalCoreCount\":4,\"LogicalCoreCount\":8,\"RuntimeVersion\":\"Clr 4.0.x.mock\",\"Architecture\":\"64mock\",\"HasAttachedDebugger\":false,\"HasRyuJit\":true,\"Configuration\":\"CONFIGURATION\",\"DotNetCliVersion\":\"1.0.x.mock\",\"ChronometerFrequency\":{\"Hertz\":2531248},\"HardwareTimerKind\":\"Tsc\"},\"Benchmarks\":[{\"DisplayInfo\":\"MockBenchmarkClass.Foo: LongRun(IterationCount=100, LaunchCount=3, WarmupCount=15)\",\"Namespace\":\"BenchmarkDotNet.Tests.Mocks\",\"Type\":\"MockBenchmarkClass\",\"Method\":\"Foo\",\"MethodTitle\":\"Foo\",\"Parameters\":\"\",\"FullName\":\"BenchmarkDotNet.Tests.Mocks.MockFactory+MockBenchmarkClass.Foo\",\"HardwareIntrinsics\":\"\",\"Statistics\":{\"OriginalValues\":[1,1,1,1,1,1],\"N\":6,\"Min\":1,\"LowerFence\":1,\"Q1\":1,\"Median\":1,\"Mean\":1,\"Q3\":1,\"UpperFence\":1,\"Max\":1,\"InterquartileRange\":0,\"LowerOutliers\":[],\"UpperOutliers\":[],\"AllOutliers\":[],\"StandardError\":0,\"Variance\":0,\"StandardDeviation\":0,\"Skewness\":\"\",\"Kurtosis\":\"\",\"ConfidenceInterval\":{\"N\":6,\"Mean\":1,\"StandardError\":0,\"Level\":12,\"Margin\":0,\"Lower\":1,\"Upper\":1},\"Percentiles\":{\"P0\":1,\"P25\":1,\"P50\":1,\"P67\":1,\"P80\":1,\"P85\":1,\"P90\":1,\"P95\":1,\"P100\":1}},\"Memory\":{\"Gen0Collections\":0,\"Gen1Collections\":0,\"Gen2Collections\":0,\"TotalOperations\":0,\"BytesAllocatedPerOperation\":null}},{\"DisplayInfo\":\"MockBenchmarkClass.Bar: LongRun(IterationCount=100, LaunchCount=3, WarmupCount=15)\",\"Namespace\":\"BenchmarkDotNet.Tests.Mocks\",\"Type\":\"MockBenchmarkClass\",\"Method\":\"Bar\",\"MethodTitle\":\"Bar\",\"Parameters\":\"\",\"FullName\":\"BenchmarkDotNet.Tests.Mocks.MockFactory+MockBenchmarkClass.Bar\",\"HardwareIntrinsics\":\"\",\"Statistics\":{\"OriginalValues\":[1,1,1,1,1,1],\"N\":6,\"Min\":1,\"LowerFence\":1,\"Q1\":1,\"Median\":1,\"Mean\":1,\"Q3\":1,\"UpperFence\":1,\"Max\":1,\"InterquartileRange\":0,\"LowerOutliers\":[],\"UpperOutliers\":[],\"AllOutliers\":[],\"StandardError\":0,\"Variance\":0,\"StandardDeviation\":0,\"Skewness\":\"\",\"Kurtosis\":\"\",\"ConfidenceInterval\":{\"N\":6,\"Mean\":1,\"StandardError\":0,\"Level\":12,\"Margin\":0,\"Lower\":1,\"Upper\":1},\"Percentiles\":{\"P0\":1,\"P25\":1,\"P50\":1,\"P67\":1,\"P80\":1,\"P85\":1,\"P90\":1,\"P95\":1,\"P100\":1}},\"Memory\":{\"Gen0Collections\":0,\"Gen1Collections\":0,\"Gen2Collections\":0,\"TotalOperations\":0,\"BytesAllocatedPerOperation\":null}}]}\n############################################\nJsonExporter-full\n############################################\n{\n  \"Title\": \"MockSummary\",\n  \"HostEnvironmentInfo\": {\n    \"BenchmarkDotNetCaption\": \"BenchmarkDotNet\",\n    \"BenchmarkDotNetVersion\": \"0.10.x-mock\",\n    \"OsVersion\": \"Microsoft Windows NT 10.0.x.mock\",\n    \"ProcessorName\": \"MockIntel Core i7-6700HQ CPU 2.60GHz\",\n    \"PhysicalProcessorCount\": 1,\n    \"PhysicalCoreCount\": 4,\n    \"LogicalCoreCount\": 8,\n    \"RuntimeVersion\": \"Clr 4.0.x.mock\",\n    \"Architecture\": \"64mock\",\n    \"HasAttachedDebugger\": false,\n    \"HasRyuJit\": true,\n    \"Configuration\": \"CONFIGURATION\",\n    \"DotNetCliVersion\": \"1.0.x.mock\",\n    \"ChronometerFrequency\": {\n      \"Hertz\": 2531248\n    },\n    \"HardwareTimerKind\": \"Tsc\"\n  },\n  \"Benchmarks\": [\n    {\n      \"DisplayInfo\": \"MockBenchmarkClass.Foo: LongRun(IterationCount=100, LaunchCount=3, WarmupCount=15)\",\n      \"Namespace\": \"BenchmarkDotNet.Tests.Mocks\",\n      \"Type\": \"MockBenchmarkClass\",\n      \"Method\": \"Foo\",\n      \"MethodTitle\": \"Foo\",\n      \"Parameters\": \"\",\n      \"FullName\": \"BenchmarkDotNet.Tests.Mocks.MockFactory+MockBenchmarkClass.Foo\",\n      \"HardwareIntrinsics\": \"\",\n      \"Statistics\": {\n        \"OriginalValues\": [\n          1,\n          1,\n          1,\n          1,\n          1,\n          1\n        ],\n        \"N\": 6,\n        \"Min\": 1,\n        \"LowerFence\": 1,\n        \"Q1\": 1,\n        \"Median\": 1,\n        \"Mean\": 1,\n        \"Q3\": 1,\n        \"UpperFence\": 1,\n        \"Max\": 1,\n        \"InterquartileRange\": 0,\n        \"LowerOutliers\": [],\n        \"UpperOutliers\": [],\n        \"AllOutliers\": [],\n        \"StandardError\": 0,\n        \"Variance\": 0,\n        \"StandardDeviation\": 0,\n        \"Skewness\": \"\",\n        \"Kurtosis\": \"\",\n        \"ConfidenceInterval\": {\n          \"N\": 6,\n          \"Mean\": 1,\n          \"StandardError\": 0,\n          \"Level\": 12,\n          \"Margin\": 0,\n          \"Lower\": 1,\n          \"Upper\": 1\n        },\n        \"Percentiles\": {\n          \"P0\": 1,\n          \"P25\": 1,\n          \"P50\": 1,\n          \"P67\": 1,\n          \"P80\": 1,\n          \"P85\": 1,\n          \"P90\": 1,\n          \"P95\": 1,\n          \"P100\": 1\n        }\n      },\n      \"Memory\": {\n        \"Gen0Collections\": 0,\n        \"Gen1Collections\": 0,\n        \"Gen2Collections\": 0,\n        \"TotalOperations\": 0,\n        \"BytesAllocatedPerOperation\": null\n      },\n      \"Measurements\": [\n        {\n          \"IterationMode\": \"Workload\",\n          \"IterationStage\": \"Result\",\n          \"LaunchIndex\": 1,\n          \"IterationIndex\": 1,\n          \"Operations\": 1,\n          \"Nanoseconds\": 1\n        },\n        {\n          \"IterationMode\": \"Workload\",\n          \"IterationStage\": \"Result\",\n          \"LaunchIndex\": 1,\n          \"IterationIndex\": 2,\n          \"Operations\": 1,\n          \"Nanoseconds\": 1\n        },\n        {\n          \"IterationMode\": \"Workload\",\n          \"IterationStage\": \"Result\",\n          \"LaunchIndex\": 1,\n          \"IterationIndex\": 3,\n          \"Operations\": 1,\n          \"Nanoseconds\": 1\n        },\n        {\n          \"IterationMode\": \"Workload\",\n          \"IterationStage\": \"Result\",\n          \"LaunchIndex\": 1,\n          \"IterationIndex\": 4,\n          \"Operations\": 1,\n          \"Nanoseconds\": 1\n        },\n        {\n          \"IterationMode\": \"Workload\",\n          \"IterationStage\": \"Result\",\n          \"LaunchIndex\": 1,\n          \"IterationIndex\": 5,\n          \"Operations\": 1,\n          \"Nanoseconds\": 1\n        },\n        {\n          \"IterationMode\": \"Workload\",\n          \"IterationStage\": \"Result\",\n          \"LaunchIndex\": 1,\n          \"IterationIndex\": 6,\n          \"Operations\": 1,\n          \"Nanoseconds\": 1\n        }\n      ],\n      \"Metrics\": [\n        {\n          \"Value\": 7,\n          \"Descriptor\": {\n            \"Id\": \"CacheMisses\",\n            \"DisplayName\": \"CacheMisses\",\n            \"Legend\": \"Hardware counter 'CacheMisses' per single operation\",\n            \"NumberFormat\": \"N0\",\n            \"UnitType\": 0,\n            \"Unit\": \"\",\n            \"TheGreaterTheBetter\": false,\n            \"PriorityInCategory\": 0\n          }\n        }\n      ]\n    },\n    {\n      \"DisplayInfo\": \"MockBenchmarkClass.Bar: LongRun(IterationCount=100, LaunchCount=3, WarmupCount=15)\",\n      \"Namespace\": \"BenchmarkDotNet.Tests.Mocks\",\n      \"Type\": \"MockBenchmarkClass\",\n      \"Method\": \"Bar\",\n      \"MethodTitle\": \"Bar\",\n      \"Parameters\": \"\",\n      \"FullName\": \"BenchmarkDotNet.Tests.Mocks.MockFactory+MockBenchmarkClass.Bar\",\n      \"HardwareIntrinsics\": \"\",\n      \"Statistics\": {\n        \"OriginalValues\": [\n          1,\n          1,\n          1,\n          1,\n          1,\n          1\n        ],\n        \"N\": 6,\n        \"Min\": 1,\n        \"LowerFence\": 1,\n        \"Q1\": 1,\n        \"Median\": 1,\n        \"Mean\": 1,\n        \"Q3\": 1,\n        \"UpperFence\": 1,\n        \"Max\": 1,\n        \"InterquartileRange\": 0,\n        \"LowerOutliers\": [],\n        \"UpperOutliers\": [],\n        \"AllOutliers\": [],\n        \"StandardError\": 0,\n        \"Variance\": 0,\n        \"StandardDeviation\": 0,\n        \"Skewness\": \"\",\n        \"Kurtosis\": \"\",\n        \"ConfidenceInterval\": {\n          \"N\": 6,\n          \"Mean\": 1,\n          \"StandardError\": 0,\n          \"Level\": 12,\n          \"Margin\": 0,\n          \"Lower\": 1,\n          \"Upper\": 1\n        },\n        \"Percentiles\": {\n          \"P0\": 1,\n          \"P25\": 1,\n          \"P50\": 1,\n          \"P67\": 1,\n          \"P80\": 1,\n          \"P85\": 1,\n          \"P90\": 1,\n          \"P95\": 1,\n          \"P100\": 1\n        }\n      },\n      \"Memory\": {\n        \"Gen0Collections\": 0,\n        \"Gen1Collections\": 0,\n        \"Gen2Collections\": 0,\n        \"TotalOperations\": 0,\n        \"BytesAllocatedPerOperation\": null\n      },\n      \"Measurements\": [\n        {\n          \"IterationMode\": \"Workload\",\n          \"IterationStage\": \"Result\",\n          \"LaunchIndex\": 1,\n          \"IterationIndex\": 1,\n          \"Operations\": 1,\n          \"Nanoseconds\": 1\n        },\n        {\n          \"IterationMode\": \"Workload\",\n          \"IterationStage\": \"Result\",\n          \"LaunchIndex\": 1,\n          \"IterationIndex\": 2,\n          \"Operations\": 1,\n          \"Nanoseconds\": 1\n        },\n        {\n          \"IterationMode\": \"Workload\",\n          \"IterationStage\": \"Result\",\n          \"LaunchIndex\": 1,\n          \"IterationIndex\": 3,\n          \"Operations\": 1,\n          \"Nanoseconds\": 1\n        },\n        {\n          \"IterationMode\": \"Workload\",\n          \"IterationStage\": \"Result\",\n          \"LaunchIndex\": 1,\n          \"IterationIndex\": 4,\n          \"Operations\": 1,\n          \"Nanoseconds\": 1\n        },\n        {\n          \"IterationMode\": \"Workload\",\n          \"IterationStage\": \"Result\",\n          \"LaunchIndex\": 1,\n          \"IterationIndex\": 5,\n          \"Operations\": 1,\n          \"Nanoseconds\": 1\n        },\n        {\n          \"IterationMode\": \"Workload\",\n          \"IterationStage\": \"Result\",\n          \"LaunchIndex\": 1,\n          \"IterationIndex\": 6,\n          \"Operations\": 1,\n          \"Nanoseconds\": 1\n        }\n      ],\n      \"Metrics\": [\n        {\n          \"Value\": 7,\n          \"Descriptor\": {\n            \"Id\": \"CacheMisses\",\n            \"DisplayName\": \"CacheMisses\",\n            \"Legend\": \"Hardware counter 'CacheMisses' per single operation\",\n            \"NumberFormat\": \"N0\",\n            \"UnitType\": 0,\n            \"Unit\": \"\",\n            \"TheGreaterTheBetter\": false,\n            \"PriorityInCategory\": 0\n          }\n        }\n      ]\n    }\n  ]\n}\n############################################\nJsonExporter-full-compressed\n############################################\n{\"Title\":\"MockSummary\",\"HostEnvironmentInfo\":{\"BenchmarkDotNetCaption\":\"BenchmarkDotNet\",\"BenchmarkDotNetVersion\":\"0.10.x-mock\",\"OsVersion\":\"Microsoft Windows NT 10.0.x.mock\",\"ProcessorName\":\"MockIntel Core i7-6700HQ CPU 2.60GHz\",\"PhysicalProcessorCount\":1,\"PhysicalCoreCount\":4,\"LogicalCoreCount\":8,\"RuntimeVersion\":\"Clr 4.0.x.mock\",\"Architecture\":\"64mock\",\"HasAttachedDebugger\":false,\"HasRyuJit\":true,\"Configuration\":\"CONFIGURATION\",\"DotNetCliVersion\":\"1.0.x.mock\",\"ChronometerFrequency\":{\"Hertz\":2531248},\"HardwareTimerKind\":\"Tsc\"},\"Benchmarks\":[{\"DisplayInfo\":\"MockBenchmarkClass.Foo: LongRun(IterationCount=100, LaunchCount=3, WarmupCount=15)\",\"Namespace\":\"BenchmarkDotNet.Tests.Mocks\",\"Type\":\"MockBenchmarkClass\",\"Method\":\"Foo\",\"MethodTitle\":\"Foo\",\"Parameters\":\"\",\"FullName\":\"BenchmarkDotNet.Tests.Mocks.MockFactory+MockBenchmarkClass.Foo\",\"HardwareIntrinsics\":\"\",\"Statistics\":{\"OriginalValues\":[1,1,1,1,1,1],\"N\":6,\"Min\":1,\"LowerFence\":1,\"Q1\":1,\"Median\":1,\"Mean\":1,\"Q3\":1,\"UpperFence\":1,\"Max\":1,\"InterquartileRange\":0,\"LowerOutliers\":[],\"UpperOutliers\":[],\"AllOutliers\":[],\"StandardError\":0,\"Variance\":0,\"StandardDeviation\":0,\"Skewness\":\"\",\"Kurtosis\":\"\",\"ConfidenceInterval\":{\"N\":6,\"Mean\":1,\"StandardError\":0,\"Level\":12,\"Margin\":0,\"Lower\":1,\"Upper\":1},\"Percentiles\":{\"P0\":1,\"P25\":1,\"P50\":1,\"P67\":1,\"P80\":1,\"P85\":1,\"P90\":1,\"P95\":1,\"P100\":1}},\"Memory\":{\"Gen0Collections\":0,\"Gen1Collections\":0,\"Gen2Collections\":0,\"TotalOperations\":0,\"BytesAllocatedPerOperation\":null},\"Measurements\":[{\"IterationMode\":\"Workload\",\"IterationStage\":\"Result\",\"LaunchIndex\":1,\"IterationIndex\":1,\"Operations\":1,\"Nanoseconds\":1},{\"IterationMode\":\"Workload\",\"IterationStage\":\"Result\",\"LaunchIndex\":1,\"IterationIndex\":2,\"Operations\":1,\"Nanoseconds\":1},{\"IterationMode\":\"Workload\",\"IterationStage\":\"Result\",\"LaunchIndex\":1,\"IterationIndex\":3,\"Operations\":1,\"Nanoseconds\":1},{\"IterationMode\":\"Workload\",\"IterationStage\":\"Result\",\"LaunchIndex\":1,\"IterationIndex\":4,\"Operations\":1,\"Nanoseconds\":1},{\"IterationMode\":\"Workload\",\"IterationStage\":\"Result\",\"LaunchIndex\":1,\"IterationIndex\":5,\"Operations\":1,\"Nanoseconds\":1},{\"IterationMode\":\"Workload\",\"IterationStage\":\"Result\",\"LaunchIndex\":1,\"IterationIndex\":6,\"Operations\":1,\"Nanoseconds\":1}],\"Metrics\":[{\"Value\":7,\"Descriptor\":{\"Id\":\"CacheMisses\",\"DisplayName\":\"CacheMisses\",\"Legend\":\"Hardware counter 'CacheMisses' per single operation\",\"NumberFormat\":\"N0\",\"UnitType\":0,\"Unit\":\"\",\"TheGreaterTheBetter\":false,\"PriorityInCategory\":0}}]},{\"DisplayInfo\":\"MockBenchmarkClass.Bar: LongRun(IterationCount=100, LaunchCount=3, WarmupCount=15)\",\"Namespace\":\"BenchmarkDotNet.Tests.Mocks\",\"Type\":\"MockBenchmarkClass\",\"Method\":\"Bar\",\"MethodTitle\":\"Bar\",\"Parameters\":\"\",\"FullName\":\"BenchmarkDotNet.Tests.Mocks.MockFactory+MockBenchmarkClass.Bar\",\"HardwareIntrinsics\":\"\",\"Statistics\":{\"OriginalValues\":[1,1,1,1,1,1],\"N\":6,\"Min\":1,\"LowerFence\":1,\"Q1\":1,\"Median\":1,\"Mean\":1,\"Q3\":1,\"UpperFence\":1,\"Max\":1,\"InterquartileRange\":0,\"LowerOutliers\":[],\"UpperOutliers\":[],\"AllOutliers\":[],\"StandardError\":0,\"Variance\":0,\"StandardDeviation\":0,\"Skewness\":\"\",\"Kurtosis\":\"\",\"ConfidenceInterval\":{\"N\":6,\"Mean\":1,\"StandardError\":0,\"Level\":12,\"Margin\":0,\"Lower\":1,\"Upper\":1},\"Percentiles\":{\"P0\":1,\"P25\":1,\"P50\":1,\"P67\":1,\"P80\":1,\"P85\":1,\"P90\":1,\"P95\":1,\"P100\":1}},\"Memory\":{\"Gen0Collections\":0,\"Gen1Collections\":0,\"Gen2Collections\":0,\"TotalOperations\":0,\"BytesAllocatedPerOperation\":null},\"Measurements\":[{\"IterationMode\":\"Workload\",\"IterationStage\":\"Result\",\"LaunchIndex\":1,\"IterationIndex\":1,\"Operations\":1,\"Nanoseconds\":1},{\"IterationMode\":\"Workload\",\"IterationStage\":\"Result\",\"LaunchIndex\":1,\"IterationIndex\":2,\"Operations\":1,\"Nanoseconds\":1},{\"IterationMode\":\"Workload\",\"IterationStage\":\"Result\",\"LaunchIndex\":1,\"IterationIndex\":3,\"Operations\":1,\"Nanoseconds\":1},{\"IterationMode\":\"Workload\",\"IterationStage\":\"Result\",\"LaunchIndex\":1,\"IterationIndex\":4,\"Operations\":1,\"Nanoseconds\":1},{\"IterationMode\":\"Workload\",\"IterationStage\":\"Result\",\"LaunchIndex\":1,\"IterationIndex\":5,\"Operations\":1,\"Nanoseconds\":1},{\"IterationMode\":\"Workload\",\"IterationStage\":\"Result\",\"LaunchIndex\":1,\"IterationIndex\":6,\"Operations\":1,\"Nanoseconds\":1}],\"Metrics\":[{\"Value\":7,\"Descriptor\":{\"Id\":\"CacheMisses\",\"DisplayName\":\"CacheMisses\",\"Legend\":\"Hardware counter 'CacheMisses' per single operation\",\"NumberFormat\":\"N0\",\"UnitType\":0,\"Unit\":\"\",\"TheGreaterTheBetter\":false,\"PriorityInCategory\":0}}]}]}\n############################################\nMarkdownExporter-default\n############################################\n\nBenchmarkDotNet v0.10.x-mock, Microsoft Windows NT 10.0.x.mock (Hyper-V)\nMockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\nFrequency: 2531248 Hz, Resolution: 395.062 ns, Timer: TSC\n.NET Core SDK 1.0.x.mock\n  [Host] : Clr 4.0.x.mock, 64mock RyuJIT-v4.6.x.mock CONFIGURATION\n\nJob=LongRun  IterationCount=100  LaunchCount=3  \nWarmupCount=15  \n\n Method | Mean     | Error    | StdDev   | P67      | CacheMisses |\n------- |---------:|---------:|---------:|---------:|------------:|\n Foo    | 1.000 ns | 0.000 ns | 0.000 ns | 1.000 ns |           7 |\n Bar    | 1.000 ns | 0.000 ns | 0.000 ns | 1.000 ns |           7 |\n############################################\nMarkdownExporter-atlassian\n############################################\n{noformat}\n\nBenchmarkDotNet v0.10.x-mock, Microsoft Windows NT 10.0.x.mock (Hyper-V)\nMockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\nFrequency: 2531248 Hz, Resolution: 395.062 ns, Timer: TSC\n.NET Core SDK 1.0.x.mock\n  [Host] : Clr 4.0.x.mock, 64mock RyuJIT-v4.6.x.mock CONFIGURATION\n\nJob=LongRun  IterationCount=100  LaunchCount=3  \nWarmupCount=15  \n\n{noformat}\n||Method ||Mean     ||Error    ||StdDev   ||P67      ||CacheMisses ||\n| Foo    | 1.000 ns | 0.000 ns | 0.000 ns | 1.000 ns |           7 |\n| Bar    | 1.000 ns | 0.000 ns | 0.000 ns | 1.000 ns |           7 |\n############################################\nMarkdownExporter-console\n############################################\n\nBenchmarkDotNet v0.10.x-mock, Microsoft Windows NT 10.0.x.mock (Hyper-V)\nMockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\nFrequency: 2531248 Hz, Resolution: 395.062 ns, Timer: TSC\n.NET Core SDK 1.0.x.mock\n  [Host] : Clr 4.0.x.mock, 64mock RyuJIT-v4.6.x.mock CONFIGURATION\n\nJob=LongRun  IterationCount=100  LaunchCount=3  \nWarmupCount=15  \n\n| Method | Mean     | Error    | StdDev   | P67      | CacheMisses |\n|------- |---------:|---------:|---------:|---------:|------------:|\n| Foo    | 1.000 ns | 0.000 ns | 0.000 ns | 1.000 ns |           7 |\n| Bar    | 1.000 ns | 0.000 ns | 0.000 ns | 1.000 ns |           7 |\n############################################\nMarkdownExporter-github\n############################################\n```\n\nBenchmarkDotNet v0.10.x-mock, Microsoft Windows NT 10.0.x.mock (Hyper-V)\nMockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\nFrequency: 2531248 Hz, Resolution: 395.062 ns, Timer: TSC\n.NET Core SDK 1.0.x.mock\n  [Host] : Clr 4.0.x.mock, 64mock RyuJIT-v4.6.x.mock CONFIGURATION\n\nJob=LongRun  IterationCount=100  LaunchCount=3  \nWarmupCount=15  \n\n```\n| Method | Mean     | Error    | StdDev   | P67      | CacheMisses |\n|------- |---------:|---------:|---------:|---------:|------------:|\n| Foo    | 1.000 ns | 0.000 ns | 0.000 ns | 1.000 ns |           7 |\n| Bar    | 1.000 ns | 0.000 ns | 0.000 ns | 1.000 ns |           7 |\n############################################\nMarkdownExporter-stackoverflow\n############################################\n\n    BenchmarkDotNet v0.10.x-mock, Microsoft Windows NT 10.0.x.mock (Hyper-V)\n    MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n    Frequency: 2531248 Hz, Resolution: 395.062 ns, Timer: TSC\n    .NET Core SDK 1.0.x.mock\n      [Host] : Clr 4.0.x.mock, 64mock RyuJIT-v4.6.x.mock CONFIGURATION\n\n    Job=LongRun  IterationCount=100  LaunchCount=3  \n    WarmupCount=15  \n\n     Method | Mean     | Error    | StdDev   | P67      | CacheMisses |\n    ------- |---------:|---------:|---------:|---------:|------------:|\n     Foo    | 1.000 ns | 0.000 ns | 0.000 ns | 1.000 ns |           7 |\n     Bar    | 1.000 ns | 0.000 ns | 0.000 ns | 1.000 ns |           7 |\n############################################\nOpenMetricsExporter\n############################################\n# HELP benchmark_cachemisses Additional metric CacheMisses\n# TYPE benchmark_cachemisses gauge\nbenchmark_cachemisses{method=\"Foo\", type=\"MockBenchmarkClass\"} 7\nbenchmark_cachemisses{method=\"Bar\", type=\"MockBenchmarkClass\"} 7\n# HELP benchmark_error_nanoseconds Standard error of the mean execution time in nanoseconds.\n# TYPE benchmark_error_nanoseconds gauge\n# UNIT benchmark_error_nanoseconds nanoseconds\nbenchmark_error_nanoseconds{method=\"Foo\", type=\"MockBenchmarkClass\"} 0\nbenchmark_error_nanoseconds{method=\"Bar\", type=\"MockBenchmarkClass\"} 0\n# HELP benchmark_execution_time_nanoseconds Mean execution time in nanoseconds.\n# TYPE benchmark_execution_time_nanoseconds gauge\n# UNIT benchmark_execution_time_nanoseconds nanoseconds\nbenchmark_execution_time_nanoseconds{method=\"Foo\", type=\"MockBenchmarkClass\"} 1\nbenchmark_execution_time_nanoseconds{method=\"Bar\", type=\"MockBenchmarkClass\"} 1\n# HELP benchmark_gc_gen0_collections_total Total number of Gen 0 garbage collections during the benchmark execution.\n# TYPE benchmark_gc_gen0_collections_total counter\nbenchmark_gc_gen0_collections_total{method=\"Foo\", type=\"MockBenchmarkClass\"} 0\nbenchmark_gc_gen0_collections_total{method=\"Bar\", type=\"MockBenchmarkClass\"} 0\n# HELP benchmark_gc_gen1_collections_total Total number of Gen 1 garbage collections during the benchmark execution.\n# TYPE benchmark_gc_gen1_collections_total counter\nbenchmark_gc_gen1_collections_total{method=\"Foo\", type=\"MockBenchmarkClass\"} 0\nbenchmark_gc_gen1_collections_total{method=\"Bar\", type=\"MockBenchmarkClass\"} 0\n# HELP benchmark_gc_gen2_collections_total Total number of Gen 2 garbage collections during the benchmark execution.\n# TYPE benchmark_gc_gen2_collections_total counter\nbenchmark_gc_gen2_collections_total{method=\"Foo\", type=\"MockBenchmarkClass\"} 0\nbenchmark_gc_gen2_collections_total{method=\"Bar\", type=\"MockBenchmarkClass\"} 0\n# HELP benchmark_gc_total_operations_total Total number of garbage collection operations during the benchmark execution.\n# TYPE benchmark_gc_total_operations_total counter\nbenchmark_gc_total_operations_total{method=\"Foo\", type=\"MockBenchmarkClass\"} 0\nbenchmark_gc_total_operations_total{method=\"Bar\", type=\"MockBenchmarkClass\"} 0\n# HELP benchmark_p90_nanoseconds 90th percentile execution time in nanoseconds.\n# TYPE benchmark_p90_nanoseconds gauge\n# UNIT benchmark_p90_nanoseconds nanoseconds\nbenchmark_p90_nanoseconds{method=\"Foo\", type=\"MockBenchmarkClass\"} 1\nbenchmark_p90_nanoseconds{method=\"Bar\", type=\"MockBenchmarkClass\"} 1\n# HELP benchmark_p95_nanoseconds 95th percentile execution time in nanoseconds.\n# TYPE benchmark_p95_nanoseconds gauge\n# UNIT benchmark_p95_nanoseconds nanoseconds\nbenchmark_p95_nanoseconds{method=\"Foo\", type=\"MockBenchmarkClass\"} 1\nbenchmark_p95_nanoseconds{method=\"Bar\", type=\"MockBenchmarkClass\"} 1\n# HELP benchmark_stddev_nanoseconds Standard deviation of execution time in nanoseconds.\n# TYPE benchmark_stddev_nanoseconds gauge\n# UNIT benchmark_stddev_nanoseconds nanoseconds\nbenchmark_stddev_nanoseconds{method=\"Foo\", type=\"MockBenchmarkClass\"} 0\nbenchmark_stddev_nanoseconds{method=\"Bar\", type=\"MockBenchmarkClass\"} 0\n# EOF\n############################################\nPlainExporter\n############################################\n*** MockBenchmarkClass.Foo: LongRun(IterationCount=100, LaunchCount=3, WarmupCount=15) ***\n* Raw *\nWorkloadResult   1: 1 op, 1.00 ns, 1.0000 ns/op\nWorkloadResult   2: 1 op, 1.00 ns, 1.0000 ns/op\nWorkloadResult   3: 1 op, 1.00 ns, 1.0000 ns/op\nWorkloadResult   4: 1 op, 1.00 ns, 1.0000 ns/op\nWorkloadResult   5: 1 op, 1.00 ns, 1.0000 ns/op\nWorkloadResult   6: 1 op, 1.00 ns, 1.0000 ns/op\n\n* Statistics for WorkloadResult\nMean = 1.000 ns, StdErr = 0.000 ns (0.00%), N = 6, StdDev = 0.000 ns\nMin = 1.000 ns, Q1 = 1.000 ns, Median = 1.000 ns, Q3 = 1.000 ns, Max = 1.000 ns\nIQR = 0.000 ns, LowerFence = 1.000 ns, UpperFence = 1.000 ns\nConfidenceInterval = [1.000 ns; 1.000 ns] (CI 99.9%), Margin = 0.000 ns (0.00% of Mean)\nSkewness = NaN, Kurtosis = NaN, MValue = 2\n-------------------- Histogram --------------------\n[0.500 ns ; 1.500 ns) | @@@@@@\n---------------------------------------------------\n*** MockBenchmarkClass.Bar: LongRun(IterationCount=100, LaunchCount=3, WarmupCount=15) ***\n* Raw *\nWorkloadResult   1: 1 op, 1.00 ns, 1.0000 ns/op\nWorkloadResult   2: 1 op, 1.00 ns, 1.0000 ns/op\nWorkloadResult   3: 1 op, 1.00 ns, 1.0000 ns/op\nWorkloadResult   4: 1 op, 1.00 ns, 1.0000 ns/op\nWorkloadResult   5: 1 op, 1.00 ns, 1.0000 ns/op\nWorkloadResult   6: 1 op, 1.00 ns, 1.0000 ns/op\n\n* Statistics for WorkloadResult\nMean = 1.000 ns, StdErr = 0.000 ns (0.00%), N = 6, StdDev = 0.000 ns\nMin = 1.000 ns, Q1 = 1.000 ns, Median = 1.000 ns, Q3 = 1.000 ns, Max = 1.000 ns\nIQR = 0.000 ns, LowerFence = 1.000 ns, UpperFence = 1.000 ns\nConfidenceInterval = [1.000 ns; 1.000 ns] (CI 99.9%), Margin = 0.000 ns (0.00% of Mean)\nSkewness = NaN, Kurtosis = NaN, MValue = 2\n-------------------- Histogram --------------------\n[0.500 ns ; 1.500 ns) | @@@@@@\n---------------------------------------------------\n############################################\nXmlExporter-brief\n############################################\n<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Summary>\n  <Title>MockSummary</Title>\n  <HostEnvironmentInfo>\n    <BenchmarkDotNetCaption>BenchmarkDotNet</BenchmarkDotNetCaption>\n    <BenchmarkDotNetVersion>0.10.x-mock</BenchmarkDotNetVersion>\n    <OsVersion>Microsoft Windows NT 10.0.x.mock</OsVersion>\n    <ProcessorName>MockIntel Core i7-6700HQ CPU 2.60GHz</ProcessorName>\n    <PhysicalProcessorCount>1</PhysicalProcessorCount>\n    <PhysicalCoreCount>4</PhysicalCoreCount>\n    <LogicalCoreCount>8</LogicalCoreCount>\n    <RuntimeVersion>Clr 4.0.x.mock</RuntimeVersion>\n    <Architecture>64mock</Architecture>\n    <HasAttachedDebugger>False</HasAttachedDebugger>\n    <HasRyuJit>True</HasRyuJit>\n    <Configuration>CONFIGURATION</Configuration>\n    <DotNetSdkVersion>1.0.x.mock</DotNetSdkVersion>\n    <ChronometerFrequency>\n      <Hertz>2531248</Hertz>\n    </ChronometerFrequency>\n    <HardwareTimerKind>Tsc</HardwareTimerKind>\n  </HostEnvironmentInfo>\n  <Benchmarks>\n    <BenchmarkCase>\n      <DisplayInfo>MockBenchmarkClass.Foo: LongRun(IterationCount=100, LaunchCount=3, WarmupCount=15)</DisplayInfo>\n      <Namespace>BenchmarkDotNet.Tests.Mocks</Namespace>\n      <Type>MockBenchmarkClass</Type>\n      <Method>Foo</Method>\n      <MethodTitle>Foo</MethodTitle>\n      <Statistics>\n        <OriginalValues>\n          <Item>1</Item>\n          <Item>1</Item>\n          <Item>1</Item>\n          <Item>1</Item>\n          <Item>1</Item>\n          <Item>1</Item>\n        </OriginalValues>\n        <N>6</N>\n        <Min>1</Min>\n        <LowerFence>1</LowerFence>\n        <Q1>1</Q1>\n        <Median>1</Median>\n        <Mean>1</Mean>\n        <Q3>1</Q3>\n        <UpperFence>1</UpperFence>\n        <Max>1</Max>\n        <InterquartileRange>0</InterquartileRange>\n        <StandardError>0</StandardError>\n        <Variance>0</Variance>\n        <StandardDeviation>0</StandardDeviation>\n        <Skewness>NaN</Skewness>\n        <Kurtosis>NaN</Kurtosis>\n        <ConfidenceInterval>\n          <N>6</N>\n          <Mean>1</Mean>\n          <StandardError>0</StandardError>\n          <Level>L999</Level>\n          <Margin>0</Margin>\n          <Lower>1</Lower>\n          <Upper>1</Upper>\n        </ConfidenceInterval>\n        <Percentiles>\n          <P0>1</P0>\n          <P25>1</P25>\n          <P50>1</P50>\n          <P67>1</P67>\n          <P80>1</P80>\n          <P85>1</P85>\n          <P90>1</P90>\n          <P95>1</P95>\n          <P100>1</P100>\n        </Percentiles>\n      </Statistics>\n      <Metrics>\n        <Item>\n          <Value>7</Value>\n          <Descriptor>\n            <Id>CacheMisses</Id>\n            <DisplayName>CacheMisses</DisplayName>\n            <Legend>Hardware counter 'CacheMisses' per single operation</Legend>\n            <NumberFormat>N0</NumberFormat>\n            <UnitType>Dimensionless</UnitType>\n            <TheGreaterTheBetter>False</TheGreaterTheBetter>\n            <PriorityInCategory>0</PriorityInCategory>\n          </Descriptor>\n        </Item>\n      </Metrics>\n      <Memory>\n        <Gen0Collections>0</Gen0Collections>\n        <Gen1Collections>0</Gen1Collections>\n        <Gen2Collections>0</Gen2Collections>\n        <TotalOperations>0</TotalOperations>\n        <BytesAllocatedPerOperation />\n      </Memory>\n    </BenchmarkCase>\n    <BenchmarkCase>\n      <DisplayInfo>MockBenchmarkClass.Bar: LongRun(IterationCount=100, LaunchCount=3, WarmupCount=15)</DisplayInfo>\n      <Namespace>BenchmarkDotNet.Tests.Mocks</Namespace>\n      <Type>MockBenchmarkClass</Type>\n      <Method>Bar</Method>\n      <MethodTitle>Bar</MethodTitle>\n      <Statistics>\n        <OriginalValues>\n          <Item>1</Item>\n          <Item>1</Item>\n          <Item>1</Item>\n          <Item>1</Item>\n          <Item>1</Item>\n          <Item>1</Item>\n        </OriginalValues>\n        <N>6</N>\n        <Min>1</Min>\n        <LowerFence>1</LowerFence>\n        <Q1>1</Q1>\n        <Median>1</Median>\n        <Mean>1</Mean>\n        <Q3>1</Q3>\n        <UpperFence>1</UpperFence>\n        <Max>1</Max>\n        <InterquartileRange>0</InterquartileRange>\n        <StandardError>0</StandardError>\n        <Variance>0</Variance>\n        <StandardDeviation>0</StandardDeviation>\n        <Skewness>NaN</Skewness>\n        <Kurtosis>NaN</Kurtosis>\n        <ConfidenceInterval>\n          <N>6</N>\n          <Mean>1</Mean>\n          <StandardError>0</StandardError>\n          <Level>L999</Level>\n          <Margin>0</Margin>\n          <Lower>1</Lower>\n          <Upper>1</Upper>\n        </ConfidenceInterval>\n        <Percentiles>\n          <P0>1</P0>\n          <P25>1</P25>\n          <P50>1</P50>\n          <P67>1</P67>\n          <P80>1</P80>\n          <P85>1</P85>\n          <P90>1</P90>\n          <P95>1</P95>\n          <P100>1</P100>\n        </Percentiles>\n      </Statistics>\n      <Metrics>\n        <Item>\n          <Value>7</Value>\n          <Descriptor>\n            <Id>CacheMisses</Id>\n            <DisplayName>CacheMisses</DisplayName>\n            <Legend>Hardware counter 'CacheMisses' per single operation</Legend>\n            <NumberFormat>N0</NumberFormat>\n            <UnitType>Dimensionless</UnitType>\n            <TheGreaterTheBetter>False</TheGreaterTheBetter>\n            <PriorityInCategory>0</PriorityInCategory>\n          </Descriptor>\n        </Item>\n      </Metrics>\n      <Memory>\n        <Gen0Collections>0</Gen0Collections>\n        <Gen1Collections>0</Gen1Collections>\n        <Gen2Collections>0</Gen2Collections>\n        <TotalOperations>0</TotalOperations>\n        <BytesAllocatedPerOperation />\n      </Memory>\n    </BenchmarkCase>\n  </Benchmarks>\n</Summary>\n############################################\nXmlExporter-brief-compressed\n############################################\n<?xml version=\"1.0\" encoding=\"utf-8\"?><Summary><Title>MockSummary</Title><HostEnvironmentInfo><BenchmarkDotNetCaption>BenchmarkDotNet</BenchmarkDotNetCaption><BenchmarkDotNetVersion>0.10.x-mock</BenchmarkDotNetVersion><OsVersion>Microsoft Windows NT 10.0.x.mock</OsVersion><ProcessorName>MockIntel Core i7-6700HQ CPU 2.60GHz</ProcessorName><PhysicalProcessorCount>1</PhysicalProcessorCount><PhysicalCoreCount>4</PhysicalCoreCount><LogicalCoreCount>8</LogicalCoreCount><RuntimeVersion>Clr 4.0.x.mock</RuntimeVersion><Architecture>64mock</Architecture><HasAttachedDebugger>False</HasAttachedDebugger><HasRyuJit>True</HasRyuJit><Configuration>CONFIGURATION</Configuration><DotNetSdkVersion>1.0.x.mock</DotNetSdkVersion><ChronometerFrequency><Hertz>2531248</Hertz></ChronometerFrequency><HardwareTimerKind>Tsc</HardwareTimerKind></HostEnvironmentInfo><Benchmarks><BenchmarkCase><DisplayInfo>MockBenchmarkClass.Foo: LongRun(IterationCount=100, LaunchCount=3, WarmupCount=15)</DisplayInfo><Namespace>BenchmarkDotNet.Tests.Mocks</Namespace><Type>MockBenchmarkClass</Type><Method>Foo</Method><MethodTitle>Foo</MethodTitle><Statistics><OriginalValues><Item>1</Item><Item>1</Item><Item>1</Item><Item>1</Item><Item>1</Item><Item>1</Item></OriginalValues><N>6</N><Min>1</Min><LowerFence>1</LowerFence><Q1>1</Q1><Median>1</Median><Mean>1</Mean><Q3>1</Q3><UpperFence>1</UpperFence><Max>1</Max><InterquartileRange>0</InterquartileRange><StandardError>0</StandardError><Variance>0</Variance><StandardDeviation>0</StandardDeviation><Skewness>NaN</Skewness><Kurtosis>NaN</Kurtosis><ConfidenceInterval><N>6</N><Mean>1</Mean><StandardError>0</StandardError><Level>L999</Level><Margin>0</Margin><Lower>1</Lower><Upper>1</Upper></ConfidenceInterval><Percentiles><P0>1</P0><P25>1</P25><P50>1</P50><P67>1</P67><P80>1</P80><P85>1</P85><P90>1</P90><P95>1</P95><P100>1</P100></Percentiles></Statistics><Metrics><Item><Value>7</Value><Descriptor><Id>CacheMisses</Id><DisplayName>CacheMisses</DisplayName><Legend>Hardware counter 'CacheMisses' per single operation</Legend><NumberFormat>N0</NumberFormat><UnitType>Dimensionless</UnitType><TheGreaterTheBetter>False</TheGreaterTheBetter><PriorityInCategory>0</PriorityInCategory></Descriptor></Item></Metrics><Memory><Gen0Collections>0</Gen0Collections><Gen1Collections>0</Gen1Collections><Gen2Collections>0</Gen2Collections><TotalOperations>0</TotalOperations><BytesAllocatedPerOperation /></Memory></BenchmarkCase><BenchmarkCase><DisplayInfo>MockBenchmarkClass.Bar: LongRun(IterationCount=100, LaunchCount=3, WarmupCount=15)</DisplayInfo><Namespace>BenchmarkDotNet.Tests.Mocks</Namespace><Type>MockBenchmarkClass</Type><Method>Bar</Method><MethodTitle>Bar</MethodTitle><Statistics><OriginalValues><Item>1</Item><Item>1</Item><Item>1</Item><Item>1</Item><Item>1</Item><Item>1</Item></OriginalValues><N>6</N><Min>1</Min><LowerFence>1</LowerFence><Q1>1</Q1><Median>1</Median><Mean>1</Mean><Q3>1</Q3><UpperFence>1</UpperFence><Max>1</Max><InterquartileRange>0</InterquartileRange><StandardError>0</StandardError><Variance>0</Variance><StandardDeviation>0</StandardDeviation><Skewness>NaN</Skewness><Kurtosis>NaN</Kurtosis><ConfidenceInterval><N>6</N><Mean>1</Mean><StandardError>0</StandardError><Level>L999</Level><Margin>0</Margin><Lower>1</Lower><Upper>1</Upper></ConfidenceInterval><Percentiles><P0>1</P0><P25>1</P25><P50>1</P50><P67>1</P67><P80>1</P80><P85>1</P85><P90>1</P90><P95>1</P95><P100>1</P100></Percentiles></Statistics><Metrics><Item><Value>7</Value><Descriptor><Id>CacheMisses</Id><DisplayName>CacheMisses</DisplayName><Legend>Hardware counter 'CacheMisses' per single operation</Legend><NumberFormat>N0</NumberFormat><UnitType>Dimensionless</UnitType><TheGreaterTheBetter>False</TheGreaterTheBetter><PriorityInCategory>0</PriorityInCategory></Descriptor></Item></Metrics><Memory><Gen0Collections>0</Gen0Collections><Gen1Collections>0</Gen1Collections><Gen2Collections>0</Gen2Collections><TotalOperations>0</TotalOperations><BytesAllocatedPerOperation /></Memory></BenchmarkCase></Benchmarks></Summary>\n############################################\nXmlExporter-full\n############################################\n<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Summary>\n  <Title>MockSummary</Title>\n  <HostEnvironmentInfo>\n    <BenchmarkDotNetCaption>BenchmarkDotNet</BenchmarkDotNetCaption>\n    <BenchmarkDotNetVersion>0.10.x-mock</BenchmarkDotNetVersion>\n    <OsVersion>Microsoft Windows NT 10.0.x.mock</OsVersion>\n    <ProcessorName>MockIntel Core i7-6700HQ CPU 2.60GHz</ProcessorName>\n    <PhysicalProcessorCount>1</PhysicalProcessorCount>\n    <PhysicalCoreCount>4</PhysicalCoreCount>\n    <LogicalCoreCount>8</LogicalCoreCount>\n    <RuntimeVersion>Clr 4.0.x.mock</RuntimeVersion>\n    <Architecture>64mock</Architecture>\n    <HasAttachedDebugger>False</HasAttachedDebugger>\n    <HasRyuJit>True</HasRyuJit>\n    <Configuration>CONFIGURATION</Configuration>\n    <DotNetSdkVersion>1.0.x.mock</DotNetSdkVersion>\n    <ChronometerFrequency>\n      <Hertz>2531248</Hertz>\n    </ChronometerFrequency>\n    <HardwareTimerKind>Tsc</HardwareTimerKind>\n  </HostEnvironmentInfo>\n  <Benchmarks>\n    <BenchmarkCase>\n      <DisplayInfo>MockBenchmarkClass.Foo: LongRun(IterationCount=100, LaunchCount=3, WarmupCount=15)</DisplayInfo>\n      <Namespace>BenchmarkDotNet.Tests.Mocks</Namespace>\n      <Type>MockBenchmarkClass</Type>\n      <Method>Foo</Method>\n      <MethodTitle>Foo</MethodTitle>\n      <Statistics>\n        <OriginalValues>\n          <Item>1</Item>\n          <Item>1</Item>\n          <Item>1</Item>\n          <Item>1</Item>\n          <Item>1</Item>\n          <Item>1</Item>\n        </OriginalValues>\n        <N>6</N>\n        <Min>1</Min>\n        <LowerFence>1</LowerFence>\n        <Q1>1</Q1>\n        <Median>1</Median>\n        <Mean>1</Mean>\n        <Q3>1</Q3>\n        <UpperFence>1</UpperFence>\n        <Max>1</Max>\n        <InterquartileRange>0</InterquartileRange>\n        <StandardError>0</StandardError>\n        <Variance>0</Variance>\n        <StandardDeviation>0</StandardDeviation>\n        <Skewness>NaN</Skewness>\n        <Kurtosis>NaN</Kurtosis>\n        <ConfidenceInterval>\n          <N>6</N>\n          <Mean>1</Mean>\n          <StandardError>0</StandardError>\n          <Level>L999</Level>\n          <Margin>0</Margin>\n          <Lower>1</Lower>\n          <Upper>1</Upper>\n        </ConfidenceInterval>\n        <Percentiles>\n          <P0>1</P0>\n          <P25>1</P25>\n          <P50>1</P50>\n          <P67>1</P67>\n          <P80>1</P80>\n          <P85>1</P85>\n          <P90>1</P90>\n          <P95>1</P95>\n          <P100>1</P100>\n        </Percentiles>\n      </Statistics>\n      <Metrics>\n        <Item>\n          <Value>7</Value>\n          <Descriptor>\n            <Id>CacheMisses</Id>\n            <DisplayName>CacheMisses</DisplayName>\n            <Legend>Hardware counter 'CacheMisses' per single operation</Legend>\n            <NumberFormat>N0</NumberFormat>\n            <UnitType>Dimensionless</UnitType>\n            <TheGreaterTheBetter>False</TheGreaterTheBetter>\n            <PriorityInCategory>0</PriorityInCategory>\n          </Descriptor>\n        </Item>\n      </Metrics>\n      <Memory>\n        <Gen0Collections>0</Gen0Collections>\n        <Gen1Collections>0</Gen1Collections>\n        <Gen2Collections>0</Gen2Collections>\n        <TotalOperations>0</TotalOperations>\n        <BytesAllocatedPerOperation />\n      </Memory>\n      <Measurements>\n        <Measurement>\n          <IterationMode>Workload</IterationMode>\n          <IterationStage>Result</IterationStage>\n          <LaunchIndex>1</LaunchIndex>\n          <IterationIndex>1</IterationIndex>\n          <Operations>1</Operations>\n          <Nanoseconds>1</Nanoseconds>\n        </Measurement>\n        <Measurement>\n          <IterationMode>Workload</IterationMode>\n          <IterationStage>Result</IterationStage>\n          <LaunchIndex>1</LaunchIndex>\n          <IterationIndex>2</IterationIndex>\n          <Operations>1</Operations>\n          <Nanoseconds>1</Nanoseconds>\n        </Measurement>\n        <Measurement>\n          <IterationMode>Workload</IterationMode>\n          <IterationStage>Result</IterationStage>\n          <LaunchIndex>1</LaunchIndex>\n          <IterationIndex>3</IterationIndex>\n          <Operations>1</Operations>\n          <Nanoseconds>1</Nanoseconds>\n        </Measurement>\n        <Measurement>\n          <IterationMode>Workload</IterationMode>\n          <IterationStage>Result</IterationStage>\n          <LaunchIndex>1</LaunchIndex>\n          <IterationIndex>4</IterationIndex>\n          <Operations>1</Operations>\n          <Nanoseconds>1</Nanoseconds>\n        </Measurement>\n        <Measurement>\n          <IterationMode>Workload</IterationMode>\n          <IterationStage>Result</IterationStage>\n          <LaunchIndex>1</LaunchIndex>\n          <IterationIndex>5</IterationIndex>\n          <Operations>1</Operations>\n          <Nanoseconds>1</Nanoseconds>\n        </Measurement>\n        <Measurement>\n          <IterationMode>Workload</IterationMode>\n          <IterationStage>Result</IterationStage>\n          <LaunchIndex>1</LaunchIndex>\n          <IterationIndex>6</IterationIndex>\n          <Operations>1</Operations>\n          <Nanoseconds>1</Nanoseconds>\n        </Measurement>\n      </Measurements>\n    </BenchmarkCase>\n    <BenchmarkCase>\n      <DisplayInfo>MockBenchmarkClass.Bar: LongRun(IterationCount=100, LaunchCount=3, WarmupCount=15)</DisplayInfo>\n      <Namespace>BenchmarkDotNet.Tests.Mocks</Namespace>\n      <Type>MockBenchmarkClass</Type>\n      <Method>Bar</Method>\n      <MethodTitle>Bar</MethodTitle>\n      <Statistics>\n        <OriginalValues>\n          <Item>1</Item>\n          <Item>1</Item>\n          <Item>1</Item>\n          <Item>1</Item>\n          <Item>1</Item>\n          <Item>1</Item>\n        </OriginalValues>\n        <N>6</N>\n        <Min>1</Min>\n        <LowerFence>1</LowerFence>\n        <Q1>1</Q1>\n        <Median>1</Median>\n        <Mean>1</Mean>\n        <Q3>1</Q3>\n        <UpperFence>1</UpperFence>\n        <Max>1</Max>\n        <InterquartileRange>0</InterquartileRange>\n        <StandardError>0</StandardError>\n        <Variance>0</Variance>\n        <StandardDeviation>0</StandardDeviation>\n        <Skewness>NaN</Skewness>\n        <Kurtosis>NaN</Kurtosis>\n        <ConfidenceInterval>\n          <N>6</N>\n          <Mean>1</Mean>\n          <StandardError>0</StandardError>\n          <Level>L999</Level>\n          <Margin>0</Margin>\n          <Lower>1</Lower>\n          <Upper>1</Upper>\n        </ConfidenceInterval>\n        <Percentiles>\n          <P0>1</P0>\n          <P25>1</P25>\n          <P50>1</P50>\n          <P67>1</P67>\n          <P80>1</P80>\n          <P85>1</P85>\n          <P90>1</P90>\n          <P95>1</P95>\n          <P100>1</P100>\n        </Percentiles>\n      </Statistics>\n      <Metrics>\n        <Item>\n          <Value>7</Value>\n          <Descriptor>\n            <Id>CacheMisses</Id>\n            <DisplayName>CacheMisses</DisplayName>\n            <Legend>Hardware counter 'CacheMisses' per single operation</Legend>\n            <NumberFormat>N0</NumberFormat>\n            <UnitType>Dimensionless</UnitType>\n            <TheGreaterTheBetter>False</TheGreaterTheBetter>\n            <PriorityInCategory>0</PriorityInCategory>\n          </Descriptor>\n        </Item>\n      </Metrics>\n      <Memory>\n        <Gen0Collections>0</Gen0Collections>\n        <Gen1Collections>0</Gen1Collections>\n        <Gen2Collections>0</Gen2Collections>\n        <TotalOperations>0</TotalOperations>\n        <BytesAllocatedPerOperation />\n      </Memory>\n      <Measurements>\n        <Measurement>\n          <IterationMode>Workload</IterationMode>\n          <IterationStage>Result</IterationStage>\n          <LaunchIndex>1</LaunchIndex>\n          <IterationIndex>1</IterationIndex>\n          <Operations>1</Operations>\n          <Nanoseconds>1</Nanoseconds>\n        </Measurement>\n        <Measurement>\n          <IterationMode>Workload</IterationMode>\n          <IterationStage>Result</IterationStage>\n          <LaunchIndex>1</LaunchIndex>\n          <IterationIndex>2</IterationIndex>\n          <Operations>1</Operations>\n          <Nanoseconds>1</Nanoseconds>\n        </Measurement>\n        <Measurement>\n          <IterationMode>Workload</IterationMode>\n          <IterationStage>Result</IterationStage>\n          <LaunchIndex>1</LaunchIndex>\n          <IterationIndex>3</IterationIndex>\n          <Operations>1</Operations>\n          <Nanoseconds>1</Nanoseconds>\n        </Measurement>\n        <Measurement>\n          <IterationMode>Workload</IterationMode>\n          <IterationStage>Result</IterationStage>\n          <LaunchIndex>1</LaunchIndex>\n          <IterationIndex>4</IterationIndex>\n          <Operations>1</Operations>\n          <Nanoseconds>1</Nanoseconds>\n        </Measurement>\n        <Measurement>\n          <IterationMode>Workload</IterationMode>\n          <IterationStage>Result</IterationStage>\n          <LaunchIndex>1</LaunchIndex>\n          <IterationIndex>5</IterationIndex>\n          <Operations>1</Operations>\n          <Nanoseconds>1</Nanoseconds>\n        </Measurement>\n        <Measurement>\n          <IterationMode>Workload</IterationMode>\n          <IterationStage>Result</IterationStage>\n          <LaunchIndex>1</LaunchIndex>\n          <IterationIndex>6</IterationIndex>\n          <Operations>1</Operations>\n          <Nanoseconds>1</Nanoseconds>\n        </Measurement>\n      </Measurements>\n    </BenchmarkCase>\n  </Benchmarks>\n</Summary>\n############################################\nXmlExporter-full-compressed\n############################################\n<?xml version=\"1.0\" encoding=\"utf-8\"?><Summary><Title>MockSummary</Title><HostEnvironmentInfo><BenchmarkDotNetCaption>BenchmarkDotNet</BenchmarkDotNetCaption><BenchmarkDotNetVersion>0.10.x-mock</BenchmarkDotNetVersion><OsVersion>Microsoft Windows NT 10.0.x.mock</OsVersion><ProcessorName>MockIntel Core i7-6700HQ CPU 2.60GHz</ProcessorName><PhysicalProcessorCount>1</PhysicalProcessorCount><PhysicalCoreCount>4</PhysicalCoreCount><LogicalCoreCount>8</LogicalCoreCount><RuntimeVersion>Clr 4.0.x.mock</RuntimeVersion><Architecture>64mock</Architecture><HasAttachedDebugger>False</HasAttachedDebugger><HasRyuJit>True</HasRyuJit><Configuration>CONFIGURATION</Configuration><DotNetSdkVersion>1.0.x.mock</DotNetSdkVersion><ChronometerFrequency><Hertz>2531248</Hertz></ChronometerFrequency><HardwareTimerKind>Tsc</HardwareTimerKind></HostEnvironmentInfo><Benchmarks><BenchmarkCase><DisplayInfo>MockBenchmarkClass.Foo: LongRun(IterationCount=100, LaunchCount=3, WarmupCount=15)</DisplayInfo><Namespace>BenchmarkDotNet.Tests.Mocks</Namespace><Type>MockBenchmarkClass</Type><Method>Foo</Method><MethodTitle>Foo</MethodTitle><Statistics><OriginalValues><Item>1</Item><Item>1</Item><Item>1</Item><Item>1</Item><Item>1</Item><Item>1</Item></OriginalValues><N>6</N><Min>1</Min><LowerFence>1</LowerFence><Q1>1</Q1><Median>1</Median><Mean>1</Mean><Q3>1</Q3><UpperFence>1</UpperFence><Max>1</Max><InterquartileRange>0</InterquartileRange><StandardError>0</StandardError><Variance>0</Variance><StandardDeviation>0</StandardDeviation><Skewness>NaN</Skewness><Kurtosis>NaN</Kurtosis><ConfidenceInterval><N>6</N><Mean>1</Mean><StandardError>0</StandardError><Level>L999</Level><Margin>0</Margin><Lower>1</Lower><Upper>1</Upper></ConfidenceInterval><Percentiles><P0>1</P0><P25>1</P25><P50>1</P50><P67>1</P67><P80>1</P80><P85>1</P85><P90>1</P90><P95>1</P95><P100>1</P100></Percentiles></Statistics><Metrics><Item><Value>7</Value><Descriptor><Id>CacheMisses</Id><DisplayName>CacheMisses</DisplayName><Legend>Hardware counter 'CacheMisses' per single operation</Legend><NumberFormat>N0</NumberFormat><UnitType>Dimensionless</UnitType><TheGreaterTheBetter>False</TheGreaterTheBetter><PriorityInCategory>0</PriorityInCategory></Descriptor></Item></Metrics><Memory><Gen0Collections>0</Gen0Collections><Gen1Collections>0</Gen1Collections><Gen2Collections>0</Gen2Collections><TotalOperations>0</TotalOperations><BytesAllocatedPerOperation /></Memory><Measurements><Measurement><IterationMode>Workload</IterationMode><IterationStage>Result</IterationStage><LaunchIndex>1</LaunchIndex><IterationIndex>1</IterationIndex><Operations>1</Operations><Nanoseconds>1</Nanoseconds></Measurement><Measurement><IterationMode>Workload</IterationMode><IterationStage>Result</IterationStage><LaunchIndex>1</LaunchIndex><IterationIndex>2</IterationIndex><Operations>1</Operations><Nanoseconds>1</Nanoseconds></Measurement><Measurement><IterationMode>Workload</IterationMode><IterationStage>Result</IterationStage><LaunchIndex>1</LaunchIndex><IterationIndex>3</IterationIndex><Operations>1</Operations><Nanoseconds>1</Nanoseconds></Measurement><Measurement><IterationMode>Workload</IterationMode><IterationStage>Result</IterationStage><LaunchIndex>1</LaunchIndex><IterationIndex>4</IterationIndex><Operations>1</Operations><Nanoseconds>1</Nanoseconds></Measurement><Measurement><IterationMode>Workload</IterationMode><IterationStage>Result</IterationStage><LaunchIndex>1</LaunchIndex><IterationIndex>5</IterationIndex><Operations>1</Operations><Nanoseconds>1</Nanoseconds></Measurement><Measurement><IterationMode>Workload</IterationMode><IterationStage>Result</IterationStage><LaunchIndex>1</LaunchIndex><IterationIndex>6</IterationIndex><Operations>1</Operations><Nanoseconds>1</Nanoseconds></Measurement></Measurements></BenchmarkCase><BenchmarkCase><DisplayInfo>MockBenchmarkClass.Bar: LongRun(IterationCount=100, LaunchCount=3, WarmupCount=15)</DisplayInfo><Namespace>BenchmarkDotNet.Tests.Mocks</Namespace><Type>MockBenchmarkClass</Type><Method>Bar</Method><MethodTitle>Bar</MethodTitle><Statistics><OriginalValues><Item>1</Item><Item>1</Item><Item>1</Item><Item>1</Item><Item>1</Item><Item>1</Item></OriginalValues><N>6</N><Min>1</Min><LowerFence>1</LowerFence><Q1>1</Q1><Median>1</Median><Mean>1</Mean><Q3>1</Q3><UpperFence>1</UpperFence><Max>1</Max><InterquartileRange>0</InterquartileRange><StandardError>0</StandardError><Variance>0</Variance><StandardDeviation>0</StandardDeviation><Skewness>NaN</Skewness><Kurtosis>NaN</Kurtosis><ConfidenceInterval><N>6</N><Mean>1</Mean><StandardError>0</StandardError><Level>L999</Level><Margin>0</Margin><Lower>1</Lower><Upper>1</Upper></ConfidenceInterval><Percentiles><P0>1</P0><P25>1</P25><P50>1</P50><P67>1</P67><P80>1</P80><P85>1</P85><P90>1</P90><P95>1</P95><P100>1</P100></Percentiles></Statistics><Metrics><Item><Value>7</Value><Descriptor><Id>CacheMisses</Id><DisplayName>CacheMisses</DisplayName><Legend>Hardware counter 'CacheMisses' per single operation</Legend><NumberFormat>N0</NumberFormat><UnitType>Dimensionless</UnitType><TheGreaterTheBetter>False</TheGreaterTheBetter><PriorityInCategory>0</PriorityInCategory></Descriptor></Item></Metrics><Memory><Gen0Collections>0</Gen0Collections><Gen1Collections>0</Gen1Collections><Gen2Collections>0</Gen2Collections><TotalOperations>0</TotalOperations><BytesAllocatedPerOperation /></Memory><Measurements><Measurement><IterationMode>Workload</IterationMode><IterationStage>Result</IterationStage><LaunchIndex>1</LaunchIndex><IterationIndex>1</IterationIndex><Operations>1</Operations><Nanoseconds>1</Nanoseconds></Measurement><Measurement><IterationMode>Workload</IterationMode><IterationStage>Result</IterationStage><LaunchIndex>1</LaunchIndex><IterationIndex>2</IterationIndex><Operations>1</Operations><Nanoseconds>1</Nanoseconds></Measurement><Measurement><IterationMode>Workload</IterationMode><IterationStage>Result</IterationStage><LaunchIndex>1</LaunchIndex><IterationIndex>3</IterationIndex><Operations>1</Operations><Nanoseconds>1</Nanoseconds></Measurement><Measurement><IterationMode>Workload</IterationMode><IterationStage>Result</IterationStage><LaunchIndex>1</LaunchIndex><IterationIndex>4</IterationIndex><Operations>1</Operations><Nanoseconds>1</Nanoseconds></Measurement><Measurement><IterationMode>Workload</IterationMode><IterationStage>Result</IterationStage><LaunchIndex>1</LaunchIndex><IterationIndex>5</IterationIndex><Operations>1</Operations><Nanoseconds>1</Nanoseconds></Measurement><Measurement><IterationMode>Workload</IterationMode><IterationStage>Result</IterationStage><LaunchIndex>1</LaunchIndex><IterationIndex>6</IterationIndex><Operations>1</Operations><Nanoseconds>1</Nanoseconds></Measurement></Measurements></BenchmarkCase></Benchmarks></Summary>\n"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Exporters/VerifiedFiles/CommonExporterVerifyTests.Exporters_ru-RU.verified.txt",
    "content": "﻿############################################\nAsciiDocExporter\n############################################\n....\nBenchmarkDotNet v0.10.x-mock, Microsoft Windows NT 10.0.x.mock (Hyper-V)\nMockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\nFrequency: 2531248 Hz, Resolution: 395.062 ns, Timer: TSC\n.NET Core SDK 1.0.x.mock\n  [Host] : Clr 4.0.x.mock, 64mock RyuJIT-v4.6.x.mock CONFIGURATION\n\nJob=LongRun  IterationCount=100  LaunchCount=3  \nWarmupCount=15  \n....\n[options=\"header\"]\n|===\n|Method  |Mean      |Error     |StdDev    |P67       |CacheMisses  \n|Foo     |  1.000 ns|  0.000 ns|  0.000 ns|  1.000 ns|            7\n|Bar     |  1.000 ns|  0.000 ns|  0.000 ns|  1.000 ns|            7\n|===\n############################################\nHtmlExporter\n############################################\n<!DOCTYPE html>\n<html lang='en'>\n<head>\n<meta charset='utf-8' />\n<title>MockSummary</title>\n\n<style type=\"text/css\">\n\ttable { border-collapse: collapse; display: block; width: 100%; overflow: auto; }\n\ttd, th { padding: 6px 13px; border: 1px solid #ddd; text-align: right; }\n\ttr { background-color: #fff; border-top: 1px solid #ccc; }\n\ttr:nth-child(even) { background: #f8f8f8; }\n</style>\n</head>\n<body>\n<pre><code>\nBenchmarkDotNet v0.10.x-mock, Microsoft Windows NT 10.0.x.mock (Hyper-V)\nMockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\nFrequency: 2531248 Hz, Resolution: 395.062 ns, Timer: TSC\n.NET Core SDK 1.0.x.mock\n  [Host] : Clr 4.0.x.mock, 64mock RyuJIT-v4.6.x.mock CONFIGURATION\n</code></pre>\n<pre><code>Job=LongRun  IterationCount=100  LaunchCount=3  \nWarmupCount=15  \n</code></pre>\n\n<table>\n<thead><tr><th>Method</th><th>Mean</th><th>Error</th><th>StdDev</th><th>P67</th><th>CacheMisses</th>\n</tr>\n</thead><tbody><tr><td>Foo</td><td>1.000 ns</td><td>0.000 ns</td><td>0.000 ns</td><td>1.000 ns</td><td>7</td>\n</tr><tr><td>Bar</td><td>1.000 ns</td><td>0.000 ns</td><td>0.000 ns</td><td>1.000 ns</td><td>7</td>\n</tr></tbody></table>\n</body>\n</html>\n############################################\nJsonExporter-brief\n############################################\n{\n  \"Title\": \"MockSummary\",\n  \"HostEnvironmentInfo\": {\n    \"BenchmarkDotNetCaption\": \"BenchmarkDotNet\",\n    \"BenchmarkDotNetVersion\": \"0.10.x-mock\",\n    \"OsVersion\": \"Microsoft Windows NT 10.0.x.mock\",\n    \"ProcessorName\": \"MockIntel Core i7-6700HQ CPU 2.60GHz\",\n    \"PhysicalProcessorCount\": 1,\n    \"PhysicalCoreCount\": 4,\n    \"LogicalCoreCount\": 8,\n    \"RuntimeVersion\": \"Clr 4.0.x.mock\",\n    \"Architecture\": \"64mock\",\n    \"HasAttachedDebugger\": false,\n    \"HasRyuJit\": true,\n    \"Configuration\": \"CONFIGURATION\",\n    \"DotNetCliVersion\": \"1.0.x.mock\",\n    \"ChronometerFrequency\": {\n      \"Hertz\": 2531248\n    },\n    \"HardwareTimerKind\": \"Tsc\"\n  },\n  \"Benchmarks\": [\n    {\n      \"DisplayInfo\": \"MockBenchmarkClass.Foo: LongRun(IterationCount=100, LaunchCount=3, WarmupCount=15)\",\n      \"Namespace\": \"BenchmarkDotNet.Tests.Mocks\",\n      \"Type\": \"MockBenchmarkClass\",\n      \"Method\": \"Foo\",\n      \"MethodTitle\": \"Foo\",\n      \"Parameters\": \"\",\n      \"FullName\": \"BenchmarkDotNet.Tests.Mocks.MockFactory+MockBenchmarkClass.Foo\",\n      \"HardwareIntrinsics\": \"\",\n      \"Statistics\": {\n        \"OriginalValues\": [\n          1,\n          1,\n          1,\n          1,\n          1,\n          1\n        ],\n        \"N\": 6,\n        \"Min\": 1,\n        \"LowerFence\": 1,\n        \"Q1\": 1,\n        \"Median\": 1,\n        \"Mean\": 1,\n        \"Q3\": 1,\n        \"UpperFence\": 1,\n        \"Max\": 1,\n        \"InterquartileRange\": 0,\n        \"LowerOutliers\": [],\n        \"UpperOutliers\": [],\n        \"AllOutliers\": [],\n        \"StandardError\": 0,\n        \"Variance\": 0,\n        \"StandardDeviation\": 0,\n        \"Skewness\": \"\",\n        \"Kurtosis\": \"\",\n        \"ConfidenceInterval\": {\n          \"N\": 6,\n          \"Mean\": 1,\n          \"StandardError\": 0,\n          \"Level\": 12,\n          \"Margin\": 0,\n          \"Lower\": 1,\n          \"Upper\": 1\n        },\n        \"Percentiles\": {\n          \"P0\": 1,\n          \"P25\": 1,\n          \"P50\": 1,\n          \"P67\": 1,\n          \"P80\": 1,\n          \"P85\": 1,\n          \"P90\": 1,\n          \"P95\": 1,\n          \"P100\": 1\n        }\n      },\n      \"Memory\": {\n        \"Gen0Collections\": 0,\n        \"Gen1Collections\": 0,\n        \"Gen2Collections\": 0,\n        \"TotalOperations\": 0,\n        \"BytesAllocatedPerOperation\": null\n      }\n    },\n    {\n      \"DisplayInfo\": \"MockBenchmarkClass.Bar: LongRun(IterationCount=100, LaunchCount=3, WarmupCount=15)\",\n      \"Namespace\": \"BenchmarkDotNet.Tests.Mocks\",\n      \"Type\": \"MockBenchmarkClass\",\n      \"Method\": \"Bar\",\n      \"MethodTitle\": \"Bar\",\n      \"Parameters\": \"\",\n      \"FullName\": \"BenchmarkDotNet.Tests.Mocks.MockFactory+MockBenchmarkClass.Bar\",\n      \"HardwareIntrinsics\": \"\",\n      \"Statistics\": {\n        \"OriginalValues\": [\n          1,\n          1,\n          1,\n          1,\n          1,\n          1\n        ],\n        \"N\": 6,\n        \"Min\": 1,\n        \"LowerFence\": 1,\n        \"Q1\": 1,\n        \"Median\": 1,\n        \"Mean\": 1,\n        \"Q3\": 1,\n        \"UpperFence\": 1,\n        \"Max\": 1,\n        \"InterquartileRange\": 0,\n        \"LowerOutliers\": [],\n        \"UpperOutliers\": [],\n        \"AllOutliers\": [],\n        \"StandardError\": 0,\n        \"Variance\": 0,\n        \"StandardDeviation\": 0,\n        \"Skewness\": \"\",\n        \"Kurtosis\": \"\",\n        \"ConfidenceInterval\": {\n          \"N\": 6,\n          \"Mean\": 1,\n          \"StandardError\": 0,\n          \"Level\": 12,\n          \"Margin\": 0,\n          \"Lower\": 1,\n          \"Upper\": 1\n        },\n        \"Percentiles\": {\n          \"P0\": 1,\n          \"P25\": 1,\n          \"P50\": 1,\n          \"P67\": 1,\n          \"P80\": 1,\n          \"P85\": 1,\n          \"P90\": 1,\n          \"P95\": 1,\n          \"P100\": 1\n        }\n      },\n      \"Memory\": {\n        \"Gen0Collections\": 0,\n        \"Gen1Collections\": 0,\n        \"Gen2Collections\": 0,\n        \"TotalOperations\": 0,\n        \"BytesAllocatedPerOperation\": null\n      }\n    }\n  ]\n}\n############################################\nJsonExporter-brief-compressed\n############################################\n{\"Title\":\"MockSummary\",\"HostEnvironmentInfo\":{\"BenchmarkDotNetCaption\":\"BenchmarkDotNet\",\"BenchmarkDotNetVersion\":\"0.10.x-mock\",\"OsVersion\":\"Microsoft Windows NT 10.0.x.mock\",\"ProcessorName\":\"MockIntel Core i7-6700HQ CPU 2.60GHz\",\"PhysicalProcessorCount\":1,\"PhysicalCoreCount\":4,\"LogicalCoreCount\":8,\"RuntimeVersion\":\"Clr 4.0.x.mock\",\"Architecture\":\"64mock\",\"HasAttachedDebugger\":false,\"HasRyuJit\":true,\"Configuration\":\"CONFIGURATION\",\"DotNetCliVersion\":\"1.0.x.mock\",\"ChronometerFrequency\":{\"Hertz\":2531248},\"HardwareTimerKind\":\"Tsc\"},\"Benchmarks\":[{\"DisplayInfo\":\"MockBenchmarkClass.Foo: LongRun(IterationCount=100, LaunchCount=3, WarmupCount=15)\",\"Namespace\":\"BenchmarkDotNet.Tests.Mocks\",\"Type\":\"MockBenchmarkClass\",\"Method\":\"Foo\",\"MethodTitle\":\"Foo\",\"Parameters\":\"\",\"FullName\":\"BenchmarkDotNet.Tests.Mocks.MockFactory+MockBenchmarkClass.Foo\",\"HardwareIntrinsics\":\"\",\"Statistics\":{\"OriginalValues\":[1,1,1,1,1,1],\"N\":6,\"Min\":1,\"LowerFence\":1,\"Q1\":1,\"Median\":1,\"Mean\":1,\"Q3\":1,\"UpperFence\":1,\"Max\":1,\"InterquartileRange\":0,\"LowerOutliers\":[],\"UpperOutliers\":[],\"AllOutliers\":[],\"StandardError\":0,\"Variance\":0,\"StandardDeviation\":0,\"Skewness\":\"\",\"Kurtosis\":\"\",\"ConfidenceInterval\":{\"N\":6,\"Mean\":1,\"StandardError\":0,\"Level\":12,\"Margin\":0,\"Lower\":1,\"Upper\":1},\"Percentiles\":{\"P0\":1,\"P25\":1,\"P50\":1,\"P67\":1,\"P80\":1,\"P85\":1,\"P90\":1,\"P95\":1,\"P100\":1}},\"Memory\":{\"Gen0Collections\":0,\"Gen1Collections\":0,\"Gen2Collections\":0,\"TotalOperations\":0,\"BytesAllocatedPerOperation\":null}},{\"DisplayInfo\":\"MockBenchmarkClass.Bar: LongRun(IterationCount=100, LaunchCount=3, WarmupCount=15)\",\"Namespace\":\"BenchmarkDotNet.Tests.Mocks\",\"Type\":\"MockBenchmarkClass\",\"Method\":\"Bar\",\"MethodTitle\":\"Bar\",\"Parameters\":\"\",\"FullName\":\"BenchmarkDotNet.Tests.Mocks.MockFactory+MockBenchmarkClass.Bar\",\"HardwareIntrinsics\":\"\",\"Statistics\":{\"OriginalValues\":[1,1,1,1,1,1],\"N\":6,\"Min\":1,\"LowerFence\":1,\"Q1\":1,\"Median\":1,\"Mean\":1,\"Q3\":1,\"UpperFence\":1,\"Max\":1,\"InterquartileRange\":0,\"LowerOutliers\":[],\"UpperOutliers\":[],\"AllOutliers\":[],\"StandardError\":0,\"Variance\":0,\"StandardDeviation\":0,\"Skewness\":\"\",\"Kurtosis\":\"\",\"ConfidenceInterval\":{\"N\":6,\"Mean\":1,\"StandardError\":0,\"Level\":12,\"Margin\":0,\"Lower\":1,\"Upper\":1},\"Percentiles\":{\"P0\":1,\"P25\":1,\"P50\":1,\"P67\":1,\"P80\":1,\"P85\":1,\"P90\":1,\"P95\":1,\"P100\":1}},\"Memory\":{\"Gen0Collections\":0,\"Gen1Collections\":0,\"Gen2Collections\":0,\"TotalOperations\":0,\"BytesAllocatedPerOperation\":null}}]}\n############################################\nJsonExporter-full\n############################################\n{\n  \"Title\": \"MockSummary\",\n  \"HostEnvironmentInfo\": {\n    \"BenchmarkDotNetCaption\": \"BenchmarkDotNet\",\n    \"BenchmarkDotNetVersion\": \"0.10.x-mock\",\n    \"OsVersion\": \"Microsoft Windows NT 10.0.x.mock\",\n    \"ProcessorName\": \"MockIntel Core i7-6700HQ CPU 2.60GHz\",\n    \"PhysicalProcessorCount\": 1,\n    \"PhysicalCoreCount\": 4,\n    \"LogicalCoreCount\": 8,\n    \"RuntimeVersion\": \"Clr 4.0.x.mock\",\n    \"Architecture\": \"64mock\",\n    \"HasAttachedDebugger\": false,\n    \"HasRyuJit\": true,\n    \"Configuration\": \"CONFIGURATION\",\n    \"DotNetCliVersion\": \"1.0.x.mock\",\n    \"ChronometerFrequency\": {\n      \"Hertz\": 2531248\n    },\n    \"HardwareTimerKind\": \"Tsc\"\n  },\n  \"Benchmarks\": [\n    {\n      \"DisplayInfo\": \"MockBenchmarkClass.Foo: LongRun(IterationCount=100, LaunchCount=3, WarmupCount=15)\",\n      \"Namespace\": \"BenchmarkDotNet.Tests.Mocks\",\n      \"Type\": \"MockBenchmarkClass\",\n      \"Method\": \"Foo\",\n      \"MethodTitle\": \"Foo\",\n      \"Parameters\": \"\",\n      \"FullName\": \"BenchmarkDotNet.Tests.Mocks.MockFactory+MockBenchmarkClass.Foo\",\n      \"HardwareIntrinsics\": \"\",\n      \"Statistics\": {\n        \"OriginalValues\": [\n          1,\n          1,\n          1,\n          1,\n          1,\n          1\n        ],\n        \"N\": 6,\n        \"Min\": 1,\n        \"LowerFence\": 1,\n        \"Q1\": 1,\n        \"Median\": 1,\n        \"Mean\": 1,\n        \"Q3\": 1,\n        \"UpperFence\": 1,\n        \"Max\": 1,\n        \"InterquartileRange\": 0,\n        \"LowerOutliers\": [],\n        \"UpperOutliers\": [],\n        \"AllOutliers\": [],\n        \"StandardError\": 0,\n        \"Variance\": 0,\n        \"StandardDeviation\": 0,\n        \"Skewness\": \"\",\n        \"Kurtosis\": \"\",\n        \"ConfidenceInterval\": {\n          \"N\": 6,\n          \"Mean\": 1,\n          \"StandardError\": 0,\n          \"Level\": 12,\n          \"Margin\": 0,\n          \"Lower\": 1,\n          \"Upper\": 1\n        },\n        \"Percentiles\": {\n          \"P0\": 1,\n          \"P25\": 1,\n          \"P50\": 1,\n          \"P67\": 1,\n          \"P80\": 1,\n          \"P85\": 1,\n          \"P90\": 1,\n          \"P95\": 1,\n          \"P100\": 1\n        }\n      },\n      \"Memory\": {\n        \"Gen0Collections\": 0,\n        \"Gen1Collections\": 0,\n        \"Gen2Collections\": 0,\n        \"TotalOperations\": 0,\n        \"BytesAllocatedPerOperation\": null\n      },\n      \"Measurements\": [\n        {\n          \"IterationMode\": \"Workload\",\n          \"IterationStage\": \"Result\",\n          \"LaunchIndex\": 1,\n          \"IterationIndex\": 1,\n          \"Operations\": 1,\n          \"Nanoseconds\": 1\n        },\n        {\n          \"IterationMode\": \"Workload\",\n          \"IterationStage\": \"Result\",\n          \"LaunchIndex\": 1,\n          \"IterationIndex\": 2,\n          \"Operations\": 1,\n          \"Nanoseconds\": 1\n        },\n        {\n          \"IterationMode\": \"Workload\",\n          \"IterationStage\": \"Result\",\n          \"LaunchIndex\": 1,\n          \"IterationIndex\": 3,\n          \"Operations\": 1,\n          \"Nanoseconds\": 1\n        },\n        {\n          \"IterationMode\": \"Workload\",\n          \"IterationStage\": \"Result\",\n          \"LaunchIndex\": 1,\n          \"IterationIndex\": 4,\n          \"Operations\": 1,\n          \"Nanoseconds\": 1\n        },\n        {\n          \"IterationMode\": \"Workload\",\n          \"IterationStage\": \"Result\",\n          \"LaunchIndex\": 1,\n          \"IterationIndex\": 5,\n          \"Operations\": 1,\n          \"Nanoseconds\": 1\n        },\n        {\n          \"IterationMode\": \"Workload\",\n          \"IterationStage\": \"Result\",\n          \"LaunchIndex\": 1,\n          \"IterationIndex\": 6,\n          \"Operations\": 1,\n          \"Nanoseconds\": 1\n        }\n      ],\n      \"Metrics\": [\n        {\n          \"Value\": 7,\n          \"Descriptor\": {\n            \"Id\": \"CacheMisses\",\n            \"DisplayName\": \"CacheMisses\",\n            \"Legend\": \"Hardware counter 'CacheMisses' per single operation\",\n            \"NumberFormat\": \"N0\",\n            \"UnitType\": 0,\n            \"Unit\": \"\",\n            \"TheGreaterTheBetter\": false,\n            \"PriorityInCategory\": 0\n          }\n        }\n      ]\n    },\n    {\n      \"DisplayInfo\": \"MockBenchmarkClass.Bar: LongRun(IterationCount=100, LaunchCount=3, WarmupCount=15)\",\n      \"Namespace\": \"BenchmarkDotNet.Tests.Mocks\",\n      \"Type\": \"MockBenchmarkClass\",\n      \"Method\": \"Bar\",\n      \"MethodTitle\": \"Bar\",\n      \"Parameters\": \"\",\n      \"FullName\": \"BenchmarkDotNet.Tests.Mocks.MockFactory+MockBenchmarkClass.Bar\",\n      \"HardwareIntrinsics\": \"\",\n      \"Statistics\": {\n        \"OriginalValues\": [\n          1,\n          1,\n          1,\n          1,\n          1,\n          1\n        ],\n        \"N\": 6,\n        \"Min\": 1,\n        \"LowerFence\": 1,\n        \"Q1\": 1,\n        \"Median\": 1,\n        \"Mean\": 1,\n        \"Q3\": 1,\n        \"UpperFence\": 1,\n        \"Max\": 1,\n        \"InterquartileRange\": 0,\n        \"LowerOutliers\": [],\n        \"UpperOutliers\": [],\n        \"AllOutliers\": [],\n        \"StandardError\": 0,\n        \"Variance\": 0,\n        \"StandardDeviation\": 0,\n        \"Skewness\": \"\",\n        \"Kurtosis\": \"\",\n        \"ConfidenceInterval\": {\n          \"N\": 6,\n          \"Mean\": 1,\n          \"StandardError\": 0,\n          \"Level\": 12,\n          \"Margin\": 0,\n          \"Lower\": 1,\n          \"Upper\": 1\n        },\n        \"Percentiles\": {\n          \"P0\": 1,\n          \"P25\": 1,\n          \"P50\": 1,\n          \"P67\": 1,\n          \"P80\": 1,\n          \"P85\": 1,\n          \"P90\": 1,\n          \"P95\": 1,\n          \"P100\": 1\n        }\n      },\n      \"Memory\": {\n        \"Gen0Collections\": 0,\n        \"Gen1Collections\": 0,\n        \"Gen2Collections\": 0,\n        \"TotalOperations\": 0,\n        \"BytesAllocatedPerOperation\": null\n      },\n      \"Measurements\": [\n        {\n          \"IterationMode\": \"Workload\",\n          \"IterationStage\": \"Result\",\n          \"LaunchIndex\": 1,\n          \"IterationIndex\": 1,\n          \"Operations\": 1,\n          \"Nanoseconds\": 1\n        },\n        {\n          \"IterationMode\": \"Workload\",\n          \"IterationStage\": \"Result\",\n          \"LaunchIndex\": 1,\n          \"IterationIndex\": 2,\n          \"Operations\": 1,\n          \"Nanoseconds\": 1\n        },\n        {\n          \"IterationMode\": \"Workload\",\n          \"IterationStage\": \"Result\",\n          \"LaunchIndex\": 1,\n          \"IterationIndex\": 3,\n          \"Operations\": 1,\n          \"Nanoseconds\": 1\n        },\n        {\n          \"IterationMode\": \"Workload\",\n          \"IterationStage\": \"Result\",\n          \"LaunchIndex\": 1,\n          \"IterationIndex\": 4,\n          \"Operations\": 1,\n          \"Nanoseconds\": 1\n        },\n        {\n          \"IterationMode\": \"Workload\",\n          \"IterationStage\": \"Result\",\n          \"LaunchIndex\": 1,\n          \"IterationIndex\": 5,\n          \"Operations\": 1,\n          \"Nanoseconds\": 1\n        },\n        {\n          \"IterationMode\": \"Workload\",\n          \"IterationStage\": \"Result\",\n          \"LaunchIndex\": 1,\n          \"IterationIndex\": 6,\n          \"Operations\": 1,\n          \"Nanoseconds\": 1\n        }\n      ],\n      \"Metrics\": [\n        {\n          \"Value\": 7,\n          \"Descriptor\": {\n            \"Id\": \"CacheMisses\",\n            \"DisplayName\": \"CacheMisses\",\n            \"Legend\": \"Hardware counter 'CacheMisses' per single operation\",\n            \"NumberFormat\": \"N0\",\n            \"UnitType\": 0,\n            \"Unit\": \"\",\n            \"TheGreaterTheBetter\": false,\n            \"PriorityInCategory\": 0\n          }\n        }\n      ]\n    }\n  ]\n}\n############################################\nJsonExporter-full-compressed\n############################################\n{\"Title\":\"MockSummary\",\"HostEnvironmentInfo\":{\"BenchmarkDotNetCaption\":\"BenchmarkDotNet\",\"BenchmarkDotNetVersion\":\"0.10.x-mock\",\"OsVersion\":\"Microsoft Windows NT 10.0.x.mock\",\"ProcessorName\":\"MockIntel Core i7-6700HQ CPU 2.60GHz\",\"PhysicalProcessorCount\":1,\"PhysicalCoreCount\":4,\"LogicalCoreCount\":8,\"RuntimeVersion\":\"Clr 4.0.x.mock\",\"Architecture\":\"64mock\",\"HasAttachedDebugger\":false,\"HasRyuJit\":true,\"Configuration\":\"CONFIGURATION\",\"DotNetCliVersion\":\"1.0.x.mock\",\"ChronometerFrequency\":{\"Hertz\":2531248},\"HardwareTimerKind\":\"Tsc\"},\"Benchmarks\":[{\"DisplayInfo\":\"MockBenchmarkClass.Foo: LongRun(IterationCount=100, LaunchCount=3, WarmupCount=15)\",\"Namespace\":\"BenchmarkDotNet.Tests.Mocks\",\"Type\":\"MockBenchmarkClass\",\"Method\":\"Foo\",\"MethodTitle\":\"Foo\",\"Parameters\":\"\",\"FullName\":\"BenchmarkDotNet.Tests.Mocks.MockFactory+MockBenchmarkClass.Foo\",\"HardwareIntrinsics\":\"\",\"Statistics\":{\"OriginalValues\":[1,1,1,1,1,1],\"N\":6,\"Min\":1,\"LowerFence\":1,\"Q1\":1,\"Median\":1,\"Mean\":1,\"Q3\":1,\"UpperFence\":1,\"Max\":1,\"InterquartileRange\":0,\"LowerOutliers\":[],\"UpperOutliers\":[],\"AllOutliers\":[],\"StandardError\":0,\"Variance\":0,\"StandardDeviation\":0,\"Skewness\":\"\",\"Kurtosis\":\"\",\"ConfidenceInterval\":{\"N\":6,\"Mean\":1,\"StandardError\":0,\"Level\":12,\"Margin\":0,\"Lower\":1,\"Upper\":1},\"Percentiles\":{\"P0\":1,\"P25\":1,\"P50\":1,\"P67\":1,\"P80\":1,\"P85\":1,\"P90\":1,\"P95\":1,\"P100\":1}},\"Memory\":{\"Gen0Collections\":0,\"Gen1Collections\":0,\"Gen2Collections\":0,\"TotalOperations\":0,\"BytesAllocatedPerOperation\":null},\"Measurements\":[{\"IterationMode\":\"Workload\",\"IterationStage\":\"Result\",\"LaunchIndex\":1,\"IterationIndex\":1,\"Operations\":1,\"Nanoseconds\":1},{\"IterationMode\":\"Workload\",\"IterationStage\":\"Result\",\"LaunchIndex\":1,\"IterationIndex\":2,\"Operations\":1,\"Nanoseconds\":1},{\"IterationMode\":\"Workload\",\"IterationStage\":\"Result\",\"LaunchIndex\":1,\"IterationIndex\":3,\"Operations\":1,\"Nanoseconds\":1},{\"IterationMode\":\"Workload\",\"IterationStage\":\"Result\",\"LaunchIndex\":1,\"IterationIndex\":4,\"Operations\":1,\"Nanoseconds\":1},{\"IterationMode\":\"Workload\",\"IterationStage\":\"Result\",\"LaunchIndex\":1,\"IterationIndex\":5,\"Operations\":1,\"Nanoseconds\":1},{\"IterationMode\":\"Workload\",\"IterationStage\":\"Result\",\"LaunchIndex\":1,\"IterationIndex\":6,\"Operations\":1,\"Nanoseconds\":1}],\"Metrics\":[{\"Value\":7,\"Descriptor\":{\"Id\":\"CacheMisses\",\"DisplayName\":\"CacheMisses\",\"Legend\":\"Hardware counter 'CacheMisses' per single operation\",\"NumberFormat\":\"N0\",\"UnitType\":0,\"Unit\":\"\",\"TheGreaterTheBetter\":false,\"PriorityInCategory\":0}}]},{\"DisplayInfo\":\"MockBenchmarkClass.Bar: LongRun(IterationCount=100, LaunchCount=3, WarmupCount=15)\",\"Namespace\":\"BenchmarkDotNet.Tests.Mocks\",\"Type\":\"MockBenchmarkClass\",\"Method\":\"Bar\",\"MethodTitle\":\"Bar\",\"Parameters\":\"\",\"FullName\":\"BenchmarkDotNet.Tests.Mocks.MockFactory+MockBenchmarkClass.Bar\",\"HardwareIntrinsics\":\"\",\"Statistics\":{\"OriginalValues\":[1,1,1,1,1,1],\"N\":6,\"Min\":1,\"LowerFence\":1,\"Q1\":1,\"Median\":1,\"Mean\":1,\"Q3\":1,\"UpperFence\":1,\"Max\":1,\"InterquartileRange\":0,\"LowerOutliers\":[],\"UpperOutliers\":[],\"AllOutliers\":[],\"StandardError\":0,\"Variance\":0,\"StandardDeviation\":0,\"Skewness\":\"\",\"Kurtosis\":\"\",\"ConfidenceInterval\":{\"N\":6,\"Mean\":1,\"StandardError\":0,\"Level\":12,\"Margin\":0,\"Lower\":1,\"Upper\":1},\"Percentiles\":{\"P0\":1,\"P25\":1,\"P50\":1,\"P67\":1,\"P80\":1,\"P85\":1,\"P90\":1,\"P95\":1,\"P100\":1}},\"Memory\":{\"Gen0Collections\":0,\"Gen1Collections\":0,\"Gen2Collections\":0,\"TotalOperations\":0,\"BytesAllocatedPerOperation\":null},\"Measurements\":[{\"IterationMode\":\"Workload\",\"IterationStage\":\"Result\",\"LaunchIndex\":1,\"IterationIndex\":1,\"Operations\":1,\"Nanoseconds\":1},{\"IterationMode\":\"Workload\",\"IterationStage\":\"Result\",\"LaunchIndex\":1,\"IterationIndex\":2,\"Operations\":1,\"Nanoseconds\":1},{\"IterationMode\":\"Workload\",\"IterationStage\":\"Result\",\"LaunchIndex\":1,\"IterationIndex\":3,\"Operations\":1,\"Nanoseconds\":1},{\"IterationMode\":\"Workload\",\"IterationStage\":\"Result\",\"LaunchIndex\":1,\"IterationIndex\":4,\"Operations\":1,\"Nanoseconds\":1},{\"IterationMode\":\"Workload\",\"IterationStage\":\"Result\",\"LaunchIndex\":1,\"IterationIndex\":5,\"Operations\":1,\"Nanoseconds\":1},{\"IterationMode\":\"Workload\",\"IterationStage\":\"Result\",\"LaunchIndex\":1,\"IterationIndex\":6,\"Operations\":1,\"Nanoseconds\":1}],\"Metrics\":[{\"Value\":7,\"Descriptor\":{\"Id\":\"CacheMisses\",\"DisplayName\":\"CacheMisses\",\"Legend\":\"Hardware counter 'CacheMisses' per single operation\",\"NumberFormat\":\"N0\",\"UnitType\":0,\"Unit\":\"\",\"TheGreaterTheBetter\":false,\"PriorityInCategory\":0}}]}]}\n############################################\nMarkdownExporter-default\n############################################\n\nBenchmarkDotNet v0.10.x-mock, Microsoft Windows NT 10.0.x.mock (Hyper-V)\nMockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\nFrequency: 2531248 Hz, Resolution: 395.062 ns, Timer: TSC\n.NET Core SDK 1.0.x.mock\n  [Host] : Clr 4.0.x.mock, 64mock RyuJIT-v4.6.x.mock CONFIGURATION\n\nJob=LongRun  IterationCount=100  LaunchCount=3  \nWarmupCount=15  \n\n Method | Mean     | Error    | StdDev   | P67      | CacheMisses |\n------- |---------:|---------:|---------:|---------:|------------:|\n Foo    | 1.000 ns | 0.000 ns | 0.000 ns | 1.000 ns |           7 |\n Bar    | 1.000 ns | 0.000 ns | 0.000 ns | 1.000 ns |           7 |\n############################################\nMarkdownExporter-atlassian\n############################################\n{noformat}\n\nBenchmarkDotNet v0.10.x-mock, Microsoft Windows NT 10.0.x.mock (Hyper-V)\nMockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\nFrequency: 2531248 Hz, Resolution: 395.062 ns, Timer: TSC\n.NET Core SDK 1.0.x.mock\n  [Host] : Clr 4.0.x.mock, 64mock RyuJIT-v4.6.x.mock CONFIGURATION\n\nJob=LongRun  IterationCount=100  LaunchCount=3  \nWarmupCount=15  \n\n{noformat}\n||Method ||Mean     ||Error    ||StdDev   ||P67      ||CacheMisses ||\n| Foo    | 1.000 ns | 0.000 ns | 0.000 ns | 1.000 ns |           7 |\n| Bar    | 1.000 ns | 0.000 ns | 0.000 ns | 1.000 ns |           7 |\n############################################\nMarkdownExporter-console\n############################################\n\nBenchmarkDotNet v0.10.x-mock, Microsoft Windows NT 10.0.x.mock (Hyper-V)\nMockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\nFrequency: 2531248 Hz, Resolution: 395.062 ns, Timer: TSC\n.NET Core SDK 1.0.x.mock\n  [Host] : Clr 4.0.x.mock, 64mock RyuJIT-v4.6.x.mock CONFIGURATION\n\nJob=LongRun  IterationCount=100  LaunchCount=3  \nWarmupCount=15  \n\n| Method | Mean     | Error    | StdDev   | P67      | CacheMisses |\n|------- |---------:|---------:|---------:|---------:|------------:|\n| Foo    | 1.000 ns | 0.000 ns | 0.000 ns | 1.000 ns |           7 |\n| Bar    | 1.000 ns | 0.000 ns | 0.000 ns | 1.000 ns |           7 |\n############################################\nMarkdownExporter-github\n############################################\n```\n\nBenchmarkDotNet v0.10.x-mock, Microsoft Windows NT 10.0.x.mock (Hyper-V)\nMockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\nFrequency: 2531248 Hz, Resolution: 395.062 ns, Timer: TSC\n.NET Core SDK 1.0.x.mock\n  [Host] : Clr 4.0.x.mock, 64mock RyuJIT-v4.6.x.mock CONFIGURATION\n\nJob=LongRun  IterationCount=100  LaunchCount=3  \nWarmupCount=15  \n\n```\n| Method | Mean     | Error    | StdDev   | P67      | CacheMisses |\n|------- |---------:|---------:|---------:|---------:|------------:|\n| Foo    | 1.000 ns | 0.000 ns | 0.000 ns | 1.000 ns |           7 |\n| Bar    | 1.000 ns | 0.000 ns | 0.000 ns | 1.000 ns |           7 |\n############################################\nMarkdownExporter-stackoverflow\n############################################\n\n    BenchmarkDotNet v0.10.x-mock, Microsoft Windows NT 10.0.x.mock (Hyper-V)\n    MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n    Frequency: 2531248 Hz, Resolution: 395.062 ns, Timer: TSC\n    .NET Core SDK 1.0.x.mock\n      [Host] : Clr 4.0.x.mock, 64mock RyuJIT-v4.6.x.mock CONFIGURATION\n\n    Job=LongRun  IterationCount=100  LaunchCount=3  \n    WarmupCount=15  \n\n     Method | Mean     | Error    | StdDev   | P67      | CacheMisses |\n    ------- |---------:|---------:|---------:|---------:|------------:|\n     Foo    | 1.000 ns | 0.000 ns | 0.000 ns | 1.000 ns |           7 |\n     Bar    | 1.000 ns | 0.000 ns | 0.000 ns | 1.000 ns |           7 |\n############################################\nOpenMetricsExporter\n############################################\n# HELP benchmark_cachemisses Additional metric CacheMisses\n# TYPE benchmark_cachemisses gauge\nbenchmark_cachemisses{method=\"Foo\", type=\"MockBenchmarkClass\"} 7\nbenchmark_cachemisses{method=\"Bar\", type=\"MockBenchmarkClass\"} 7\n# HELP benchmark_error_nanoseconds Standard error of the mean execution time in nanoseconds.\n# TYPE benchmark_error_nanoseconds gauge\n# UNIT benchmark_error_nanoseconds nanoseconds\nbenchmark_error_nanoseconds{method=\"Foo\", type=\"MockBenchmarkClass\"} 0\nbenchmark_error_nanoseconds{method=\"Bar\", type=\"MockBenchmarkClass\"} 0\n# HELP benchmark_execution_time_nanoseconds Mean execution time in nanoseconds.\n# TYPE benchmark_execution_time_nanoseconds gauge\n# UNIT benchmark_execution_time_nanoseconds nanoseconds\nbenchmark_execution_time_nanoseconds{method=\"Foo\", type=\"MockBenchmarkClass\"} 1\nbenchmark_execution_time_nanoseconds{method=\"Bar\", type=\"MockBenchmarkClass\"} 1\n# HELP benchmark_gc_gen0_collections_total Total number of Gen 0 garbage collections during the benchmark execution.\n# TYPE benchmark_gc_gen0_collections_total counter\nbenchmark_gc_gen0_collections_total{method=\"Foo\", type=\"MockBenchmarkClass\"} 0\nbenchmark_gc_gen0_collections_total{method=\"Bar\", type=\"MockBenchmarkClass\"} 0\n# HELP benchmark_gc_gen1_collections_total Total number of Gen 1 garbage collections during the benchmark execution.\n# TYPE benchmark_gc_gen1_collections_total counter\nbenchmark_gc_gen1_collections_total{method=\"Foo\", type=\"MockBenchmarkClass\"} 0\nbenchmark_gc_gen1_collections_total{method=\"Bar\", type=\"MockBenchmarkClass\"} 0\n# HELP benchmark_gc_gen2_collections_total Total number of Gen 2 garbage collections during the benchmark execution.\n# TYPE benchmark_gc_gen2_collections_total counter\nbenchmark_gc_gen2_collections_total{method=\"Foo\", type=\"MockBenchmarkClass\"} 0\nbenchmark_gc_gen2_collections_total{method=\"Bar\", type=\"MockBenchmarkClass\"} 0\n# HELP benchmark_gc_total_operations_total Total number of garbage collection operations during the benchmark execution.\n# TYPE benchmark_gc_total_operations_total counter\nbenchmark_gc_total_operations_total{method=\"Foo\", type=\"MockBenchmarkClass\"} 0\nbenchmark_gc_total_operations_total{method=\"Bar\", type=\"MockBenchmarkClass\"} 0\n# HELP benchmark_p90_nanoseconds 90th percentile execution time in nanoseconds.\n# TYPE benchmark_p90_nanoseconds gauge\n# UNIT benchmark_p90_nanoseconds nanoseconds\nbenchmark_p90_nanoseconds{method=\"Foo\", type=\"MockBenchmarkClass\"} 1\nbenchmark_p90_nanoseconds{method=\"Bar\", type=\"MockBenchmarkClass\"} 1\n# HELP benchmark_p95_nanoseconds 95th percentile execution time in nanoseconds.\n# TYPE benchmark_p95_nanoseconds gauge\n# UNIT benchmark_p95_nanoseconds nanoseconds\nbenchmark_p95_nanoseconds{method=\"Foo\", type=\"MockBenchmarkClass\"} 1\nbenchmark_p95_nanoseconds{method=\"Bar\", type=\"MockBenchmarkClass\"} 1\n# HELP benchmark_stddev_nanoseconds Standard deviation of execution time in nanoseconds.\n# TYPE benchmark_stddev_nanoseconds gauge\n# UNIT benchmark_stddev_nanoseconds nanoseconds\nbenchmark_stddev_nanoseconds{method=\"Foo\", type=\"MockBenchmarkClass\"} 0\nbenchmark_stddev_nanoseconds{method=\"Bar\", type=\"MockBenchmarkClass\"} 0\n# EOF\n############################################\nPlainExporter\n############################################\n*** MockBenchmarkClass.Foo: LongRun(IterationCount=100, LaunchCount=3, WarmupCount=15) ***\n* Raw *\nWorkloadResult   1: 1 op, 1.00 ns, 1.0000 ns/op\nWorkloadResult   2: 1 op, 1.00 ns, 1.0000 ns/op\nWorkloadResult   3: 1 op, 1.00 ns, 1.0000 ns/op\nWorkloadResult   4: 1 op, 1.00 ns, 1.0000 ns/op\nWorkloadResult   5: 1 op, 1.00 ns, 1.0000 ns/op\nWorkloadResult   6: 1 op, 1.00 ns, 1.0000 ns/op\n\n* Statistics for WorkloadResult\nMean = 1.000 ns, StdErr = 0.000 ns (0.00%), N = 6, StdDev = 0.000 ns\nMin = 1.000 ns, Q1 = 1.000 ns, Median = 1.000 ns, Q3 = 1.000 ns, Max = 1.000 ns\nIQR = 0.000 ns, LowerFence = 1.000 ns, UpperFence = 1.000 ns\nConfidenceInterval = [1.000 ns; 1.000 ns] (CI 99.9%), Margin = 0.000 ns (0.00% of Mean)\nSkewness = NaN, Kurtosis = NaN, MValue = 2\n-------------------- Histogram --------------------\n[0.500 ns ; 1.500 ns) | @@@@@@\n---------------------------------------------------\n*** MockBenchmarkClass.Bar: LongRun(IterationCount=100, LaunchCount=3, WarmupCount=15) ***\n* Raw *\nWorkloadResult   1: 1 op, 1.00 ns, 1.0000 ns/op\nWorkloadResult   2: 1 op, 1.00 ns, 1.0000 ns/op\nWorkloadResult   3: 1 op, 1.00 ns, 1.0000 ns/op\nWorkloadResult   4: 1 op, 1.00 ns, 1.0000 ns/op\nWorkloadResult   5: 1 op, 1.00 ns, 1.0000 ns/op\nWorkloadResult   6: 1 op, 1.00 ns, 1.0000 ns/op\n\n* Statistics for WorkloadResult\nMean = 1.000 ns, StdErr = 0.000 ns (0.00%), N = 6, StdDev = 0.000 ns\nMin = 1.000 ns, Q1 = 1.000 ns, Median = 1.000 ns, Q3 = 1.000 ns, Max = 1.000 ns\nIQR = 0.000 ns, LowerFence = 1.000 ns, UpperFence = 1.000 ns\nConfidenceInterval = [1.000 ns; 1.000 ns] (CI 99.9%), Margin = 0.000 ns (0.00% of Mean)\nSkewness = NaN, Kurtosis = NaN, MValue = 2\n-------------------- Histogram --------------------\n[0.500 ns ; 1.500 ns) | @@@@@@\n---------------------------------------------------\n############################################\nXmlExporter-brief\n############################################\n<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Summary>\n  <Title>MockSummary</Title>\n  <HostEnvironmentInfo>\n    <BenchmarkDotNetCaption>BenchmarkDotNet</BenchmarkDotNetCaption>\n    <BenchmarkDotNetVersion>0.10.x-mock</BenchmarkDotNetVersion>\n    <OsVersion>Microsoft Windows NT 10.0.x.mock</OsVersion>\n    <ProcessorName>MockIntel Core i7-6700HQ CPU 2.60GHz</ProcessorName>\n    <PhysicalProcessorCount>1</PhysicalProcessorCount>\n    <PhysicalCoreCount>4</PhysicalCoreCount>\n    <LogicalCoreCount>8</LogicalCoreCount>\n    <RuntimeVersion>Clr 4.0.x.mock</RuntimeVersion>\n    <Architecture>64mock</Architecture>\n    <HasAttachedDebugger>False</HasAttachedDebugger>\n    <HasRyuJit>True</HasRyuJit>\n    <Configuration>CONFIGURATION</Configuration>\n    <DotNetSdkVersion>1.0.x.mock</DotNetSdkVersion>\n    <ChronometerFrequency>\n      <Hertz>2531248</Hertz>\n    </ChronometerFrequency>\n    <HardwareTimerKind>Tsc</HardwareTimerKind>\n  </HostEnvironmentInfo>\n  <Benchmarks>\n    <BenchmarkCase>\n      <DisplayInfo>MockBenchmarkClass.Foo: LongRun(IterationCount=100, LaunchCount=3, WarmupCount=15)</DisplayInfo>\n      <Namespace>BenchmarkDotNet.Tests.Mocks</Namespace>\n      <Type>MockBenchmarkClass</Type>\n      <Method>Foo</Method>\n      <MethodTitle>Foo</MethodTitle>\n      <Statistics>\n        <OriginalValues>\n          <Item>1</Item>\n          <Item>1</Item>\n          <Item>1</Item>\n          <Item>1</Item>\n          <Item>1</Item>\n          <Item>1</Item>\n        </OriginalValues>\n        <N>6</N>\n        <Min>1</Min>\n        <LowerFence>1</LowerFence>\n        <Q1>1</Q1>\n        <Median>1</Median>\n        <Mean>1</Mean>\n        <Q3>1</Q3>\n        <UpperFence>1</UpperFence>\n        <Max>1</Max>\n        <InterquartileRange>0</InterquartileRange>\n        <StandardError>0</StandardError>\n        <Variance>0</Variance>\n        <StandardDeviation>0</StandardDeviation>\n        <Skewness>NaN</Skewness>\n        <Kurtosis>NaN</Kurtosis>\n        <ConfidenceInterval>\n          <N>6</N>\n          <Mean>1</Mean>\n          <StandardError>0</StandardError>\n          <Level>L999</Level>\n          <Margin>0</Margin>\n          <Lower>1</Lower>\n          <Upper>1</Upper>\n        </ConfidenceInterval>\n        <Percentiles>\n          <P0>1</P0>\n          <P25>1</P25>\n          <P50>1</P50>\n          <P67>1</P67>\n          <P80>1</P80>\n          <P85>1</P85>\n          <P90>1</P90>\n          <P95>1</P95>\n          <P100>1</P100>\n        </Percentiles>\n      </Statistics>\n      <Metrics>\n        <Item>\n          <Value>7</Value>\n          <Descriptor>\n            <Id>CacheMisses</Id>\n            <DisplayName>CacheMisses</DisplayName>\n            <Legend>Hardware counter 'CacheMisses' per single operation</Legend>\n            <NumberFormat>N0</NumberFormat>\n            <UnitType>Dimensionless</UnitType>\n            <TheGreaterTheBetter>False</TheGreaterTheBetter>\n            <PriorityInCategory>0</PriorityInCategory>\n          </Descriptor>\n        </Item>\n      </Metrics>\n      <Memory>\n        <Gen0Collections>0</Gen0Collections>\n        <Gen1Collections>0</Gen1Collections>\n        <Gen2Collections>0</Gen2Collections>\n        <TotalOperations>0</TotalOperations>\n        <BytesAllocatedPerOperation />\n      </Memory>\n    </BenchmarkCase>\n    <BenchmarkCase>\n      <DisplayInfo>MockBenchmarkClass.Bar: LongRun(IterationCount=100, LaunchCount=3, WarmupCount=15)</DisplayInfo>\n      <Namespace>BenchmarkDotNet.Tests.Mocks</Namespace>\n      <Type>MockBenchmarkClass</Type>\n      <Method>Bar</Method>\n      <MethodTitle>Bar</MethodTitle>\n      <Statistics>\n        <OriginalValues>\n          <Item>1</Item>\n          <Item>1</Item>\n          <Item>1</Item>\n          <Item>1</Item>\n          <Item>1</Item>\n          <Item>1</Item>\n        </OriginalValues>\n        <N>6</N>\n        <Min>1</Min>\n        <LowerFence>1</LowerFence>\n        <Q1>1</Q1>\n        <Median>1</Median>\n        <Mean>1</Mean>\n        <Q3>1</Q3>\n        <UpperFence>1</UpperFence>\n        <Max>1</Max>\n        <InterquartileRange>0</InterquartileRange>\n        <StandardError>0</StandardError>\n        <Variance>0</Variance>\n        <StandardDeviation>0</StandardDeviation>\n        <Skewness>NaN</Skewness>\n        <Kurtosis>NaN</Kurtosis>\n        <ConfidenceInterval>\n          <N>6</N>\n          <Mean>1</Mean>\n          <StandardError>0</StandardError>\n          <Level>L999</Level>\n          <Margin>0</Margin>\n          <Lower>1</Lower>\n          <Upper>1</Upper>\n        </ConfidenceInterval>\n        <Percentiles>\n          <P0>1</P0>\n          <P25>1</P25>\n          <P50>1</P50>\n          <P67>1</P67>\n          <P80>1</P80>\n          <P85>1</P85>\n          <P90>1</P90>\n          <P95>1</P95>\n          <P100>1</P100>\n        </Percentiles>\n      </Statistics>\n      <Metrics>\n        <Item>\n          <Value>7</Value>\n          <Descriptor>\n            <Id>CacheMisses</Id>\n            <DisplayName>CacheMisses</DisplayName>\n            <Legend>Hardware counter 'CacheMisses' per single operation</Legend>\n            <NumberFormat>N0</NumberFormat>\n            <UnitType>Dimensionless</UnitType>\n            <TheGreaterTheBetter>False</TheGreaterTheBetter>\n            <PriorityInCategory>0</PriorityInCategory>\n          </Descriptor>\n        </Item>\n      </Metrics>\n      <Memory>\n        <Gen0Collections>0</Gen0Collections>\n        <Gen1Collections>0</Gen1Collections>\n        <Gen2Collections>0</Gen2Collections>\n        <TotalOperations>0</TotalOperations>\n        <BytesAllocatedPerOperation />\n      </Memory>\n    </BenchmarkCase>\n  </Benchmarks>\n</Summary>\n############################################\nXmlExporter-brief-compressed\n############################################\n<?xml version=\"1.0\" encoding=\"utf-8\"?><Summary><Title>MockSummary</Title><HostEnvironmentInfo><BenchmarkDotNetCaption>BenchmarkDotNet</BenchmarkDotNetCaption><BenchmarkDotNetVersion>0.10.x-mock</BenchmarkDotNetVersion><OsVersion>Microsoft Windows NT 10.0.x.mock</OsVersion><ProcessorName>MockIntel Core i7-6700HQ CPU 2.60GHz</ProcessorName><PhysicalProcessorCount>1</PhysicalProcessorCount><PhysicalCoreCount>4</PhysicalCoreCount><LogicalCoreCount>8</LogicalCoreCount><RuntimeVersion>Clr 4.0.x.mock</RuntimeVersion><Architecture>64mock</Architecture><HasAttachedDebugger>False</HasAttachedDebugger><HasRyuJit>True</HasRyuJit><Configuration>CONFIGURATION</Configuration><DotNetSdkVersion>1.0.x.mock</DotNetSdkVersion><ChronometerFrequency><Hertz>2531248</Hertz></ChronometerFrequency><HardwareTimerKind>Tsc</HardwareTimerKind></HostEnvironmentInfo><Benchmarks><BenchmarkCase><DisplayInfo>MockBenchmarkClass.Foo: LongRun(IterationCount=100, LaunchCount=3, WarmupCount=15)</DisplayInfo><Namespace>BenchmarkDotNet.Tests.Mocks</Namespace><Type>MockBenchmarkClass</Type><Method>Foo</Method><MethodTitle>Foo</MethodTitle><Statistics><OriginalValues><Item>1</Item><Item>1</Item><Item>1</Item><Item>1</Item><Item>1</Item><Item>1</Item></OriginalValues><N>6</N><Min>1</Min><LowerFence>1</LowerFence><Q1>1</Q1><Median>1</Median><Mean>1</Mean><Q3>1</Q3><UpperFence>1</UpperFence><Max>1</Max><InterquartileRange>0</InterquartileRange><StandardError>0</StandardError><Variance>0</Variance><StandardDeviation>0</StandardDeviation><Skewness>NaN</Skewness><Kurtosis>NaN</Kurtosis><ConfidenceInterval><N>6</N><Mean>1</Mean><StandardError>0</StandardError><Level>L999</Level><Margin>0</Margin><Lower>1</Lower><Upper>1</Upper></ConfidenceInterval><Percentiles><P0>1</P0><P25>1</P25><P50>1</P50><P67>1</P67><P80>1</P80><P85>1</P85><P90>1</P90><P95>1</P95><P100>1</P100></Percentiles></Statistics><Metrics><Item><Value>7</Value><Descriptor><Id>CacheMisses</Id><DisplayName>CacheMisses</DisplayName><Legend>Hardware counter 'CacheMisses' per single operation</Legend><NumberFormat>N0</NumberFormat><UnitType>Dimensionless</UnitType><TheGreaterTheBetter>False</TheGreaterTheBetter><PriorityInCategory>0</PriorityInCategory></Descriptor></Item></Metrics><Memory><Gen0Collections>0</Gen0Collections><Gen1Collections>0</Gen1Collections><Gen2Collections>0</Gen2Collections><TotalOperations>0</TotalOperations><BytesAllocatedPerOperation /></Memory></BenchmarkCase><BenchmarkCase><DisplayInfo>MockBenchmarkClass.Bar: LongRun(IterationCount=100, LaunchCount=3, WarmupCount=15)</DisplayInfo><Namespace>BenchmarkDotNet.Tests.Mocks</Namespace><Type>MockBenchmarkClass</Type><Method>Bar</Method><MethodTitle>Bar</MethodTitle><Statistics><OriginalValues><Item>1</Item><Item>1</Item><Item>1</Item><Item>1</Item><Item>1</Item><Item>1</Item></OriginalValues><N>6</N><Min>1</Min><LowerFence>1</LowerFence><Q1>1</Q1><Median>1</Median><Mean>1</Mean><Q3>1</Q3><UpperFence>1</UpperFence><Max>1</Max><InterquartileRange>0</InterquartileRange><StandardError>0</StandardError><Variance>0</Variance><StandardDeviation>0</StandardDeviation><Skewness>NaN</Skewness><Kurtosis>NaN</Kurtosis><ConfidenceInterval><N>6</N><Mean>1</Mean><StandardError>0</StandardError><Level>L999</Level><Margin>0</Margin><Lower>1</Lower><Upper>1</Upper></ConfidenceInterval><Percentiles><P0>1</P0><P25>1</P25><P50>1</P50><P67>1</P67><P80>1</P80><P85>1</P85><P90>1</P90><P95>1</P95><P100>1</P100></Percentiles></Statistics><Metrics><Item><Value>7</Value><Descriptor><Id>CacheMisses</Id><DisplayName>CacheMisses</DisplayName><Legend>Hardware counter 'CacheMisses' per single operation</Legend><NumberFormat>N0</NumberFormat><UnitType>Dimensionless</UnitType><TheGreaterTheBetter>False</TheGreaterTheBetter><PriorityInCategory>0</PriorityInCategory></Descriptor></Item></Metrics><Memory><Gen0Collections>0</Gen0Collections><Gen1Collections>0</Gen1Collections><Gen2Collections>0</Gen2Collections><TotalOperations>0</TotalOperations><BytesAllocatedPerOperation /></Memory></BenchmarkCase></Benchmarks></Summary>\n############################################\nXmlExporter-full\n############################################\n<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Summary>\n  <Title>MockSummary</Title>\n  <HostEnvironmentInfo>\n    <BenchmarkDotNetCaption>BenchmarkDotNet</BenchmarkDotNetCaption>\n    <BenchmarkDotNetVersion>0.10.x-mock</BenchmarkDotNetVersion>\n    <OsVersion>Microsoft Windows NT 10.0.x.mock</OsVersion>\n    <ProcessorName>MockIntel Core i7-6700HQ CPU 2.60GHz</ProcessorName>\n    <PhysicalProcessorCount>1</PhysicalProcessorCount>\n    <PhysicalCoreCount>4</PhysicalCoreCount>\n    <LogicalCoreCount>8</LogicalCoreCount>\n    <RuntimeVersion>Clr 4.0.x.mock</RuntimeVersion>\n    <Architecture>64mock</Architecture>\n    <HasAttachedDebugger>False</HasAttachedDebugger>\n    <HasRyuJit>True</HasRyuJit>\n    <Configuration>CONFIGURATION</Configuration>\n    <DotNetSdkVersion>1.0.x.mock</DotNetSdkVersion>\n    <ChronometerFrequency>\n      <Hertz>2531248</Hertz>\n    </ChronometerFrequency>\n    <HardwareTimerKind>Tsc</HardwareTimerKind>\n  </HostEnvironmentInfo>\n  <Benchmarks>\n    <BenchmarkCase>\n      <DisplayInfo>MockBenchmarkClass.Foo: LongRun(IterationCount=100, LaunchCount=3, WarmupCount=15)</DisplayInfo>\n      <Namespace>BenchmarkDotNet.Tests.Mocks</Namespace>\n      <Type>MockBenchmarkClass</Type>\n      <Method>Foo</Method>\n      <MethodTitle>Foo</MethodTitle>\n      <Statistics>\n        <OriginalValues>\n          <Item>1</Item>\n          <Item>1</Item>\n          <Item>1</Item>\n          <Item>1</Item>\n          <Item>1</Item>\n          <Item>1</Item>\n        </OriginalValues>\n        <N>6</N>\n        <Min>1</Min>\n        <LowerFence>1</LowerFence>\n        <Q1>1</Q1>\n        <Median>1</Median>\n        <Mean>1</Mean>\n        <Q3>1</Q3>\n        <UpperFence>1</UpperFence>\n        <Max>1</Max>\n        <InterquartileRange>0</InterquartileRange>\n        <StandardError>0</StandardError>\n        <Variance>0</Variance>\n        <StandardDeviation>0</StandardDeviation>\n        <Skewness>NaN</Skewness>\n        <Kurtosis>NaN</Kurtosis>\n        <ConfidenceInterval>\n          <N>6</N>\n          <Mean>1</Mean>\n          <StandardError>0</StandardError>\n          <Level>L999</Level>\n          <Margin>0</Margin>\n          <Lower>1</Lower>\n          <Upper>1</Upper>\n        </ConfidenceInterval>\n        <Percentiles>\n          <P0>1</P0>\n          <P25>1</P25>\n          <P50>1</P50>\n          <P67>1</P67>\n          <P80>1</P80>\n          <P85>1</P85>\n          <P90>1</P90>\n          <P95>1</P95>\n          <P100>1</P100>\n        </Percentiles>\n      </Statistics>\n      <Metrics>\n        <Item>\n          <Value>7</Value>\n          <Descriptor>\n            <Id>CacheMisses</Id>\n            <DisplayName>CacheMisses</DisplayName>\n            <Legend>Hardware counter 'CacheMisses' per single operation</Legend>\n            <NumberFormat>N0</NumberFormat>\n            <UnitType>Dimensionless</UnitType>\n            <TheGreaterTheBetter>False</TheGreaterTheBetter>\n            <PriorityInCategory>0</PriorityInCategory>\n          </Descriptor>\n        </Item>\n      </Metrics>\n      <Memory>\n        <Gen0Collections>0</Gen0Collections>\n        <Gen1Collections>0</Gen1Collections>\n        <Gen2Collections>0</Gen2Collections>\n        <TotalOperations>0</TotalOperations>\n        <BytesAllocatedPerOperation />\n      </Memory>\n      <Measurements>\n        <Measurement>\n          <IterationMode>Workload</IterationMode>\n          <IterationStage>Result</IterationStage>\n          <LaunchIndex>1</LaunchIndex>\n          <IterationIndex>1</IterationIndex>\n          <Operations>1</Operations>\n          <Nanoseconds>1</Nanoseconds>\n        </Measurement>\n        <Measurement>\n          <IterationMode>Workload</IterationMode>\n          <IterationStage>Result</IterationStage>\n          <LaunchIndex>1</LaunchIndex>\n          <IterationIndex>2</IterationIndex>\n          <Operations>1</Operations>\n          <Nanoseconds>1</Nanoseconds>\n        </Measurement>\n        <Measurement>\n          <IterationMode>Workload</IterationMode>\n          <IterationStage>Result</IterationStage>\n          <LaunchIndex>1</LaunchIndex>\n          <IterationIndex>3</IterationIndex>\n          <Operations>1</Operations>\n          <Nanoseconds>1</Nanoseconds>\n        </Measurement>\n        <Measurement>\n          <IterationMode>Workload</IterationMode>\n          <IterationStage>Result</IterationStage>\n          <LaunchIndex>1</LaunchIndex>\n          <IterationIndex>4</IterationIndex>\n          <Operations>1</Operations>\n          <Nanoseconds>1</Nanoseconds>\n        </Measurement>\n        <Measurement>\n          <IterationMode>Workload</IterationMode>\n          <IterationStage>Result</IterationStage>\n          <LaunchIndex>1</LaunchIndex>\n          <IterationIndex>5</IterationIndex>\n          <Operations>1</Operations>\n          <Nanoseconds>1</Nanoseconds>\n        </Measurement>\n        <Measurement>\n          <IterationMode>Workload</IterationMode>\n          <IterationStage>Result</IterationStage>\n          <LaunchIndex>1</LaunchIndex>\n          <IterationIndex>6</IterationIndex>\n          <Operations>1</Operations>\n          <Nanoseconds>1</Nanoseconds>\n        </Measurement>\n      </Measurements>\n    </BenchmarkCase>\n    <BenchmarkCase>\n      <DisplayInfo>MockBenchmarkClass.Bar: LongRun(IterationCount=100, LaunchCount=3, WarmupCount=15)</DisplayInfo>\n      <Namespace>BenchmarkDotNet.Tests.Mocks</Namespace>\n      <Type>MockBenchmarkClass</Type>\n      <Method>Bar</Method>\n      <MethodTitle>Bar</MethodTitle>\n      <Statistics>\n        <OriginalValues>\n          <Item>1</Item>\n          <Item>1</Item>\n          <Item>1</Item>\n          <Item>1</Item>\n          <Item>1</Item>\n          <Item>1</Item>\n        </OriginalValues>\n        <N>6</N>\n        <Min>1</Min>\n        <LowerFence>1</LowerFence>\n        <Q1>1</Q1>\n        <Median>1</Median>\n        <Mean>1</Mean>\n        <Q3>1</Q3>\n        <UpperFence>1</UpperFence>\n        <Max>1</Max>\n        <InterquartileRange>0</InterquartileRange>\n        <StandardError>0</StandardError>\n        <Variance>0</Variance>\n        <StandardDeviation>0</StandardDeviation>\n        <Skewness>NaN</Skewness>\n        <Kurtosis>NaN</Kurtosis>\n        <ConfidenceInterval>\n          <N>6</N>\n          <Mean>1</Mean>\n          <StandardError>0</StandardError>\n          <Level>L999</Level>\n          <Margin>0</Margin>\n          <Lower>1</Lower>\n          <Upper>1</Upper>\n        </ConfidenceInterval>\n        <Percentiles>\n          <P0>1</P0>\n          <P25>1</P25>\n          <P50>1</P50>\n          <P67>1</P67>\n          <P80>1</P80>\n          <P85>1</P85>\n          <P90>1</P90>\n          <P95>1</P95>\n          <P100>1</P100>\n        </Percentiles>\n      </Statistics>\n      <Metrics>\n        <Item>\n          <Value>7</Value>\n          <Descriptor>\n            <Id>CacheMisses</Id>\n            <DisplayName>CacheMisses</DisplayName>\n            <Legend>Hardware counter 'CacheMisses' per single operation</Legend>\n            <NumberFormat>N0</NumberFormat>\n            <UnitType>Dimensionless</UnitType>\n            <TheGreaterTheBetter>False</TheGreaterTheBetter>\n            <PriorityInCategory>0</PriorityInCategory>\n          </Descriptor>\n        </Item>\n      </Metrics>\n      <Memory>\n        <Gen0Collections>0</Gen0Collections>\n        <Gen1Collections>0</Gen1Collections>\n        <Gen2Collections>0</Gen2Collections>\n        <TotalOperations>0</TotalOperations>\n        <BytesAllocatedPerOperation />\n      </Memory>\n      <Measurements>\n        <Measurement>\n          <IterationMode>Workload</IterationMode>\n          <IterationStage>Result</IterationStage>\n          <LaunchIndex>1</LaunchIndex>\n          <IterationIndex>1</IterationIndex>\n          <Operations>1</Operations>\n          <Nanoseconds>1</Nanoseconds>\n        </Measurement>\n        <Measurement>\n          <IterationMode>Workload</IterationMode>\n          <IterationStage>Result</IterationStage>\n          <LaunchIndex>1</LaunchIndex>\n          <IterationIndex>2</IterationIndex>\n          <Operations>1</Operations>\n          <Nanoseconds>1</Nanoseconds>\n        </Measurement>\n        <Measurement>\n          <IterationMode>Workload</IterationMode>\n          <IterationStage>Result</IterationStage>\n          <LaunchIndex>1</LaunchIndex>\n          <IterationIndex>3</IterationIndex>\n          <Operations>1</Operations>\n          <Nanoseconds>1</Nanoseconds>\n        </Measurement>\n        <Measurement>\n          <IterationMode>Workload</IterationMode>\n          <IterationStage>Result</IterationStage>\n          <LaunchIndex>1</LaunchIndex>\n          <IterationIndex>4</IterationIndex>\n          <Operations>1</Operations>\n          <Nanoseconds>1</Nanoseconds>\n        </Measurement>\n        <Measurement>\n          <IterationMode>Workload</IterationMode>\n          <IterationStage>Result</IterationStage>\n          <LaunchIndex>1</LaunchIndex>\n          <IterationIndex>5</IterationIndex>\n          <Operations>1</Operations>\n          <Nanoseconds>1</Nanoseconds>\n        </Measurement>\n        <Measurement>\n          <IterationMode>Workload</IterationMode>\n          <IterationStage>Result</IterationStage>\n          <LaunchIndex>1</LaunchIndex>\n          <IterationIndex>6</IterationIndex>\n          <Operations>1</Operations>\n          <Nanoseconds>1</Nanoseconds>\n        </Measurement>\n      </Measurements>\n    </BenchmarkCase>\n  </Benchmarks>\n</Summary>\n############################################\nXmlExporter-full-compressed\n############################################\n<?xml version=\"1.0\" encoding=\"utf-8\"?><Summary><Title>MockSummary</Title><HostEnvironmentInfo><BenchmarkDotNetCaption>BenchmarkDotNet</BenchmarkDotNetCaption><BenchmarkDotNetVersion>0.10.x-mock</BenchmarkDotNetVersion><OsVersion>Microsoft Windows NT 10.0.x.mock</OsVersion><ProcessorName>MockIntel Core i7-6700HQ CPU 2.60GHz</ProcessorName><PhysicalProcessorCount>1</PhysicalProcessorCount><PhysicalCoreCount>4</PhysicalCoreCount><LogicalCoreCount>8</LogicalCoreCount><RuntimeVersion>Clr 4.0.x.mock</RuntimeVersion><Architecture>64mock</Architecture><HasAttachedDebugger>False</HasAttachedDebugger><HasRyuJit>True</HasRyuJit><Configuration>CONFIGURATION</Configuration><DotNetSdkVersion>1.0.x.mock</DotNetSdkVersion><ChronometerFrequency><Hertz>2531248</Hertz></ChronometerFrequency><HardwareTimerKind>Tsc</HardwareTimerKind></HostEnvironmentInfo><Benchmarks><BenchmarkCase><DisplayInfo>MockBenchmarkClass.Foo: LongRun(IterationCount=100, LaunchCount=3, WarmupCount=15)</DisplayInfo><Namespace>BenchmarkDotNet.Tests.Mocks</Namespace><Type>MockBenchmarkClass</Type><Method>Foo</Method><MethodTitle>Foo</MethodTitle><Statistics><OriginalValues><Item>1</Item><Item>1</Item><Item>1</Item><Item>1</Item><Item>1</Item><Item>1</Item></OriginalValues><N>6</N><Min>1</Min><LowerFence>1</LowerFence><Q1>1</Q1><Median>1</Median><Mean>1</Mean><Q3>1</Q3><UpperFence>1</UpperFence><Max>1</Max><InterquartileRange>0</InterquartileRange><StandardError>0</StandardError><Variance>0</Variance><StandardDeviation>0</StandardDeviation><Skewness>NaN</Skewness><Kurtosis>NaN</Kurtosis><ConfidenceInterval><N>6</N><Mean>1</Mean><StandardError>0</StandardError><Level>L999</Level><Margin>0</Margin><Lower>1</Lower><Upper>1</Upper></ConfidenceInterval><Percentiles><P0>1</P0><P25>1</P25><P50>1</P50><P67>1</P67><P80>1</P80><P85>1</P85><P90>1</P90><P95>1</P95><P100>1</P100></Percentiles></Statistics><Metrics><Item><Value>7</Value><Descriptor><Id>CacheMisses</Id><DisplayName>CacheMisses</DisplayName><Legend>Hardware counter 'CacheMisses' per single operation</Legend><NumberFormat>N0</NumberFormat><UnitType>Dimensionless</UnitType><TheGreaterTheBetter>False</TheGreaterTheBetter><PriorityInCategory>0</PriorityInCategory></Descriptor></Item></Metrics><Memory><Gen0Collections>0</Gen0Collections><Gen1Collections>0</Gen1Collections><Gen2Collections>0</Gen2Collections><TotalOperations>0</TotalOperations><BytesAllocatedPerOperation /></Memory><Measurements><Measurement><IterationMode>Workload</IterationMode><IterationStage>Result</IterationStage><LaunchIndex>1</LaunchIndex><IterationIndex>1</IterationIndex><Operations>1</Operations><Nanoseconds>1</Nanoseconds></Measurement><Measurement><IterationMode>Workload</IterationMode><IterationStage>Result</IterationStage><LaunchIndex>1</LaunchIndex><IterationIndex>2</IterationIndex><Operations>1</Operations><Nanoseconds>1</Nanoseconds></Measurement><Measurement><IterationMode>Workload</IterationMode><IterationStage>Result</IterationStage><LaunchIndex>1</LaunchIndex><IterationIndex>3</IterationIndex><Operations>1</Operations><Nanoseconds>1</Nanoseconds></Measurement><Measurement><IterationMode>Workload</IterationMode><IterationStage>Result</IterationStage><LaunchIndex>1</LaunchIndex><IterationIndex>4</IterationIndex><Operations>1</Operations><Nanoseconds>1</Nanoseconds></Measurement><Measurement><IterationMode>Workload</IterationMode><IterationStage>Result</IterationStage><LaunchIndex>1</LaunchIndex><IterationIndex>5</IterationIndex><Operations>1</Operations><Nanoseconds>1</Nanoseconds></Measurement><Measurement><IterationMode>Workload</IterationMode><IterationStage>Result</IterationStage><LaunchIndex>1</LaunchIndex><IterationIndex>6</IterationIndex><Operations>1</Operations><Nanoseconds>1</Nanoseconds></Measurement></Measurements></BenchmarkCase><BenchmarkCase><DisplayInfo>MockBenchmarkClass.Bar: LongRun(IterationCount=100, LaunchCount=3, WarmupCount=15)</DisplayInfo><Namespace>BenchmarkDotNet.Tests.Mocks</Namespace><Type>MockBenchmarkClass</Type><Method>Bar</Method><MethodTitle>Bar</MethodTitle><Statistics><OriginalValues><Item>1</Item><Item>1</Item><Item>1</Item><Item>1</Item><Item>1</Item><Item>1</Item></OriginalValues><N>6</N><Min>1</Min><LowerFence>1</LowerFence><Q1>1</Q1><Median>1</Median><Mean>1</Mean><Q3>1</Q3><UpperFence>1</UpperFence><Max>1</Max><InterquartileRange>0</InterquartileRange><StandardError>0</StandardError><Variance>0</Variance><StandardDeviation>0</StandardDeviation><Skewness>NaN</Skewness><Kurtosis>NaN</Kurtosis><ConfidenceInterval><N>6</N><Mean>1</Mean><StandardError>0</StandardError><Level>L999</Level><Margin>0</Margin><Lower>1</Lower><Upper>1</Upper></ConfidenceInterval><Percentiles><P0>1</P0><P25>1</P25><P50>1</P50><P67>1</P67><P80>1</P80><P85>1</P85><P90>1</P90><P95>1</P95><P100>1</P100></Percentiles></Statistics><Metrics><Item><Value>7</Value><Descriptor><Id>CacheMisses</Id><DisplayName>CacheMisses</DisplayName><Legend>Hardware counter 'CacheMisses' per single operation</Legend><NumberFormat>N0</NumberFormat><UnitType>Dimensionless</UnitType><TheGreaterTheBetter>False</TheGreaterTheBetter><PriorityInCategory>0</PriorityInCategory></Descriptor></Item></Metrics><Memory><Gen0Collections>0</Gen0Collections><Gen1Collections>0</Gen1Collections><Gen2Collections>0</Gen2Collections><TotalOperations>0</TotalOperations><BytesAllocatedPerOperation /></Memory><Measurements><Measurement><IterationMode>Workload</IterationMode><IterationStage>Result</IterationStage><LaunchIndex>1</LaunchIndex><IterationIndex>1</IterationIndex><Operations>1</Operations><Nanoseconds>1</Nanoseconds></Measurement><Measurement><IterationMode>Workload</IterationMode><IterationStage>Result</IterationStage><LaunchIndex>1</LaunchIndex><IterationIndex>2</IterationIndex><Operations>1</Operations><Nanoseconds>1</Nanoseconds></Measurement><Measurement><IterationMode>Workload</IterationMode><IterationStage>Result</IterationStage><LaunchIndex>1</LaunchIndex><IterationIndex>3</IterationIndex><Operations>1</Operations><Nanoseconds>1</Nanoseconds></Measurement><Measurement><IterationMode>Workload</IterationMode><IterationStage>Result</IterationStage><LaunchIndex>1</LaunchIndex><IterationIndex>4</IterationIndex><Operations>1</Operations><Nanoseconds>1</Nanoseconds></Measurement><Measurement><IterationMode>Workload</IterationMode><IterationStage>Result</IterationStage><LaunchIndex>1</LaunchIndex><IterationIndex>5</IterationIndex><Operations>1</Operations><Nanoseconds>1</Nanoseconds></Measurement><Measurement><IterationMode>Workload</IterationMode><IterationStage>Result</IterationStage><LaunchIndex>1</LaunchIndex><IterationIndex>6</IterationIndex><Operations>1</Operations><Nanoseconds>1</Nanoseconds></Measurement></Measurements></BenchmarkCase></Benchmarks></Summary>\n"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Exporters/VerifiedFiles/MarkdownExporterVerifyTests.GroupExporterTest_Escape_ParamsAndArguments.verified.txt",
    "content": "﻿=== Escape_ParamsAndArguments ===\n\nBenchmarkDotNet v0.10.x-mock, Microsoft Windows NT 10.0.x.mock (Hyper-V)\nMockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\nFrequency: 2531248 Hz, Resolution: 395.062 ns, Timer: TSC\n  [Host]     : Clr 4.0.x.mock, 64mock RyuJIT-v4.6.x.mock CONFIGURATION\n  DefaultJob : extra output line\n\n\n Method | StringParam | charArg | Mean     | Error   | StdDev  |\n------- |------------ |-------- |---------:|--------:|--------:|\n Foo    | \\t          | \\t      | 114.5 ns | 5.88 ns | 8.80 ns | ^\n Foo    | \\t          | \\n      | 214.5 ns | 5.88 ns | 8.80 ns | ^\n Bar    | \\t          | ?       | 314.5 ns | 5.88 ns | 8.80 ns | ^\n Foo    | \\n          | \\t      | 414.5 ns | 5.88 ns | 8.80 ns | ^\n Foo    | \\n          | \\n      | 514.5 ns | 5.88 ns | 8.80 ns | ^\n Bar    | \\n          | ?       | 614.5 ns | 5.88 ns | 8.80 ns | ^\n\nErrors: 0\n"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Exporters/VerifiedFiles/MarkdownExporterVerifyTests.GroupExporterTest_HideColumns_TableMarkDown.verified.txt",
    "content": "﻿=== HideColumns_TableMarkDown ===\n\nBenchmarkDotNet v0.10.x-mock, Microsoft Windows NT 10.0.x.mock (Hyper-V)\nMockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\nFrequency: 2531248 Hz, Resolution: 395.062 ns, Timer: TSC\n  [Host]     : Clr 4.0.x.mock, 64mock RyuJIT-v4.6.x.mock CONFIGURATION\n  DefaultJob : extra output line\n\nStdDev=8.80 ns  \n\n Method | Mean     | Error   | \n------- |---------:|--------:|\n Foo    | 114.5 ns | 5.88 ns | \n\nErrors: 0\n"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Exporters/VerifiedFiles/MarkdownExporterVerifyTests.GroupExporterTest_Invalid_TwoJobBaselines.verified.txt",
    "content": "﻿=== Invalid_TwoJobBaselines ===\n\nBenchmarkDotNet v0.10.x-mock, Microsoft Windows NT 10.0.x.mock (Hyper-V)\nMockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\nFrequency: 2531248 Hz, Resolution: 395.062 ns, Timer: TSC\n  [Host] : Clr 4.0.x.mock, 64mock RyuJIT-v4.6.x.mock CONFIGURATION\n  Job1   : extra output line\n  Job2   : extra output line\n\n\n Method | Job  | Mean     | Error   | StdDev  | Ratio | RatioSD | Rank | LogicalGroup                                  | Baseline |\n------- |----- |---------:|--------:|--------:|------:|--------:|-----:|---------------------------------------------- |--------- |\n Foo    | Job1 | 114.5 ns | 5.88 ns | 8.80 ns |  1.00 |    0.00 |    1 | DistinctParamSet0-Invalid_TwoJobBaselines.Foo | Yes      |\n Foo    | Job2 | 314.5 ns | 5.88 ns | 8.80 ns |  2.76 |    0.22 |    2 | DistinctParamSet0-Invalid_TwoJobBaselines.Foo | Yes      |\n        |      |          |         |         |       |         |      |                                               |          |\n Bar    | Job1 | 214.5 ns | 5.88 ns | 8.80 ns |  1.00 |    0.00 |    1 | DistinctParamSet0-Invalid_TwoJobBaselines.Bar | Yes      |\n Bar    | Job2 | 414.5 ns | 5.88 ns | 8.80 ns |  1.94 |    0.09 |    2 | DistinctParamSet0-Invalid_TwoJobBaselines.Bar | Yes      |\n\nErrors: 2\n* Only 1 job in a group can have \"Baseline = true\" applied to it, group DistinctParamSet0-Invalid_TwoJobBaselines.Foo in class Invalid_TwoJobBaselines has 2\n* Only 1 job in a group can have \"Baseline = true\" applied to it, group DistinctParamSet0-Invalid_TwoJobBaselines.Bar in class Invalid_TwoJobBaselines has 2\n"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Exporters/VerifiedFiles/MarkdownExporterVerifyTests.GroupExporterTest_Invalid_TwoMethodBaselines.verified.txt",
    "content": "﻿=== Invalid_TwoMethodBaselines ===\n\nBenchmarkDotNet v0.10.x-mock, Microsoft Windows NT 10.0.x.mock (Hyper-V)\nMockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\nFrequency: 2531248 Hz, Resolution: 395.062 ns, Timer: TSC\n  [Host]     : Clr 4.0.x.mock, 64mock RyuJIT-v4.6.x.mock CONFIGURATION\n  DefaultJob : extra output line\n\n\n Method | Mean     | Error   | StdDev  | Ratio | RatioSD | Rank | LogicalGroup                 | Baseline |\n------- |---------:|--------:|--------:|------:|--------:|-----:|----------------------------- |--------- |\n Foo    | 114.5 ns | 5.88 ns | 8.80 ns |  1.00 |    0.00 |    1 | DistinctParamSet0-DefaultJob | Yes      |\n Bar    | 214.5 ns | 5.88 ns | 8.80 ns |  1.88 |    0.16 |    2 | DistinctParamSet0-DefaultJob | Yes      |\n\nErrors: 1\n* Only 1 benchmark method in a group can have \"Baseline = true\" applied to it, group DistinctParamSet0-DefaultJob in class Invalid_TwoMethodBaselines has 2\n"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Exporters/VerifiedFiles/MarkdownExporterVerifyTests.GroupExporterTest_JobBaseline_MethodsJobs.verified.txt",
    "content": "﻿=== JobBaseline_MethodsJobs ===\n\nBenchmarkDotNet v0.10.x-mock, Microsoft Windows NT 10.0.x.mock (Hyper-V)\nMockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\nFrequency: 2531248 Hz, Resolution: 395.062 ns, Timer: TSC\n  [Host] : Clr 4.0.x.mock, 64mock RyuJIT-v4.6.x.mock CONFIGURATION\n  Job1   : extra output line\n  Job2   : extra output line\n\n\n Method | Job  | Mean     | Error   | StdDev  | Ratio | RatioSD | Rank | LogicalGroup                                   | Baseline |\n------- |----- |---------:|--------:|--------:|------:|--------:|-----:|----------------------------------------------- |--------- |\n Base   | Job1 | 114.5 ns | 5.88 ns | 8.80 ns |  1.00 |    0.00 |    1 | DistinctParamSet0-JobBaseline_MethodsJobs.Base | Yes      |\n Base   | Job2 | 414.5 ns | 5.88 ns | 8.80 ns |  3.64 |    0.29 |    2 | DistinctParamSet0-JobBaseline_MethodsJobs.Base | No       |\n        |      |          |         |         |       |         |      |                                                |          |\n Foo    | Job1 | 214.5 ns | 5.88 ns | 8.80 ns |  1.00 |    0.00 |    1 | DistinctParamSet0-JobBaseline_MethodsJobs.Foo  | Yes      |\n Foo    | Job2 | 514.5 ns | 5.88 ns | 8.80 ns |  2.40 |    0.11 |    2 | DistinctParamSet0-JobBaseline_MethodsJobs.Foo  | No       |\n        |      |          |         |         |       |         |      |                                                |          |\n Bar    | Job1 | 314.5 ns | 5.88 ns | 8.80 ns |  1.00 |    0.00 |    1 | DistinctParamSet0-JobBaseline_MethodsJobs.Bar  | Yes      |\n Bar    | Job2 | 614.5 ns | 5.88 ns | 8.80 ns |  1.96 |    0.06 |    2 | DistinctParamSet0-JobBaseline_MethodsJobs.Bar  | No       |\n\nErrors: 0\n"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Exporters/VerifiedFiles/MarkdownExporterVerifyTests.GroupExporterTest_JobBaseline_MethodsParamsJobs.verified.txt",
    "content": "﻿=== JobBaseline_MethodsParamsJobs ===\n\nBenchmarkDotNet v0.10.x-mock, Microsoft Windows NT 10.0.x.mock (Hyper-V)\nMockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\nFrequency: 2531248 Hz, Resolution: 395.062 ns, Timer: TSC\n  [Host] : Clr 4.0.x.mock, 64mock RyuJIT-v4.6.x.mock CONFIGURATION\n  Job1   : extra output line\n  Job2   : extra output line\n\n\n Method | Job  | Param | Mean       | Error   | StdDev  | Ratio | RatioSD | Rank | LogicalGroup                                         | Baseline |\n------- |----- |------ |-----------:|--------:|--------:|------:|--------:|-----:|----------------------------------------------------- |--------- |\n Base   | Job1 | 2     |   114.5 ns | 5.88 ns | 8.80 ns |  1.00 |    0.00 |    1 | DistinctParamSet0-JobBaseline_MethodsParamsJobs.Base | Yes      | ^\n Base   | Job2 | 2     |   414.5 ns | 5.88 ns | 8.80 ns |  3.64 |    0.29 |    2 | DistinctParamSet0-JobBaseline_MethodsParamsJobs.Base | No       |\n        |      |       |            |         |         |       |         |      |                                                      |          |\n Foo    | Job1 | 2     |   214.5 ns | 5.88 ns | 8.80 ns |  1.00 |    0.00 |    1 | DistinctParamSet0-JobBaseline_MethodsParamsJobs.Foo  | Yes      |\n Foo    | Job2 | 2     |   514.5 ns | 5.88 ns | 8.80 ns |  2.40 |    0.11 |    2 | DistinctParamSet0-JobBaseline_MethodsParamsJobs.Foo  | No       |\n        |      |       |            |         |         |       |         |      |                                                      |          |\n Bar    | Job1 | 2     |   314.5 ns | 5.88 ns | 8.80 ns |  1.00 |    0.00 |    1 | DistinctParamSet0-JobBaseline_MethodsParamsJobs.Bar  | Yes      |\n Bar    | Job2 | 2     |   614.5 ns | 5.88 ns | 8.80 ns |  1.96 |    0.06 |    2 | DistinctParamSet0-JobBaseline_MethodsParamsJobs.Bar  | No       |\n        |      |       |            |         |         |       |         |      |                                                      |          |\n Base   | Job1 | 10    |   714.5 ns | 5.88 ns | 8.80 ns |  1.00 |    0.00 |    1 | DistinctParamSet6-JobBaseline_MethodsParamsJobs.Base | Yes      | ^\n Base   | Job2 | 10    | 1,014.5 ns | 5.88 ns | 8.80 ns |  1.42 |    0.02 |    2 | DistinctParamSet6-JobBaseline_MethodsParamsJobs.Base | No       |\n        |      |       |            |         |         |       |         |      |                                                      |          |\n Foo    | Job1 | 10    |   814.5 ns | 5.88 ns | 8.80 ns |  1.00 |    0.00 |    1 | DistinctParamSet6-JobBaseline_MethodsParamsJobs.Foo  | Yes      |\n Foo    | Job2 | 10    | 1,114.5 ns | 5.88 ns | 8.80 ns |  1.37 |    0.02 |    2 | DistinctParamSet6-JobBaseline_MethodsParamsJobs.Foo  | No       |\n        |      |       |            |         |         |       |         |      |                                                      |          |\n Bar    | Job1 | 10    |   914.5 ns | 5.88 ns | 8.80 ns |  1.00 |    0.00 |    1 | DistinctParamSet6-JobBaseline_MethodsParamsJobs.Bar  | Yes      |\n Bar    | Job2 | 10    | 1,214.5 ns | 5.88 ns | 8.80 ns |  1.33 |    0.02 |    2 | DistinctParamSet6-JobBaseline_MethodsParamsJobs.Bar  | No       |\n\nErrors: 0\n"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Exporters/VerifiedFiles/MarkdownExporterVerifyTests.GroupExporterTest_MethodBaseline_Methods.verified.txt",
    "content": "﻿=== MethodBaseline_Methods ===\n\nBenchmarkDotNet v0.10.x-mock, Microsoft Windows NT 10.0.x.mock (Hyper-V)\nMockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\nFrequency: 2531248 Hz, Resolution: 395.062 ns, Timer: TSC\n  [Host]     : Clr 4.0.x.mock, 64mock RyuJIT-v4.6.x.mock CONFIGURATION\n  DefaultJob : extra output line\n\n\n Method | Mean     | Error   | StdDev  | Ratio | RatioSD | Rank | LogicalGroup                 | Baseline |\n------- |---------:|--------:|--------:|------:|--------:|-----:|----------------------------- |--------- |\n Base   | 114.5 ns | 5.88 ns | 8.80 ns |  1.00 |    0.00 |    1 | DistinctParamSet0-DefaultJob | Yes      |\n Foo    | 214.5 ns | 5.88 ns | 8.80 ns |  1.88 |    0.16 |    2 | DistinctParamSet0-DefaultJob | No       |\n Bar    | 314.5 ns | 5.88 ns | 8.80 ns |  2.76 |    0.22 |    3 | DistinctParamSet0-DefaultJob | No       |\n\nErrors: 0\n"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Exporters/VerifiedFiles/MarkdownExporterVerifyTests.GroupExporterTest_MethodBaseline_MethodsJobs.verified.txt",
    "content": "﻿=== MethodBaseline_MethodsJobs ===\n\nBenchmarkDotNet v0.10.x-mock, Microsoft Windows NT 10.0.x.mock (Hyper-V)\nMockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\nFrequency: 2531248 Hz, Resolution: 395.062 ns, Timer: TSC\n  [Host] : Clr 4.0.x.mock, 64mock RyuJIT-v4.6.x.mock CONFIGURATION\n  Job1   : extra output line\n  Job2   : extra output line\n\n\n Method | Job  | Mean     | Error   | StdDev  | Ratio | RatioSD | Rank | LogicalGroup           | Baseline |\n------- |----- |---------:|--------:|--------:|------:|--------:|-----:|----------------------- |--------- |\n Base   | Job1 | 114.5 ns | 5.88 ns | 8.80 ns |  1.00 |    0.00 |    1 | DistinctParamSet0-Job1 | Yes      |\n Foo    | Job1 | 214.5 ns | 5.88 ns | 8.80 ns |  1.88 |    0.16 |    2 | DistinctParamSet0-Job1 | No       |\n Bar    | Job1 | 314.5 ns | 5.88 ns | 8.80 ns |  2.76 |    0.22 |    3 | DistinctParamSet0-Job1 | No       |\n        |      |          |         |         |       |         |      |                        |          |\n Base   | Job2 | 414.5 ns | 5.88 ns | 8.80 ns |  1.00 |    0.00 |    1 | DistinctParamSet0-Job2 | Yes      |\n Foo    | Job2 | 514.5 ns | 5.88 ns | 8.80 ns |  1.24 |    0.03 |    2 | DistinctParamSet0-Job2 | No       |\n Bar    | Job2 | 614.5 ns | 5.88 ns | 8.80 ns |  1.48 |    0.04 |    3 | DistinctParamSet0-Job2 | No       |\n\nErrors: 0\n"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Exporters/VerifiedFiles/MarkdownExporterVerifyTests.GroupExporterTest_MethodBaseline_MethodsParams.verified.txt",
    "content": "﻿=== MethodBaseline_MethodsParams ===\n\nBenchmarkDotNet v0.10.x-mock, Microsoft Windows NT 10.0.x.mock (Hyper-V)\nMockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\nFrequency: 2531248 Hz, Resolution: 395.062 ns, Timer: TSC\n  [Host]     : Clr 4.0.x.mock, 64mock RyuJIT-v4.6.x.mock CONFIGURATION\n  DefaultJob : extra output line\n\n\n Method | Param | Mean     | Error   | StdDev  | Ratio | RatioSD | Rank | LogicalGroup                 | Baseline |\n------- |------ |---------:|--------:|--------:|------:|--------:|-----:|----------------------------- |--------- |\n Base   | 2     | 114.5 ns | 5.88 ns | 8.80 ns |  1.00 |    0.00 |    1 | DistinctParamSet0-DefaultJob | Yes      | ^\n Foo    | 2     | 214.5 ns | 5.88 ns | 8.80 ns |  1.88 |    0.16 |    2 | DistinctParamSet0-DefaultJob | No       |\n Bar    | 2     | 314.5 ns | 5.88 ns | 8.80 ns |  2.76 |    0.22 |    3 | DistinctParamSet0-DefaultJob | No       |\n        |       |          |         |         |       |         |      |                              |          |\n Base   | 10    | 414.5 ns | 5.88 ns | 8.80 ns |  1.00 |    0.00 |    1 | DistinctParamSet3-DefaultJob | Yes      | ^\n Foo    | 10    | 514.5 ns | 5.88 ns | 8.80 ns |  1.24 |    0.03 |    2 | DistinctParamSet3-DefaultJob | No       |\n Bar    | 10    | 614.5 ns | 5.88 ns | 8.80 ns |  1.48 |    0.04 |    3 | DistinctParamSet3-DefaultJob | No       |\n\nErrors: 0\n"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Exporters/VerifiedFiles/MarkdownExporterVerifyTests.GroupExporterTest_MethodBaseline_MethodsParamsJobs.verified.txt",
    "content": "﻿=== MethodBaseline_MethodsParamsJobs ===\n\nBenchmarkDotNet v0.10.x-mock, Microsoft Windows NT 10.0.x.mock (Hyper-V)\nMockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\nFrequency: 2531248 Hz, Resolution: 395.062 ns, Timer: TSC\n  [Host] : Clr 4.0.x.mock, 64mock RyuJIT-v4.6.x.mock CONFIGURATION\n  Job1   : extra output line\n  Job2   : extra output line\n\n\n Method | Job  | Param | Mean       | Error   | StdDev  | Ratio | RatioSD | Rank | LogicalGroup           | Baseline |\n------- |----- |------ |-----------:|--------:|--------:|------:|--------:|-----:|----------------------- |--------- |\n Base   | Job1 | 2     |   114.5 ns | 5.88 ns | 8.80 ns |  1.00 |    0.00 |    1 | DistinctParamSet0-Job1 | Yes      | ^\n Foo    | Job1 | 2     |   214.5 ns | 5.88 ns | 8.80 ns |  1.88 |    0.16 |    2 | DistinctParamSet0-Job1 | No       |\n Bar    | Job1 | 2     |   314.5 ns | 5.88 ns | 8.80 ns |  2.76 |    0.22 |    3 | DistinctParamSet0-Job1 | No       |\n        |      |       |            |         |         |       |         |      |                        |          |\n Base   | Job2 | 2     |   414.5 ns | 5.88 ns | 8.80 ns |  1.00 |    0.00 |    1 | DistinctParamSet0-Job2 | Yes      |\n Foo    | Job2 | 2     |   514.5 ns | 5.88 ns | 8.80 ns |  1.24 |    0.03 |    2 | DistinctParamSet0-Job2 | No       |\n Bar    | Job2 | 2     |   614.5 ns | 5.88 ns | 8.80 ns |  1.48 |    0.04 |    3 | DistinctParamSet0-Job2 | No       |\n        |      |       |            |         |         |       |         |      |                        |          |\n Base   | Job1 | 10    |   714.5 ns | 5.88 ns | 8.80 ns |  1.00 |    0.00 |    1 | DistinctParamSet6-Job1 | Yes      | ^\n Foo    | Job1 | 10    |   814.5 ns | 5.88 ns | 8.80 ns |  1.14 |    0.02 |    2 | DistinctParamSet6-Job1 | No       |\n Bar    | Job1 | 10    |   914.5 ns | 5.88 ns | 8.80 ns |  1.28 |    0.02 |    3 | DistinctParamSet6-Job1 | No       |\n        |      |       |            |         |         |       |         |      |                        |          |\n Base   | Job2 | 10    | 1,014.5 ns | 5.88 ns | 8.80 ns |  1.00 |    0.00 |    1 | DistinctParamSet6-Job2 | Yes      |\n Foo    | Job2 | 10    | 1,114.5 ns | 5.88 ns | 8.80 ns |  1.10 |    0.01 |    2 | DistinctParamSet6-Job2 | No       |\n Bar    | Job2 | 10    | 1,214.5 ns | 5.88 ns | 8.80 ns |  1.20 |    0.01 |    3 | DistinctParamSet6-Job2 | No       |\n\nErrors: 0\n"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Exporters/VerifiedFiles/MarkdownExporterVerifyTests.GroupExporterTest_MethodJobBaseline_MethodsJobs.verified.txt",
    "content": "﻿=== MethodJobBaseline_MethodsJobs ===\n\nBenchmarkDotNet v0.10.x-mock, Microsoft Windows NT 10.0.x.mock (Hyper-V)\nMockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\nFrequency: 2531248 Hz, Resolution: 395.062 ns, Timer: TSC\n  [Host] : Clr 4.0.x.mock, 64mock RyuJIT-v4.6.x.mock CONFIGURATION\n  Job1   : extra output line\n  Job2   : extra output line\n\n\n Method | Job  | Mean     | Error   | StdDev  | Ratio | RatioSD | Rank | LogicalGroup      | Baseline |\n------- |----- |---------:|--------:|--------:|------:|--------:|-----:|------------------ |--------- |\n Foo    | Job1 | 114.5 ns | 5.88 ns | 8.80 ns |  1.00 |    0.00 |    1 | DistinctParamSet0 | Yes      |\n Bar    | Job1 | 214.5 ns | 5.88 ns | 8.80 ns |  1.88 |    0.16 |    2 | DistinctParamSet0 | No       |\n Foo    | Job2 | 314.5 ns | 5.88 ns | 8.80 ns |  2.76 |    0.22 |    3 | DistinctParamSet0 | No       |\n Bar    | Job2 | 414.5 ns | 5.88 ns | 8.80 ns |  3.64 |    0.29 |    4 | DistinctParamSet0 | No       |\n\nErrors: 0\n"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Exporters/VerifiedFiles/MarkdownExporterVerifyTests.GroupExporterTest_MethodJobBaseline_MethodsJobsParams.verified.txt",
    "content": "﻿=== MethodJobBaseline_MethodsJobsParams ===\n\nBenchmarkDotNet v0.10.x-mock, Microsoft Windows NT 10.0.x.mock (Hyper-V)\nMockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\nFrequency: 2531248 Hz, Resolution: 395.062 ns, Timer: TSC\n  [Host] : Clr 4.0.x.mock, 64mock RyuJIT-v4.6.x.mock CONFIGURATION\n  Job1   : extra output line\n  Job2   : extra output line\n\n\n Method | Job  | Param | Mean     | Error   | StdDev  | Ratio | RatioSD | Rank | LogicalGroup      | Baseline |\n------- |----- |------ |---------:|--------:|--------:|------:|--------:|-----:|------------------ |--------- |\n Foo    | Job1 | 2     | 114.5 ns | 5.88 ns | 8.80 ns |  1.00 |    0.00 |    1 | DistinctParamSet0 | Yes      | ^\n Bar    | Job1 | 2     | 214.5 ns | 5.88 ns | 8.80 ns |  1.88 |    0.16 |    2 | DistinctParamSet0 | No       |\n Foo    | Job2 | 2     | 314.5 ns | 5.88 ns | 8.80 ns |  2.76 |    0.22 |    3 | DistinctParamSet0 | No       |\n Bar    | Job2 | 2     | 414.5 ns | 5.88 ns | 8.80 ns |  3.64 |    0.29 |    4 | DistinctParamSet0 | No       |\n        |      |       |          |         |         |       |         |      |                   |          |\n Foo    | Job1 | 10    | 514.5 ns | 5.88 ns | 8.80 ns |  1.00 |    0.00 |    1 | DistinctParamSet4 | Yes      | ^\n Bar    | Job1 | 10    | 614.5 ns | 5.88 ns | 8.80 ns |  1.19 |    0.03 |    2 | DistinctParamSet4 | No       |\n Foo    | Job2 | 10    | 714.5 ns | 5.88 ns | 8.80 ns |  1.39 |    0.03 |    3 | DistinctParamSet4 | No       |\n Bar    | Job2 | 10    | 814.5 ns | 5.88 ns | 8.80 ns |  1.58 |    0.03 |    4 | DistinctParamSet4 | No       |\n\nErrors: 0\n"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Exporters/VerifiedFiles/MarkdownExporterVerifyTests.GroupExporterTest_NoBaseline_MethodsParamsJobs.verified.txt",
    "content": "﻿=== NoBaseline_MethodsParamsJobs ===\n\nBenchmarkDotNet v0.10.x-mock, Microsoft Windows NT 10.0.x.mock (Hyper-V)\nMockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\nFrequency: 2531248 Hz, Resolution: 395.062 ns, Timer: TSC\n  [Host] : Clr 4.0.x.mock, 64mock RyuJIT-v4.6.x.mock CONFIGURATION\n  Job1   : extra output line\n  Job2   : extra output line\n\n\n Method | Job  | Param | Mean       | Error   | StdDev  | Rank | LogicalGroup | Baseline |\n------- |----- |------ |-----------:|--------:|--------:|-----:|------------- |--------- |\n Base   | Job1 | 2     |   114.5 ns | 5.88 ns | 8.80 ns |    1 | *            | No       | ^\n Foo    | Job1 | 2     |   214.5 ns | 5.88 ns | 8.80 ns |    2 | *            | No       |\n Bar    | Job1 | 2     |   314.5 ns | 5.88 ns | 8.80 ns |    3 | *            | No       |\n Base   | Job2 | 2     |   414.5 ns | 5.88 ns | 8.80 ns |    4 | *            | No       |\n Foo    | Job2 | 2     |   514.5 ns | 5.88 ns | 8.80 ns |    5 | *            | No       |\n Bar    | Job2 | 2     |   614.5 ns | 5.88 ns | 8.80 ns |    6 | *            | No       |\n Base   | Job1 | 10    |   714.5 ns | 5.88 ns | 8.80 ns |    7 | *            | No       | ^\n Foo    | Job1 | 10    |   814.5 ns | 5.88 ns | 8.80 ns |    8 | *            | No       |\n Bar    | Job1 | 10    |   914.5 ns | 5.88 ns | 8.80 ns |    9 | *            | No       |\n Base   | Job2 | 10    | 1,014.5 ns | 5.88 ns | 8.80 ns |   10 | *            | No       |\n Foo    | Job2 | 10    | 1,114.5 ns | 5.88 ns | 8.80 ns |   11 | *            | No       |\n Bar    | Job2 | 10    | 1,214.5 ns | 5.88 ns | 8.80 ns |   12 | *            | No       |\n\nErrors: 0\n"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Exporters/VerifiedFiles/MarkdownExporterVerifyTests.GroupExporterTest_NoBaseline_MethodsParamsJobs_GroupByAll.verified.txt",
    "content": "﻿=== NoBaseline_MethodsParamsJobs_GroupByAll ===\n\nBenchmarkDotNet v0.10.x-mock, Microsoft Windows NT 10.0.x.mock (Hyper-V)\nMockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\nFrequency: 2531248 Hz, Resolution: 395.062 ns, Timer: TSC\n  [Host] : Clr 4.0.x.mock, 64mock RyuJIT-v4.6.x.mock CONFIGURATION\n  Job1   : extra output line\n  Job2   : extra output line\n\n\n Method | Job  | Param | Mean       | Error   | StdDev  | Ratio | RatioSD | Rank | LogicalGroup                                                           | Baseline |\n------- |----- |------ |-----------:|--------:|--------:|------:|--------:|-----:|----------------------------------------------------------------------- |--------- |\n A1     | Job1 | 2     |   114.5 ns | 5.88 ns | 8.80 ns |  1.00 |    0.00 |    1 | NoBaseline_MethodsParamsJobs_GroupByAll.A1-Job1-DistinctParamSet0-CatA | Yes      | ^\n        |      |       |            |         |         |       |         |      |                                                                        |          |\n A1     | Job1 | 10    |   514.5 ns | 5.88 ns | 8.80 ns |  1.00 |    0.00 |    1 | NoBaseline_MethodsParamsJobs_GroupByAll.A1-Job1-DistinctParamSet1-CatA | Yes      | ^\n        |      |       |            |         |         |       |         |      |                                                                        |          |\n A1     | Job2 | 2     |   314.5 ns | 5.88 ns | 8.80 ns |  1.00 |    0.00 |    1 | NoBaseline_MethodsParamsJobs_GroupByAll.A1-Job2-DistinctParamSet0-CatA | Yes      | ^\n        |      |       |            |         |         |       |         |      |                                                                        |          |\n A1     | Job2 | 10    |   714.5 ns | 5.88 ns | 8.80 ns |  1.00 |    0.00 |    1 | NoBaseline_MethodsParamsJobs_GroupByAll.A1-Job2-DistinctParamSet1-CatA | Yes      | ^\n        |      |       |            |         |         |       |         |      |                                                                        |          |\n A2     | Job1 | 2     |   214.5 ns | 5.88 ns | 8.80 ns |     ? |       ? |    1 | NoBaseline_MethodsParamsJobs_GroupByAll.A2-Job1-DistinctParamSet0-CatA | No       | ^\n        |      |       |            |         |         |       |         |      |                                                                        |          |\n A2     | Job1 | 10    |   614.5 ns | 5.88 ns | 8.80 ns |     ? |       ? |    1 | NoBaseline_MethodsParamsJobs_GroupByAll.A2-Job1-DistinctParamSet1-CatA | No       | ^\n        |      |       |            |         |         |       |         |      |                                                                        |          |\n A2     | Job2 | 2     |   414.5 ns | 5.88 ns | 8.80 ns |     ? |       ? |    1 | NoBaseline_MethodsParamsJobs_GroupByAll.A2-Job2-DistinctParamSet0-CatA | No       | ^\n        |      |       |            |         |         |       |         |      |                                                                        |          |\n A2     | Job2 | 10    |   814.5 ns | 5.88 ns | 8.80 ns |     ? |       ? |    1 | NoBaseline_MethodsParamsJobs_GroupByAll.A2-Job2-DistinctParamSet1-CatA | No       | ^\n        |      |       |            |         |         |       |         |      |                                                                        |          |\n B1     | Job1 | 2     |   914.5 ns | 5.88 ns | 8.80 ns |  1.00 |    0.00 |    1 | NoBaseline_MethodsParamsJobs_GroupByAll.B1-Job1-DistinctParamSet0-CatB | Yes      | ^\n        |      |       |            |         |         |       |         |      |                                                                        |          |\n B1     | Job1 | 10    | 1,314.5 ns | 5.88 ns | 8.80 ns |  1.00 |    0.00 |    1 | NoBaseline_MethodsParamsJobs_GroupByAll.B1-Job1-DistinctParamSet1-CatB | Yes      | ^\n        |      |       |            |         |         |       |         |      |                                                                        |          |\n B1     | Job2 | 2     | 1,114.5 ns | 5.88 ns | 8.80 ns |  1.00 |    0.00 |    1 | NoBaseline_MethodsParamsJobs_GroupByAll.B1-Job2-DistinctParamSet0-CatB | Yes      | ^\n        |      |       |            |         |         |       |         |      |                                                                        |          |\n B1     | Job2 | 10    | 1,514.5 ns | 5.88 ns | 8.80 ns |  1.00 |    0.00 |    1 | NoBaseline_MethodsParamsJobs_GroupByAll.B1-Job2-DistinctParamSet1-CatB | Yes      | ^\n        |      |       |            |         |         |       |         |      |                                                                        |          |\n B2     | Job1 | 2     | 1,014.5 ns | 5.88 ns | 8.80 ns |     ? |       ? |    1 | NoBaseline_MethodsParamsJobs_GroupByAll.B2-Job1-DistinctParamSet0-CatB | No       | ^\n        |      |       |            |         |         |       |         |      |                                                                        |          |\n B2     | Job1 | 10    | 1,414.5 ns | 5.88 ns | 8.80 ns |     ? |       ? |    1 | NoBaseline_MethodsParamsJobs_GroupByAll.B2-Job1-DistinctParamSet1-CatB | No       | ^\n        |      |       |            |         |         |       |         |      |                                                                        |          |\n B2     | Job2 | 2     | 1,214.5 ns | 5.88 ns | 8.80 ns |     ? |       ? |    1 | NoBaseline_MethodsParamsJobs_GroupByAll.B2-Job2-DistinctParamSet0-CatB | No       | ^\n        |      |       |            |         |         |       |         |      |                                                                        |          |\n B2     | Job2 | 10    | 1,614.5 ns | 5.88 ns | 8.80 ns |     ? |       ? |    1 | NoBaseline_MethodsParamsJobs_GroupByAll.B2-Job2-DistinctParamSet1-CatB | No       | ^\n\nErrors: 0\n"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Exporters/VerifiedFiles/MarkdownExporterVerifyTests.GroupExporterTest_NoBaseline_MethodsParamsJobs_GroupByCategory.verified.txt",
    "content": "﻿=== NoBaseline_MethodsParamsJobs_GroupByCategory ===\n\nBenchmarkDotNet v0.10.x-mock, Microsoft Windows NT 10.0.x.mock (Hyper-V)\nMockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\nFrequency: 2531248 Hz, Resolution: 395.062 ns, Timer: TSC\n  [Host] : Clr 4.0.x.mock, 64mock RyuJIT-v4.6.x.mock CONFIGURATION\n  Job1   : extra output line\n  Job2   : extra output line\n\n\n Method | Job  | Param | Mean       | Error   | StdDev  | Ratio | RatioSD | Rank | LogicalGroup                | Baseline |\n------- |----- |------ |-----------:|--------:|--------:|------:|--------:|-----:|---------------------------- |--------- |\n A1     | Job1 | 2     |   114.5 ns | 5.88 ns | 8.80 ns |  1.00 |    0.00 |    1 | CatA-DistinctParamSet0-Job1 | Yes      | ^\n A2     | Job1 | 2     |   214.5 ns | 5.88 ns | 8.80 ns |  1.88 |    0.16 |    2 | CatA-DistinctParamSet0-Job1 | No       |\n        |      |       |            |         |         |       |         |      |                             |          |\n A1     | Job2 | 2     |   314.5 ns | 5.88 ns | 8.80 ns |  1.00 |    0.00 |    1 | CatA-DistinctParamSet0-Job2 | Yes      |\n A2     | Job2 | 2     |   414.5 ns | 5.88 ns | 8.80 ns |  1.32 |    0.05 |    2 | CatA-DistinctParamSet0-Job2 | No       |\n        |      |       |            |         |         |       |         |      |                             |          |\n A1     | Job1 | 10    |   514.5 ns | 5.88 ns | 8.80 ns |  1.00 |    0.00 |    1 | CatA-DistinctParamSet4-Job1 | Yes      | ^\n A2     | Job1 | 10    |   614.5 ns | 5.88 ns | 8.80 ns |  1.19 |    0.03 |    2 | CatA-DistinctParamSet4-Job1 | No       |\n        |      |       |            |         |         |       |         |      |                             |          |\n A1     | Job2 | 10    |   714.5 ns | 5.88 ns | 8.80 ns |  1.00 |    0.00 |    1 | CatA-DistinctParamSet4-Job2 | Yes      |\n A2     | Job2 | 10    |   814.5 ns | 5.88 ns | 8.80 ns |  1.14 |    0.02 |    2 | CatA-DistinctParamSet4-Job2 | No       |\n        |      |       |            |         |         |       |         |      |                             |          |\n B1     | Job1 | 2     |   914.5 ns | 5.88 ns | 8.80 ns |  1.00 |    0.00 |    1 | CatB-DistinctParamSet0-Job1 | Yes      | ^\n B2     | Job1 | 2     | 1,014.5 ns | 5.88 ns | 8.80 ns |  1.11 |    0.01 |    2 | CatB-DistinctParamSet0-Job1 | No       |\n        |      |       |            |         |         |       |         |      |                             |          |\n B1     | Job2 | 2     | 1,114.5 ns | 5.88 ns | 8.80 ns |  1.00 |    0.00 |    1 | CatB-DistinctParamSet0-Job2 | Yes      |\n B2     | Job2 | 2     | 1,214.5 ns | 5.88 ns | 8.80 ns |  1.09 |    0.01 |    2 | CatB-DistinctParamSet0-Job2 | No       |\n        |      |       |            |         |         |       |         |      |                             |          |\n B1     | Job1 | 10    | 1,314.5 ns | 5.88 ns | 8.80 ns |  1.00 |    0.00 |    1 | CatB-DistinctParamSet4-Job1 | Yes      | ^\n B2     | Job1 | 10    | 1,414.5 ns | 5.88 ns | 8.80 ns |  1.08 |    0.01 |    2 | CatB-DistinctParamSet4-Job1 | No       |\n        |      |       |            |         |         |       |         |      |                             |          |\n B1     | Job2 | 10    | 1,514.5 ns | 5.88 ns | 8.80 ns |  1.00 |    0.00 |    1 | CatB-DistinctParamSet4-Job2 | Yes      |\n B2     | Job2 | 10    | 1,614.5 ns | 5.88 ns | 8.80 ns |  1.07 |    0.01 |    2 | CatB-DistinctParamSet4-Job2 | No       |\n\nErrors: 0\n"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Exporters/VerifiedFiles/MarkdownExporterVerifyTests.GroupExporterTest_NoBaseline_MethodsParamsJobs_GroupByJob.verified.txt",
    "content": "﻿=== NoBaseline_MethodsParamsJobs_GroupByJob ===\n\nBenchmarkDotNet v0.10.x-mock, Microsoft Windows NT 10.0.x.mock (Hyper-V)\nMockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\nFrequency: 2531248 Hz, Resolution: 395.062 ns, Timer: TSC\n  [Host] : Clr 4.0.x.mock, 64mock RyuJIT-v4.6.x.mock CONFIGURATION\n  Job1   : extra output line\n  Job2   : extra output line\n\n\n Method | Job  | Param | Mean       | Error   | StdDev  | Rank | LogicalGroup | Baseline |\n------- |----- |------ |-----------:|--------:|--------:|-----:|------------- |--------- |\n Base   | Job1 | 2     |   114.5 ns | 5.88 ns | 8.80 ns |    1 | Job1         | No       | ^\n Base   | Job1 | 10    |   314.5 ns | 5.88 ns | 8.80 ns |    2 | Job1         | No       | ^\n Foo    | Job1 | 2     |   514.5 ns | 5.88 ns | 8.80 ns |    3 | Job1         | No       | ^\n Bar    | Job1 | 2     |   614.5 ns | 5.88 ns | 8.80 ns |    4 | Job1         | No       |\n Foo    | Job1 | 10    |   914.5 ns | 5.88 ns | 8.80 ns |    5 | Job1         | No       | ^\n Bar    | Job1 | 10    | 1,014.5 ns | 5.88 ns | 8.80 ns |    6 | Job1         | No       |\n        |      |       |            |         |         |      |              |          |\n Base   | Job2 | 2     |   214.5 ns | 5.88 ns | 8.80 ns |    1 | Job2         | No       | ^\n Base   | Job2 | 10    |   414.5 ns | 5.88 ns | 8.80 ns |    2 | Job2         | No       | ^\n Foo    | Job2 | 2     |   714.5 ns | 5.88 ns | 8.80 ns |    3 | Job2         | No       | ^\n Bar    | Job2 | 2     |   814.5 ns | 5.88 ns | 8.80 ns |    4 | Job2         | No       |\n Foo    | Job2 | 10    | 1,114.5 ns | 5.88 ns | 8.80 ns |    5 | Job2         | No       | ^\n Bar    | Job2 | 10    | 1,214.5 ns | 5.88 ns | 8.80 ns |    6 | Job2         | No       |\n\nErrors: 0\n"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Exporters/VerifiedFiles/MarkdownExporterVerifyTests.GroupExporterTest_NoBaseline_MethodsParamsJobs_GroupByMethod.verified.txt",
    "content": "﻿=== NoBaseline_MethodsParamsJobs_GroupByMethod ===\n\nBenchmarkDotNet v0.10.x-mock, Microsoft Windows NT 10.0.x.mock (Hyper-V)\nMockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\nFrequency: 2531248 Hz, Resolution: 395.062 ns, Timer: TSC\n  [Host] : Clr 4.0.x.mock, 64mock RyuJIT-v4.6.x.mock CONFIGURATION\n  Job1   : extra output line\n  Job2   : extra output line\n\n\n Method | Job  | Param | Mean       | Error   | StdDev  | Rank | LogicalGroup                                    | Baseline |\n------- |----- |------ |-----------:|--------:|--------:|-----:|------------------------------------------------ |--------- |\n Base   | Job1 | 2     |   114.5 ns | 5.88 ns | 8.80 ns |    1 | NoBaseline_MethodsParamsJobs_GroupByMethod.Base | No       | ^\n Base   | Job2 | 2     |   214.5 ns | 5.88 ns | 8.80 ns |    2 | NoBaseline_MethodsParamsJobs_GroupByMethod.Base | No       |\n Base   | Job1 | 10    |   314.5 ns | 5.88 ns | 8.80 ns |    3 | NoBaseline_MethodsParamsJobs_GroupByMethod.Base | No       | ^\n Base   | Job2 | 10    |   414.5 ns | 5.88 ns | 8.80 ns |    4 | NoBaseline_MethodsParamsJobs_GroupByMethod.Base | No       |\n        |      |       |            |         |         |      |                                                 |          |\n Foo    | Job1 | 2     |   514.5 ns | 5.88 ns | 8.80 ns |    1 | NoBaseline_MethodsParamsJobs_GroupByMethod.Foo  | No       | ^\n Foo    | Job2 | 2     |   714.5 ns | 5.88 ns | 8.80 ns |    2 | NoBaseline_MethodsParamsJobs_GroupByMethod.Foo  | No       |\n Foo    | Job1 | 10    |   914.5 ns | 5.88 ns | 8.80 ns |    3 | NoBaseline_MethodsParamsJobs_GroupByMethod.Foo  | No       | ^\n Foo    | Job2 | 10    | 1,114.5 ns | 5.88 ns | 8.80 ns |    4 | NoBaseline_MethodsParamsJobs_GroupByMethod.Foo  | No       |\n        |      |       |            |         |         |      |                                                 |          |\n Bar    | Job1 | 2     |   614.5 ns | 5.88 ns | 8.80 ns |    1 | NoBaseline_MethodsParamsJobs_GroupByMethod.Bar  | No       | ^\n Bar    | Job2 | 2     |   814.5 ns | 5.88 ns | 8.80 ns |    2 | NoBaseline_MethodsParamsJobs_GroupByMethod.Bar  | No       |\n Bar    | Job1 | 10    | 1,014.5 ns | 5.88 ns | 8.80 ns |    3 | NoBaseline_MethodsParamsJobs_GroupByMethod.Bar  | No       | ^\n Bar    | Job2 | 10    | 1,214.5 ns | 5.88 ns | 8.80 ns |    4 | NoBaseline_MethodsParamsJobs_GroupByMethod.Bar  | No       |\n\nErrors: 0\n"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Exporters/VerifiedFiles/MarkdownExporterVerifyTests.GroupExporterTest_NoBaseline_MethodsParamsJobs_GroupByParams.verified.txt",
    "content": "﻿=== NoBaseline_MethodsParamsJobs_GroupByParams ===\n\nBenchmarkDotNet v0.10.x-mock, Microsoft Windows NT 10.0.x.mock (Hyper-V)\nMockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\nFrequency: 2531248 Hz, Resolution: 395.062 ns, Timer: TSC\n  [Host] : Clr 4.0.x.mock, 64mock RyuJIT-v4.6.x.mock CONFIGURATION\n  Job1   : extra output line\n  Job2   : extra output line\n\n\n Method | Job  | Param | Mean       | Error   | StdDev  | Rank | LogicalGroup      | Baseline |\n------- |----- |------ |-----------:|--------:|--------:|-----:|------------------ |--------- |\n Base   | Job1 | 2     |   114.5 ns | 5.88 ns | 8.80 ns |    1 | DistinctParamSet0 | No       | ^\n Base   | Job2 | 2     |   214.5 ns | 5.88 ns | 8.80 ns |    2 | DistinctParamSet0 | No       |\n Foo    | Job1 | 2     |   514.5 ns | 5.88 ns | 8.80 ns |    3 | DistinctParamSet0 | No       |\n Bar    | Job1 | 2     |   614.5 ns | 5.88 ns | 8.80 ns |    4 | DistinctParamSet0 | No       |\n Foo    | Job2 | 2     |   714.5 ns | 5.88 ns | 8.80 ns |    5 | DistinctParamSet0 | No       |\n Bar    | Job2 | 2     |   814.5 ns | 5.88 ns | 8.80 ns |    6 | DistinctParamSet0 | No       |\n        |      |       |            |         |         |      |                   |          |\n Base   | Job1 | 10    |   314.5 ns | 5.88 ns | 8.80 ns |    1 | DistinctParamSet6 | No       | ^\n Base   | Job2 | 10    |   414.5 ns | 5.88 ns | 8.80 ns |    2 | DistinctParamSet6 | No       |\n Foo    | Job1 | 10    |   914.5 ns | 5.88 ns | 8.80 ns |    3 | DistinctParamSet6 | No       |\n Bar    | Job1 | 10    | 1,014.5 ns | 5.88 ns | 8.80 ns |    4 | DistinctParamSet6 | No       |\n Foo    | Job2 | 10    | 1,114.5 ns | 5.88 ns | 8.80 ns |    5 | DistinctParamSet6 | No       |\n Bar    | Job2 | 10    | 1,214.5 ns | 5.88 ns | 8.80 ns |    6 | DistinctParamSet6 | No       |\n\nErrors: 0\n"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Exporters/VerifiedFiles/OpenMetricsExporterTests.LabelsAreEscapedCorrectly.verified.txt",
    "content": "﻿# HELP benchmark_error_nanoseconds Standard error of the mean execution time in nanoseconds.\n# TYPE benchmark_error_nanoseconds gauge\n# UNIT benchmark_error_nanoseconds nanoseconds\nbenchmark_error_nanoseconds{method=\"Foo\", type=\"MockBenchmarkClass\"} 0\n# HELP benchmark_execution_time_nanoseconds Mean execution time in nanoseconds.\n# TYPE benchmark_execution_time_nanoseconds gauge\n# UNIT benchmark_execution_time_nanoseconds nanoseconds\nbenchmark_execution_time_nanoseconds{method=\"Foo\", type=\"MockBenchmarkClass\"} 0.1\n# HELP benchmark_gc_gen0_collections_total Total number of Gen 0 garbage collections during the benchmark execution.\n# TYPE benchmark_gc_gen0_collections_total counter\nbenchmark_gc_gen0_collections_total{method=\"Foo\", type=\"MockBenchmarkClass\"} 0\n# HELP benchmark_gc_gen1_collections_total Total number of Gen 1 garbage collections during the benchmark execution.\n# TYPE benchmark_gc_gen1_collections_total counter\nbenchmark_gc_gen1_collections_total{method=\"Foo\", type=\"MockBenchmarkClass\"} 0\n# HELP benchmark_gc_gen2_collections_total Total number of Gen 2 garbage collections during the benchmark execution.\n# TYPE benchmark_gc_gen2_collections_total counter\nbenchmark_gc_gen2_collections_total{method=\"Foo\", type=\"MockBenchmarkClass\"} 0\n# HELP benchmark_gc_total_operations_total Total number of garbage collection operations during the benchmark execution.\n# TYPE benchmark_gc_total_operations_total counter\nbenchmark_gc_total_operations_total{method=\"Foo\", type=\"MockBenchmarkClass\"} 0\n# HELP benchmark_label_with_dash Additional metric label_with-dash\n# TYPE benchmark_label_with_dash gauge\nbenchmark_label_with_dash{method=\"Foo\", type=\"MockBenchmarkClass\"} 84\n# HELP benchmark_label_with_dot Additional metric label.with.dot\n# TYPE benchmark_label_with_dot gauge\nbenchmark_label_with_dot{method=\"Foo\", type=\"MockBenchmarkClass\"} 168\n# HELP benchmark_label_with_space Additional metric label with space\n# TYPE benchmark_label_with_space gauge\nbenchmark_label_with_space{method=\"Foo\", type=\"MockBenchmarkClass\"} 126\n# HELP benchmark_label_with_special_chars Additional metric label with special chars !@#$%^&*()\n# TYPE benchmark_label_with_special_chars gauge\nbenchmark_label_with_special_chars{method=\"Foo\", type=\"MockBenchmarkClass\"} 210\n# HELP benchmark_label_with_special_chars_in_the_middle Additional metric label with special !@#$%^&*()chars in the middle\n# TYPE benchmark_label_with_special_chars_in_the_middle gauge\nbenchmark_label_with_special_chars_in_the_middle{method=\"Foo\", type=\"MockBenchmarkClass\"} 210\n# HELP benchmark_label_with_underscore Additional metric label_with_underscore\n# TYPE benchmark_label_with_underscore gauge\nbenchmark_label_with_underscore{method=\"Foo\", type=\"MockBenchmarkClass\"} 42\n# HELP benchmark_p90_nanoseconds 90th percentile execution time in nanoseconds.\n# TYPE benchmark_p90_nanoseconds gauge\n# UNIT benchmark_p90_nanoseconds nanoseconds\nbenchmark_p90_nanoseconds{method=\"Foo\", type=\"MockBenchmarkClass\"} 0.1\n# HELP benchmark_p95_nanoseconds 95th percentile execution time in nanoseconds.\n# TYPE benchmark_p95_nanoseconds gauge\n# UNIT benchmark_p95_nanoseconds nanoseconds\nbenchmark_p95_nanoseconds{method=\"Foo\", type=\"MockBenchmarkClass\"} 0.1\n# HELP benchmark_stddev_nanoseconds Standard deviation of execution time in nanoseconds.\n# TYPE benchmark_stddev_nanoseconds gauge\n# UNIT benchmark_stddev_nanoseconds nanoseconds\nbenchmark_stddev_nanoseconds{method=\"Foo\", type=\"MockBenchmarkClass\"} 0\n# EOF\n"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Exporters/VerifiedFiles/OpenMetricsExporterTests.ParametrizedBenchmarks_LabelExpansion.verified.txt",
    "content": "﻿# HELP benchmark_error_nanoseconds Standard error of the mean execution time in nanoseconds.\n# TYPE benchmark_error_nanoseconds gauge\n# UNIT benchmark_error_nanoseconds nanoseconds\nbenchmark_error_nanoseconds{method=\"Foo\", param1=\"value1\", param2=\"value1\", param3=\"value1\", type=\"MockBenchmarkClass\"} 0\nbenchmark_error_nanoseconds{method=\"Foo\", param1=\"value2\", param2=\"value2\", param3=\"value2\", type=\"MockBenchmarkClass\"} 0\nbenchmark_error_nanoseconds{method=\"Foo\", param1=\"value3\", param2=\"value3\", param3=\"value3\", type=\"MockBenchmarkClass\"} 0\n# HELP benchmark_execution_time_nanoseconds Mean execution time in nanoseconds.\n# TYPE benchmark_execution_time_nanoseconds gauge\n# UNIT benchmark_execution_time_nanoseconds nanoseconds\nbenchmark_execution_time_nanoseconds{method=\"Foo\", param1=\"value1\", param2=\"value1\", param3=\"value1\", type=\"MockBenchmarkClass\"} 0.1\nbenchmark_execution_time_nanoseconds{method=\"Foo\", param1=\"value2\", param2=\"value2\", param3=\"value2\", type=\"MockBenchmarkClass\"} 0.1\nbenchmark_execution_time_nanoseconds{method=\"Foo\", param1=\"value3\", param2=\"value3\", param3=\"value3\", type=\"MockBenchmarkClass\"} 0.1\n# HELP benchmark_gc_gen0_collections_total Total number of Gen 0 garbage collections during the benchmark execution.\n# TYPE benchmark_gc_gen0_collections_total counter\nbenchmark_gc_gen0_collections_total{method=\"Foo\", param1=\"value1\", param2=\"value1\", param3=\"value1\", type=\"MockBenchmarkClass\"} 0\nbenchmark_gc_gen0_collections_total{method=\"Foo\", param1=\"value2\", param2=\"value2\", param3=\"value2\", type=\"MockBenchmarkClass\"} 0\nbenchmark_gc_gen0_collections_total{method=\"Foo\", param1=\"value3\", param2=\"value3\", param3=\"value3\", type=\"MockBenchmarkClass\"} 0\n# HELP benchmark_gc_gen1_collections_total Total number of Gen 1 garbage collections during the benchmark execution.\n# TYPE benchmark_gc_gen1_collections_total counter\nbenchmark_gc_gen1_collections_total{method=\"Foo\", param1=\"value1\", param2=\"value1\", param3=\"value1\", type=\"MockBenchmarkClass\"} 0\nbenchmark_gc_gen1_collections_total{method=\"Foo\", param1=\"value2\", param2=\"value2\", param3=\"value2\", type=\"MockBenchmarkClass\"} 0\nbenchmark_gc_gen1_collections_total{method=\"Foo\", param1=\"value3\", param2=\"value3\", param3=\"value3\", type=\"MockBenchmarkClass\"} 0\n# HELP benchmark_gc_gen2_collections_total Total number of Gen 2 garbage collections during the benchmark execution.\n# TYPE benchmark_gc_gen2_collections_total counter\nbenchmark_gc_gen2_collections_total{method=\"Foo\", param1=\"value1\", param2=\"value1\", param3=\"value1\", type=\"MockBenchmarkClass\"} 0\nbenchmark_gc_gen2_collections_total{method=\"Foo\", param1=\"value2\", param2=\"value2\", param3=\"value2\", type=\"MockBenchmarkClass\"} 0\nbenchmark_gc_gen2_collections_total{method=\"Foo\", param1=\"value3\", param2=\"value3\", param3=\"value3\", type=\"MockBenchmarkClass\"} 0\n# HELP benchmark_gc_total_operations_total Total number of garbage collection operations during the benchmark execution.\n# TYPE benchmark_gc_total_operations_total counter\nbenchmark_gc_total_operations_total{method=\"Foo\", param1=\"value1\", param2=\"value1\", param3=\"value1\", type=\"MockBenchmarkClass\"} 0\nbenchmark_gc_total_operations_total{method=\"Foo\", param1=\"value2\", param2=\"value2\", param3=\"value2\", type=\"MockBenchmarkClass\"} 0\nbenchmark_gc_total_operations_total{method=\"Foo\", param1=\"value3\", param2=\"value3\", param3=\"value3\", type=\"MockBenchmarkClass\"} 0\n# HELP benchmark_label Additional metric label\n# TYPE benchmark_label gauge\nbenchmark_label{method=\"Foo\", param1=\"value1\", param2=\"value1\", param3=\"value1\", type=\"MockBenchmarkClass\"} 42\nbenchmark_label{method=\"Foo\", param1=\"value2\", param2=\"value2\", param3=\"value2\", type=\"MockBenchmarkClass\"} 42\nbenchmark_label{method=\"Foo\", param1=\"value3\", param2=\"value3\", param3=\"value3\", type=\"MockBenchmarkClass\"} 42\n# HELP benchmark_p90_nanoseconds 90th percentile execution time in nanoseconds.\n# TYPE benchmark_p90_nanoseconds gauge\n# UNIT benchmark_p90_nanoseconds nanoseconds\nbenchmark_p90_nanoseconds{method=\"Foo\", param1=\"value1\", param2=\"value1\", param3=\"value1\", type=\"MockBenchmarkClass\"} 0.1\nbenchmark_p90_nanoseconds{method=\"Foo\", param1=\"value2\", param2=\"value2\", param3=\"value2\", type=\"MockBenchmarkClass\"} 0.1\nbenchmark_p90_nanoseconds{method=\"Foo\", param1=\"value3\", param2=\"value3\", param3=\"value3\", type=\"MockBenchmarkClass\"} 0.1\n# HELP benchmark_p95_nanoseconds 95th percentile execution time in nanoseconds.\n# TYPE benchmark_p95_nanoseconds gauge\n# UNIT benchmark_p95_nanoseconds nanoseconds\nbenchmark_p95_nanoseconds{method=\"Foo\", param1=\"value1\", param2=\"value1\", param3=\"value1\", type=\"MockBenchmarkClass\"} 0.1\nbenchmark_p95_nanoseconds{method=\"Foo\", param1=\"value2\", param2=\"value2\", param3=\"value2\", type=\"MockBenchmarkClass\"} 0.1\nbenchmark_p95_nanoseconds{method=\"Foo\", param1=\"value3\", param2=\"value3\", param3=\"value3\", type=\"MockBenchmarkClass\"} 0.1\n# HELP benchmark_stddev_nanoseconds Standard deviation of execution time in nanoseconds.\n# TYPE benchmark_stddev_nanoseconds gauge\n# UNIT benchmark_stddev_nanoseconds nanoseconds\nbenchmark_stddev_nanoseconds{method=\"Foo\", param1=\"value1\", param2=\"value1\", param3=\"value1\", type=\"MockBenchmarkClass\"} 0\nbenchmark_stddev_nanoseconds{method=\"Foo\", param1=\"value2\", param2=\"value2\", param3=\"value2\", type=\"MockBenchmarkClass\"} 0\nbenchmark_stddev_nanoseconds{method=\"Foo\", param1=\"value3\", param2=\"value3\", param3=\"value3\", type=\"MockBenchmarkClass\"} 0\n# EOF\n"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Exporters/VerifiedFiles/OpenMetricsExporterTests.SingleBenchmark_ProducesHelpAndTypeOnce.verified.txt",
    "content": "﻿# HELP benchmark_error_nanoseconds Standard error of the mean execution time in nanoseconds.\n# TYPE benchmark_error_nanoseconds gauge\n# UNIT benchmark_error_nanoseconds nanoseconds\nbenchmark_error_nanoseconds{method=\"Foo\", param1=\"value1\", type=\"MockBenchmarkClass\"} 0\nbenchmark_error_nanoseconds{method=\"Foo\", param1=\"value2\", type=\"MockBenchmarkClass\"} 0\nbenchmark_error_nanoseconds{method=\"Foo\", param1=\"value3\", type=\"MockBenchmarkClass\"} 0\n# HELP benchmark_execution_time_nanoseconds Mean execution time in nanoseconds.\n# TYPE benchmark_execution_time_nanoseconds gauge\n# UNIT benchmark_execution_time_nanoseconds nanoseconds\nbenchmark_execution_time_nanoseconds{method=\"Foo\", param1=\"value1\", type=\"MockBenchmarkClass\"} 0.1\nbenchmark_execution_time_nanoseconds{method=\"Foo\", param1=\"value2\", type=\"MockBenchmarkClass\"} 0.1\nbenchmark_execution_time_nanoseconds{method=\"Foo\", param1=\"value3\", type=\"MockBenchmarkClass\"} 0.1\n# HELP benchmark_gc_gen0_collections_total Total number of Gen 0 garbage collections during the benchmark execution.\n# TYPE benchmark_gc_gen0_collections_total counter\nbenchmark_gc_gen0_collections_total{method=\"Foo\", param1=\"value1\", type=\"MockBenchmarkClass\"} 0\nbenchmark_gc_gen0_collections_total{method=\"Foo\", param1=\"value2\", type=\"MockBenchmarkClass\"} 0\nbenchmark_gc_gen0_collections_total{method=\"Foo\", param1=\"value3\", type=\"MockBenchmarkClass\"} 0\n# HELP benchmark_gc_gen1_collections_total Total number of Gen 1 garbage collections during the benchmark execution.\n# TYPE benchmark_gc_gen1_collections_total counter\nbenchmark_gc_gen1_collections_total{method=\"Foo\", param1=\"value1\", type=\"MockBenchmarkClass\"} 0\nbenchmark_gc_gen1_collections_total{method=\"Foo\", param1=\"value2\", type=\"MockBenchmarkClass\"} 0\nbenchmark_gc_gen1_collections_total{method=\"Foo\", param1=\"value3\", type=\"MockBenchmarkClass\"} 0\n# HELP benchmark_gc_gen2_collections_total Total number of Gen 2 garbage collections during the benchmark execution.\n# TYPE benchmark_gc_gen2_collections_total counter\nbenchmark_gc_gen2_collections_total{method=\"Foo\", param1=\"value1\", type=\"MockBenchmarkClass\"} 0\nbenchmark_gc_gen2_collections_total{method=\"Foo\", param1=\"value2\", type=\"MockBenchmarkClass\"} 0\nbenchmark_gc_gen2_collections_total{method=\"Foo\", param1=\"value3\", type=\"MockBenchmarkClass\"} 0\n# HELP benchmark_gc_total_operations_total Total number of garbage collection operations during the benchmark execution.\n# TYPE benchmark_gc_total_operations_total counter\nbenchmark_gc_total_operations_total{method=\"Foo\", param1=\"value1\", type=\"MockBenchmarkClass\"} 0\nbenchmark_gc_total_operations_total{method=\"Foo\", param1=\"value2\", type=\"MockBenchmarkClass\"} 0\nbenchmark_gc_total_operations_total{method=\"Foo\", param1=\"value3\", type=\"MockBenchmarkClass\"} 0\n# HELP benchmark_label Additional metric label\n# TYPE benchmark_label gauge\nbenchmark_label{method=\"Foo\", param1=\"value1\", type=\"MockBenchmarkClass\"} 42\nbenchmark_label{method=\"Foo\", param1=\"value2\", type=\"MockBenchmarkClass\"} 42\nbenchmark_label{method=\"Foo\", param1=\"value3\", type=\"MockBenchmarkClass\"} 42\n# HELP benchmark_p90_nanoseconds 90th percentile execution time in nanoseconds.\n# TYPE benchmark_p90_nanoseconds gauge\n# UNIT benchmark_p90_nanoseconds nanoseconds\nbenchmark_p90_nanoseconds{method=\"Foo\", param1=\"value1\", type=\"MockBenchmarkClass\"} 0.1\nbenchmark_p90_nanoseconds{method=\"Foo\", param1=\"value2\", type=\"MockBenchmarkClass\"} 0.1\nbenchmark_p90_nanoseconds{method=\"Foo\", param1=\"value3\", type=\"MockBenchmarkClass\"} 0.1\n# HELP benchmark_p95_nanoseconds 95th percentile execution time in nanoseconds.\n# TYPE benchmark_p95_nanoseconds gauge\n# UNIT benchmark_p95_nanoseconds nanoseconds\nbenchmark_p95_nanoseconds{method=\"Foo\", param1=\"value1\", type=\"MockBenchmarkClass\"} 0.1\nbenchmark_p95_nanoseconds{method=\"Foo\", param1=\"value2\", type=\"MockBenchmarkClass\"} 0.1\nbenchmark_p95_nanoseconds{method=\"Foo\", param1=\"value3\", type=\"MockBenchmarkClass\"} 0.1\n# HELP benchmark_stddev_nanoseconds Standard deviation of execution time in nanoseconds.\n# TYPE benchmark_stddev_nanoseconds gauge\n# UNIT benchmark_stddev_nanoseconds nanoseconds\nbenchmark_stddev_nanoseconds{method=\"Foo\", param1=\"value1\", type=\"MockBenchmarkClass\"} 0\nbenchmark_stddev_nanoseconds{method=\"Foo\", param1=\"value2\", type=\"MockBenchmarkClass\"} 0\nbenchmark_stddev_nanoseconds{method=\"Foo\", param1=\"value3\", type=\"MockBenchmarkClass\"} 0\n# EOF\n"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Exporters/XmlSerializerTests.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Globalization;\nusing System.Text;\nusing BenchmarkDotNet.Exporters.Xml;\nusing JetBrains.Annotations;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests.Exporters\n{\n    public class XmlSerializerTests\n    {\n        [Fact]\n        public void Serialize()\n        {\n            string expected =\n                \"Start \" +\n                \"MockSource \" +\n                    \"IsValid True IsValid \" +\n                    \"IntNumber 42 IntNumber \" +\n                    $\"DoubleNumber {double.MaxValue.ToString(CultureInfo.InvariantCulture)} DoubleNumber \" +\n                    $\"LongNumber {long.MaxValue} LongNumber \" +\n                    \"Name Source Name \" +\n                    \"Items \" +\n                        \"Item Name i1 Name Item \" +\n                        \"Item Name i2 Name Item \" +\n                    \"Items \" +\n                    \"DoubleArray \" +\n                        \"Item 1 Item \" +\n                        \"Item 2 Item \" +\n                    \"DoubleArray \" +\n                \"MockSource \" +\n                \"End\";\n            var source = new MockSource();\n            var writer = new MockXmlWriter();\n            IXmlSerializer serializer = XmlSerializer.GetBuilder(typeof(MockSource)).Build();\n\n            serializer.Serialize(writer, source);\n            string actual = writer.ToString();\n\n            Assert.Equal(expected, actual);\n        }\n\n        [Fact]\n        public void WithRootName()\n        {\n            var source = new MockSource();\n            var writer = new MockXmlWriter();\n            string rootName = \"CustomRoot\";\n            IXmlSerializer serializer = XmlSerializer.GetBuilder(typeof(MockSource))\n                                                .WithRootName(rootName)\n                                                .Build();\n\n            serializer.Serialize(writer, source);\n            string actual = writer.ToString();\n\n            Assert.Contains(rootName, actual);\n            Assert.DoesNotContain(nameof(MockSource), actual);\n        }\n\n        [Fact]\n        public void WithCollectionItemName()\n        {\n            var source = new MockSource();\n            var writer = new MockXmlWriter();\n            var itemName = \"CustomItem\";\n            IXmlSerializer serializer = XmlSerializer.GetBuilder(typeof(MockSource))\n                                                .WithCollectionItemName(nameof(MockSource.Items), itemName)\n                                                .Build();\n\n            serializer.Serialize(writer, source);\n            string actual = writer.ToString();\n\n            Assert.Contains(itemName, actual);\n            Assert.DoesNotContain(nameof(XmlSerializer.DefaultItemName), actual);\n        }\n\n        [Fact]\n        public void WithExcludedProperty()\n        {\n            var source = new MockSource();\n            var writer = new MockXmlWriter();\n            var excludedProperty = nameof(MockSource.IntNumber);\n            IXmlSerializer serializer = XmlSerializer.GetBuilder(typeof(MockSource))\n                                                .WithExcludedProperty(excludedProperty)\n                                                .Build();\n\n            serializer.Serialize(writer, source);\n            string actual = writer.ToString();\n\n            Assert.DoesNotContain(excludedProperty, actual);\n        }\n\n        [Fact]\n        public void CtorThrowsWhenParameterIsNull()\n        {\n            Assert.Throws<ArgumentNullException>(() => XmlSerializer.GetBuilder(null!).Build());\n        }\n\n        [Theory]\n        [InlineData(null, typeof(ArgumentException))]\n        [InlineData(\" \", typeof(ArgumentException))]\n        [InlineData(\"\", typeof(ArgumentException))]\n        public void WithRootNameThrowsGivenNameIsNullOrWhiteSpace(string? name, Type exception)\n        {\n            Assert.Throws(exception, () => XmlSerializer.GetBuilder(typeof(MockSource))\n                                                    .WithRootName(name!)\n                                                    .Build());\n        }\n\n        [Theory]\n        [InlineData(null, null, typeof(ArgumentException))]\n        [InlineData(nameof(MockSource.Items), null, typeof(ArgumentException))]\n        [InlineData(nameof(MockSource.Items), \" \", typeof(ArgumentException))]\n        [InlineData(nameof(MockSource.Items), \"\", typeof(ArgumentException))]\n        [InlineData(null, \"MockItem\", typeof(ArgumentException))]\n        [InlineData(\" \", \"MockItem\", typeof(ArgumentException))]\n        [InlineData(\"\", \"MockItem\", typeof(ArgumentException))]\n        public void WithCollectionItemNameThrowsGivenInvalidArguments(string? collectionName, string? itemName, Type exception)\n        {\n            Assert.Throws(exception, () => XmlSerializer.GetBuilder(typeof(MockSource))\n                                                    .WithCollectionItemName(collectionName!, itemName!)\n                                                    .Build());\n        }\n\n        [Theory]\n        [InlineData(null, typeof(ArgumentException))]\n        [InlineData(\" \", typeof(ArgumentException))]\n        [InlineData(\"\", typeof(ArgumentException))]\n        public void WithExcludedPropertyThrowsGivenNameIsNullOrWhiteSpace(string? name, Type exception)\n        {\n            Assert.Throws(exception, () => XmlSerializer.GetBuilder(typeof(MockSource))\n                                                    .WithExcludedProperty(name!)\n                                                    .Build());\n        }\n\n        [Theory]\n        [MemberData(nameof(SerializeTestDataNames))]\n        public void SerializeThrowsGivenNullArguments(string dataName)\n        {\n            var (writer, source, exception) = SerializeTestDataItems[dataName];\n            var serializer = XmlSerializer.GetBuilder(typeof(MockSource)).Build();\n            Assert.Throws(exception, () => serializer.Serialize(writer, source));\n        }\n\n        private class SerializeTestData\n        {\n            private MockXmlWriter Writer { get; }\n            private object Source { get; }\n            private Type Exception { get; }\n\n            public SerializeTestData(MockXmlWriter writer, object source, Type exception)\n            {\n                Writer = writer;\n                Source = source;\n                Exception = exception;\n            }\n\n            public void Deconstruct(out MockXmlWriter writer, out object source, out Type exception)\n            {\n                writer = Writer;\n                source = Source;\n                exception = Exception;\n            }\n        }\n\n        private static readonly Dictionary<string, SerializeTestData> SerializeTestDataItems = new Dictionary<string, SerializeTestData>\n        {\n            {\"Null\", new SerializeTestData(null!, null!, typeof(ArgumentNullException))},\n            {\"MockSource\", new SerializeTestData(null!, new MockSource(), typeof(ArgumentNullException))},\n            {\"MockXmlWriter\", new SerializeTestData(new MockXmlWriter(), null!, typeof(ArgumentNullException))}\n        };\n\n        [UsedImplicitly]\n        public static TheoryData<string> SerializeTestDataNames => TheoryDataHelper.Create(SerializeTestDataItems.Keys);\n\n        [Fact]\n        public void WritesElementStringGivenSimpleCollectionItem()\n        {\n            IXmlWriter writer = new MockXmlWriter();\n            IXmlSerializer serializer = XmlSerializer.GetBuilder(typeof(SimpleItemSource)).Build();\n\n            serializer.Serialize(writer, new SimpleItemSource());\n            string? actual = writer.ToString();\n\n            Assert.Contains(\"Item s1 Item\", actual);\n            Assert.Contains(\"Item s2 Item\", actual);\n        }\n\n        [Fact]\n        public void DoesNotWriteUnwriteableCollection()\n        {\n            IXmlWriter writer = new MockXmlWriter();\n            IXmlSerializer serializer = XmlSerializer.GetBuilder(typeof(UnwriteableCollectionSource)).Build();\n\n            serializer.Serialize(writer, new UnwriteableCollectionSource());\n            string actual = writer.ToString()!;\n\n            Assert.DoesNotContain(actual, \"Items\");\n        }\n\n        private class MockSource\n        {\n            public bool IsValid { get; } = true;\n            public int IntNumber { get; } = 42;\n            public double DoubleNumber { get; } = double.MaxValue;\n            public long LongNumber { get; } = long.MaxValue;\n            public string Name { get; } = \"Source\";\n            public IEnumerable<MockCollectionItem> Items { get; } =\n                [\n                    new MockCollectionItem(\"i1\"),\n                    new MockCollectionItem(\"i2\"),\n                ];\n            public double[] DoubleArray { get; } = [1, 2];\n        }\n\n        private class SimpleItemSource\n        {\n            public IEnumerable<string> Items { get; } = [\"s1\", \"s2\"];\n        }\n\n        private class UnwriteableCollectionSource\n        {\n            public IEnumerable<string> Items { get; } = [];\n        }\n\n        private class MockCollectionItem\n        {\n            public string Name { get; }\n\n            public MockCollectionItem(string name) { Name = name; }\n        }\n\n        public class MockXmlWriter : IXmlWriter\n        {\n            private readonly StringBuilder writer = new StringBuilder();\n            private readonly Stack<string> openElements = new Stack<string>();\n\n            public void WriteStartDocument()\n            {\n                writer.Append(\"Start \");\n            }\n\n            public void WriteElementString(string localName, string value)\n            {\n                writer.Append(localName);\n                writer.Append(\" \");\n                writer.Append(value);\n                writer.Append(\" \");\n                writer.Append(localName);\n                writer.Append(\" \");\n            }\n\n            public void WriteEndDocument()\n            {\n                writer.Append(\"End\");\n            }\n\n            public void WriteEndElement()\n            {\n                var endElement = openElements.Pop();\n                writer.Append(endElement);\n                writer.Append(\" \");\n            }\n\n            public void WriteStartElement(string localName)\n            {\n                openElements.Push(localName);\n                writer.Append(localName);\n                writer.Append(\" \");\n            }\n\n            public override string ToString() => writer.ToString();\n        }\n    }\n}\n"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/FolderNameTests.cs",
    "content": "﻿using System.Collections.Generic;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Helpers;\nusing Perfolizer.Horology;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests\n{\n    public class FolderNameTests\n    {\n        [Theory]\n        [InlineData(false, \"false\")]\n        [InlineData(true, \"true\")]\n        [InlineData(\"<MyString>\", \"_MyString_\")]\n        [InlineData(\"TestCase:Arg\", \"TestCase_Arg\")]\n        [InlineData('a', \"97\")]\n        [InlineData(0.42f, \"0-42\")]\n        [InlineData(0.42d, \"0-42\")]\n        [InlineData(Jit.RyuJit, \"RyuJit\")]\n        [InlineData(typeof(int), \"System.Int32\")]\n        public void ToFolderNameTest(object value, string expectedName)\n        {\n            Assert.Equal(expectedName, FolderNameHelper.ToFolderName(value));\n        }\n\n        // Value types can't be used as attribute arguments\n        [Fact]\n        public void ToFolderNameStructTest()\n        {\n            Assert.Equal(\"0-42\", FolderNameHelper.ToFolderName(0.42m));\n            Assert.Equal(\"1234000000ns\", FolderNameHelper.ToFolderName(TimeInterval.FromSeconds(1.234)));\n        }\n\n        [Theory]\n        [InlineData(typeof(FolderNameTests), \"BenchmarkDotNet.Tests.FolderNameTests\")]\n        [InlineData(typeof(List<int>), \"System.Collections.Generic.List_Int32_\")]\n        public void FileNamesAreConsistentAcrossOSes(object value, string expectedName)\n        {\n            Assert.Equal(expectedName, FolderNameHelper.ToFolderName(value));\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/FrameworkVersionHelperTests.cs",
    "content": "﻿using BenchmarkDotNet.Helpers;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests\n{\n    public class FrameworkVersionHelperTests\n    {\n        [Theory]\n        [InlineData(\"4.6.1\", \"4.6.1\")]\n        [InlineData(\"4.6.1.123\", \"4.6.1\")]\n        [InlineData(\"4.6.2\", \"4.6.2\")]\n        [InlineData(\"4.6.2.123\", \"4.6.2\")]\n        [InlineData(\"4.7\", \"4.7\")]\n        [InlineData(\"4.7.0\", \"4.7\")]\n        [InlineData(\"4.7.1\", \"4.7.1\")]\n        [InlineData(\"4.7.1.1243\", \"4.7.1\")]\n        [InlineData(\"4.7.2\", \"4.7.2\")]\n        [InlineData(\"4.7.2.1243\", \"4.7.2\")]\n        [InlineData(\"4.7.3324.0\", \"4.7.2\")]\n        [InlineData(\"4.8\", \"4.8\")]\n        [InlineData(\"4.8.024\", \"4.8\")]\n        [InlineData(\"4.8.4510.0\", \"4.8\")]\n        [InlineData(\"4.8.4526.0\", \"4.8\")]\n        [InlineData(\"4.8.9032.0\", \"4.8.1\")]\n        public void ServicingVersionsAreMappedToCorrespondingReleaseVersions(string servicingVersion, string expectedReleaseVersion)\n        {\n            Assert.Equal(expectedReleaseVersion, FrameworkVersionHelper.MapToReleaseVersion(servicingVersion));\n        }\n    }\n}\n"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/FullNameProviderTests.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.IO;\nusing System.Linq;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Exporters;\nusing BenchmarkDotNet.Running;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests\n{\n    public class FullNameProviderTests\n    {\n        private void AssertBenchmarkName<T>(string expectedBenchmarkName)\n        {\n            var benchmark = BenchmarkConverter.TypeToBenchmarks(typeof(T)).BenchmarksCases.Single();\n\n            Assert.Equal(expectedBenchmarkName, FullNameProvider.GetBenchmarkName(benchmark));\n        }\n\n        [Fact]\n        public void MethodsWithoutArgumentsAreSupported()\n            => AssertBenchmarkName<SimplestCase>(\"BenchmarkDotNet.Tests.SimplestCase.Method\");\n\n        [Fact]\n        public void NestedTypesAreSupported()\n        {\n            AssertBenchmarkName<Level0.Level1>(\"BenchmarkDotNet.Tests.Level0+Level1.Method\"); // '+' is used for nested types\n            AssertBenchmarkName<Level0.Level1.Level2>(\"BenchmarkDotNet.Tests.Level0+Level1+Level2.Method\"); // '+' is used for nested types\n        }\n\n        [Fact]\n        public void IntegerArgumentsAreSupported()\n            => AssertBenchmarkName<SingleIntArgument>(\"BenchmarkDotNet.Tests.SingleIntArgument.Method(arg: 1)\");\n\n        [Fact]\n        public void CharacterArgumentsAreSupported()\n            => AssertBenchmarkName<SingleCharArgument>(\"BenchmarkDotNet.Tests.SingleCharArgument.Method(arg: 'c')\");\n\n        [Fact]\n        public void NullArgumentsAreSupported()\n            => AssertBenchmarkName<SingleNullArgument>(\"BenchmarkDotNet.Tests.SingleNullArgument.Method(arg: null)\"); // null is just a null (not \"null\")\n\n        [Fact]\n        public void EnumArgumentsAreSupported()\n            => AssertBenchmarkName<SingleEnumArgument>(\"BenchmarkDotNet.Tests.SingleEnumArgument.Method(arg: Read)\"); // no enum type name, just value\n\n        [Fact]\n        public void MultipleArgumentsAreSupported()\n            => AssertBenchmarkName<FewStringArguments>(\"BenchmarkDotNet.Tests.FewStringArguments.Method(arg1: \\\"a\\\", arg2: \\\"b\\\", arg3: \\\"c\\\", arg4: \\\"d\\\")\");\n\n        [Fact]\n        public void DateTimeArgumentsAreSupported()\n            => AssertBenchmarkName<SingleDateTimeArgument>(\"BenchmarkDotNet.Tests.SingleDateTimeArgument.Method(arg: 9999-12-31T23:59:59.9999999)\");\n\n        [Fact]\n        public void GuidArgumentsAreSupported()\n            => AssertBenchmarkName<SingleGuidArgument>(\"BenchmarkDotNet.Tests.SingleGuidArgument.Method(arg: 00000000-0000-0000-0000-000000000000)\");\n\n        [Fact]\n        public void GenericArgumentsAreSupported()\n            => AssertBenchmarkName<SimpleGeneric<int>>(\"BenchmarkDotNet.Tests.SimpleGeneric<Int32>.Method\");\n\n        [Fact]\n        public void ArraysAreSupported()\n            => AssertBenchmarkName<WithArray>(\"BenchmarkDotNet.Tests.WithArray.Method(array: [1, 2, 3], value: 4)\");\n\n        [Fact]\n        public void UnicodeIsSupported()\n            => AssertBenchmarkName<WithCrazyUnicodeCharacters>(\"BenchmarkDotNet.Tests.WithCrazyUnicodeCharacters.Method(arg1: \\\"\" + \"FOO\" + \"\\\", arg2: \\\"\"+ \"\\u03C3\" + \"\\\", arg3: \\\"\" + \"x\\u0305\" + \"\\\")\");\n\n        [Fact]\n        public void TabsAndEnters()\n            => AssertBenchmarkName<WithTabAndEnter>(\"BenchmarkDotNet.Tests.WithTabAndEnter.Method(tab: \\\"1\\\\t2\\\", enter: \\\"3\\\\r\\\\n4\\\")\");\n\n        [Fact]\n        public void VeryLongArraysAreSupported()\n            => AssertBenchmarkName<WithBigArray>(\"BenchmarkDotNet.Tests.WithBigArray.Method(array: [0, 1, 2, 3, 4, ...])\");\n\n        [Fact]\n        public void ArraysWithNullsAreSupported()\n            => AssertBenchmarkName<WithArrayOfNullStrings>(\"BenchmarkDotNet.Tests.WithArrayOfNullStrings.Method(array: [null, null])\");\n\n        [Fact]\n        public void MultipleParamsAreSupported()\n            => AssertBenchmarkName<WithParameters>(\"BenchmarkDotNet.Tests.WithParameters.Method(Field1: 100, Field2: 200)\");\n\n        [Fact]\n        public void ArgumentsAndParamsUsedTogetherAreSupported()\n            => AssertBenchmarkName<WithArgumentsAndParameters>(\"BenchmarkDotNet.Tests.WithArgumentsAndParameters.Method(arg: \\\"anArgument\\\", Field: 100)\");\n\n        [Fact]\n        public void TypeArgumentsAreWrappedWithTypeofKeywordAndShortTypeNamesAreUsed()\n            => AssertBenchmarkName<WithTypesAsArguments>(\"BenchmarkDotNet.Tests.WithTypesAsArguments.GetConverter(typeToConvert: typeof(bool), expectedConverter: typeof(System.ComponentModel.BooleanConverter))\");\n\n        [Fact]\n        public void NullableTypesAsArgumentsAreSupported()\n            => AssertBenchmarkName<WithNullableTypeAsArgument>(\"BenchmarkDotNet.Tests.WithNullableTypeAsArgument.GetConverter(typeToConvert: typeof(BenchmarkDotNet.Tests.SomeValueType?), expectedConverter: typeof(System.ComponentModel.NullableConverter))\");\n\n        [Fact]\n        public void VoidTypeAsArgumentIsTranslatedToSystemDotVoid()\n            => AssertBenchmarkName<WithVoidTypeAsArgument>(\"BenchmarkDotNet.Tests.WithVoidTypeAsArgument.GetConverter(typeToConvert: typeof(System.Void), expectedConverter: typeof(System.ComponentModel.TypeConverter))\");\n    }\n\n    public class Level0\n    {\n        public class Level1\n        {\n            [Benchmark]\n            public void Method() { }\n\n            public class Level2\n            {\n                [Benchmark]\n                public void Method() { }\n            }\n        }\n    }\n\n    public class SimplestCase\n    {\n        [Benchmark]\n        public void Method() { }\n    }\n\n    public class SingleIntArgument\n    {\n        [Benchmark]\n        [Arguments(1)]\n        public void Method(int arg) { }\n    }\n\n    public class SingleNullArgument\n    {\n        [Benchmark]\n        [Arguments(null)]\n        public void Method(object arg) { }\n    }\n\n    public class SingleEnumArgument\n    {\n        [Benchmark]\n        [Arguments(FileAccess.Read)]\n        public void Method(FileAccess arg) { }\n    }\n\n    public class SingleCharArgument\n    {\n        [Benchmark]\n        [Arguments('c')]\n        public void Method(char arg) { }\n    }\n\n    public class FewStringArguments\n    {\n        [Benchmark]\n        [Arguments(\"a\", \"b\", \"c\", \"d\")]\n        public void Method(string arg1, string arg2, string arg3, string arg4) { }\n    }\n\n    public class SingleDateTimeArgument\n    {\n        [Benchmark]\n        [ArgumentsSource(nameof(Date))]\n        public void Method(DateTime arg) { }\n\n        public IEnumerable<object[]> Date()\n        {\n            yield return new object[] { DateTime.MaxValue };\n        }\n    }\n\n    public class SingleGuidArgument\n    {\n        [Benchmark]\n        [ArgumentsSource(nameof(Guid))]\n        public void Method(Guid arg) { }\n\n        public IEnumerable<object[]> Guid()\n        {\n            yield return new object[] { System.Guid.Empty };\n        }\n    }\n\n    public class WithArray\n    {\n        [Benchmark]\n        [ArgumentsSource(nameof(Data))]\n        public void Method(int[] array, int value) { }\n\n        public IEnumerable<object[]> Data()\n        {\n            yield return new object[] { new int[] { 1, 2, 3 }, 4 };\n        }\n    }\n\n    public class SimpleGeneric<T>\n    {\n        [Benchmark]\n        public T Method() => default!;\n    }\n\n    public class WithCrazyUnicodeCharacters\n    {\n        [Benchmark]\n        [ArgumentsSource(nameof(Data))]\n        public void Method(string arg1, string arg2, string arg3) { }\n\n        public IEnumerable<object[]> Data()\n        {\n            yield return new object[] { \"FOO\", \"\\u03C3\", \"x\\u0305\" }; // https://github.com/Microsoft/xunit-performance/blob/f1d1d62a934694d8cd19063e60e04c590711d904/tests/simpleharness/Program.cs#L29\n        }\n    }\n\n    public class WithTabAndEnter\n    {\n        [Benchmark]\n        [Arguments(\"1\\t2\", \"3\\r\\n4\")]\n        public void Method(string tab, string enter) { }\n    }\n\n    public class WithBigArray\n    {\n        [Benchmark]\n        [ArgumentsSource(nameof(Data))]\n        public void Method(int[] array) { }\n\n        public IEnumerable<object[]> Data()\n        {\n            yield return new object[] { Enumerable.Range(0, 100).ToArray() };\n        }\n    }\n\n    public class WithArrayOfNullStrings\n    {\n        public IEnumerable<object> GetArrayOfStrings()\n        {\n            yield return new string[2];\n        }\n\n        [Benchmark]\n        [ArgumentsSource(nameof(GetArrayOfStrings))]\n        public int Method(string[] array) => array.Length;\n    }\n\n    public class WithParameters\n    {\n        [Params(100)]\n        public int Field1;\n\n        [Params(200)]\n        public int Field2;\n\n        [Benchmark]\n        public int Method() => Field1 + Field2;\n    }\n\n    public class WithArgumentsAndParameters\n    {\n        [Params(100)]\n        public int Field;\n\n        [Benchmark]\n        [Arguments(\"anArgument\")]\n        public int Method(string arg) => Field;\n    }\n\n    public class WithTypesAsArguments\n    {\n        [Benchmark]\n        [Arguments(typeof(bool), typeof(BooleanConverter))]\n        public TypeConverter GetConverter(Type typeToConvert, Type expectedConverter) => TypeDescriptor.GetConverter(typeToConvert);\n    }\n\n    public class WithNullableTypeAsArgument\n    {\n        [Benchmark]\n        [Arguments(typeof(SomeValueType?), typeof(NullableConverter))]\n        public TypeConverter GetConverter(Type typeToConvert, Type expectedConverter) => TypeDescriptor.GetConverter(typeToConvert);\n    }\n\n    public struct SomeValueType { }\n\n    public class WithVoidTypeAsArgument\n    {\n        [Benchmark]\n        [Arguments(typeof(void), typeof(TypeConverter))]\n        public TypeConverter GetConverter(Type typeToConvert, Type expectedConverter) => TypeDescriptor.GetConverter(typeToConvert);\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/GenericBuilderTests.cs",
    "content": "﻿using System;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Helpers;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests\n{\n    public class GenericBuilderTests\n    {\n        [Fact]\n        public void TestBuildGenericWithOneArgument()\n        {\n            var types = GenericBenchmarksBuilder.GetRunnableBenchmarks([typeof(OneArgGenericBenchmark<>)]);\n\n            Assert.Equal(2, types.Length);\n            Assert.Single(types, typeof(OneArgGenericBenchmark<int>));\n            Assert.Single(types, typeof(OneArgGenericBenchmark<char>));\n        }\n\n        [GenericTypeArguments(typeof(int))]\n        [GenericTypeArguments(typeof(char))]\n        public class OneArgGenericBenchmark<T>\n        {\n            [Benchmark] public T CreateT() => Activator.CreateInstance<T>();\n        }\n\n        [Fact]\n        public void TestBuildGenericWithTwoArguments()\n        {\n            var types = GenericBenchmarksBuilder.GetRunnableBenchmarks([typeof(TwoArgGenericBenchmark<,>)]);\n\n            Assert.Equal(2, types.Length);\n            Assert.Single(types, typeof(TwoArgGenericBenchmark<int, char>));\n            Assert.Single(types, typeof(TwoArgGenericBenchmark<char, string>));\n        }\n\n        [GenericTypeArguments(typeof(int), typeof(char))]\n        [GenericTypeArguments(typeof(char), typeof(string))]\n        public class TwoArgGenericBenchmark<T1, T2>\n        {\n            [Benchmark] public T1 CreateT1() => Activator.CreateInstance<T1>();\n\n            [Benchmark] public T2 CreateT2() => Activator.CreateInstance<T2>();\n        }\n\n        [Fact]\n        public void TestBuildGenericWithThreeArguments()\n        {\n            var types = GenericBenchmarksBuilder.GetRunnableBenchmarks([typeof(ThreeArgGenericBenchmark<,,>)]);\n\n            Assert.Equal(2, types.Length);\n            Assert.Single(types, typeof(ThreeArgGenericBenchmark<int, char, string>));\n            Assert.Single(types, typeof(ThreeArgGenericBenchmark<char, string, byte>));\n        }\n\n        [GenericTypeArguments(typeof(int), typeof(char),  typeof(string))]\n        [GenericTypeArguments(typeof(char), typeof(string), typeof(byte))]\n        public class ThreeArgGenericBenchmark<T1, T2, T3>\n        {\n            [Benchmark] public T1 CreateT1() => Activator.CreateInstance<T1>();\n\n            [Benchmark] public T2 CreateT2() => Activator.CreateInstance<T2>();\n\n            [Benchmark] public T3 CreateT3() => Activator.CreateInstance<T3>();\n        }\n\n        [Fact]\n        public void TestBuildGenericWithWrongAttributes()\n        {\n            var types = GenericBenchmarksBuilder.GetRunnableBenchmarks([typeof(GenericBenchmarkWithWrongAttribute<,>)]);\n\n            Assert.Equal(2, types.Length);\n            Assert.Single(types, typeof(GenericBenchmarkWithWrongAttribute<int, char>));\n            Assert.Single(types, typeof(GenericBenchmarkWithWrongAttribute<char, string>));\n        }\n\n        [GenericTypeArguments(typeof(int), typeof(char))]\n        [GenericTypeArguments(typeof(char), typeof(string))]\n#pragma warning disable BDN1102\n        [GenericTypeArguments(typeof(char))]\n#pragma warning restore BDN1102\n        public class GenericBenchmarkWithWrongAttribute<T1, T2>\n        {\n            [Benchmark] public T1 CreateT1() => Activator.CreateInstance<T1>();\n\n            [Benchmark] public T2 CreateT2() => Activator.CreateInstance<T2>();\n        }\n\n        [Fact]\n        public void TestBuildGenericWithConstraints()\n        {\n            var types = GenericBenchmarksBuilder.GetRunnableBenchmarks([typeof(GenericBenchmarkWithConstraints<,>)]);\n\n            Assert.Equal(2, types.Length);\n            Assert.Single(types, typeof(GenericBenchmarkWithConstraints<int, char>));\n            Assert.Single(types, typeof(GenericBenchmarkWithConstraints<char, byte>));\n        }\n\n        [GenericTypeArguments(typeof(int), typeof(char))]\n        [GenericTypeArguments(typeof(char), typeof(byte))]\n        public class GenericBenchmarkWithConstraints<T1, T2> where T1 : struct\n            where T2 : struct\n        {\n            [Benchmark] public T1 CreateT1() => Activator.CreateInstance<T1>();\n\n            [Benchmark] public T2 CreateT2() => Activator.CreateInstance<T2>();\n        }\n\n        [Fact]\n        public void TestBuildGenericWithConstraintsWrongArgs()\n        {\n            var types = GenericBenchmarksBuilder.GetRunnableBenchmarks([typeof(GenericBenchmarkWithConstraintsWrongArgs<,>)]);\n\n            Assert.Single(types);\n            Assert.Single(types, typeof(GenericBenchmarkWithConstraintsWrongArgs<int, char>));\n        }\n\n        [GenericTypeArguments(typeof(int), typeof(char))]\n        [GenericTypeArguments(typeof(char), typeof(string))]\n        public class GenericBenchmarkWithConstraintsWrongArgs<T1, T2> where T1 : struct\n            where T2 : struct\n        {\n            [Benchmark] public T1 CreateT1() => Activator.CreateInstance<T1>();\n\n            [Benchmark] public T2 CreateT2() => Activator.CreateInstance<T2>();\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/GlobFilterTests.cs",
    "content": "﻿using System.Linq;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Filters;\nusing BenchmarkDotNet.Running;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests\n{\n    public class GlobFilterTests\n    {\n        [Theory]\n        [InlineData(nameof(TypeWithBenchmarks), false)] // type name\n        [InlineData(\"typewithbenchmarks\", false)] // type name lowercase\n        [InlineData(\"TYPEWITHBENCHMARKS\", false)] // type name uppercase\n        [InlineData(\"*TypeWithBenchmarks*\", true)] // regular expression\n        [InlineData(\"*typewithbenchmarks*\", true)] // regular expression lowercase\n        [InlineData(\"*TYPEWITHBENCHMARKS*\", true)] // regular expression uppercase\n        [InlineData(\"*\", true)]\n        [InlineData(\"WRONG\", false)]\n        [InlineData(\"*stillWRONG*\", false)]\n        public void TheFilterIsCaseInsensitive(string pattern, bool expected)\n        {\n            var benchmarkCase  = BenchmarkConverter.TypeToBenchmarks(typeof(TypeWithBenchmarks)).BenchmarksCases.Single();\n\n            var filter = new GlobFilter([pattern]);\n\n            Assert.Equal(expected, filter.Predicate(benchmarkCase));\n        }\n\n        [Theory]\n        [InlineData(nameof(TypeWithBenchmarksAndParams), 0)] // type name\n        [InlineData(\"typewithbenchmarksandparams\", 0)] // type name lowercase\n        [InlineData(\"TYPEWITHBENCHMARKSANDPARAMS\", 0)] // type name uppercase\n        [InlineData(\"*TypeWithBenchmarksAndParams*\", 2)] // regular expression\n        [InlineData(\"*typewithbenchmarksandparams*\", 2)] // regular expression lowercase\n        [InlineData(\"*TYPEWITHBENCHMARKSANDPARAMS*\", 2)] // regular expression uppercase\n        [InlineData(\"*\", 2)]\n        [InlineData(\"WRONG\", 0)]\n        [InlineData(\"*stillWRONG*\", 0)]\n        [InlineData(\"BenchmarkDotNet.Tests.TypeWithBenchmarksAndParams.TheBenchmark\", 2)]\n        [InlineData(\"BenchmarkDotNet.Tests.TypeWithBenchmarksAndParams.TheBenchmark(A: 100)\", 1)]\n        public void TheFilterWorksWithParams(string pattern, int expectedBenchmarks)\n        {\n            var benchmarkCases = BenchmarkConverter.TypeToBenchmarks(typeof(TypeWithBenchmarksAndParams)).BenchmarksCases;\n\n            var filter = new GlobFilter([pattern]);\n\n            Assert.Equal(expectedBenchmarks, benchmarkCases.Where(benchmarkCase => filter.Predicate(benchmarkCase)).Count());\n        }\n    }\n\n    public class TypeWithBenchmarks\n    {\n        [Benchmark] public void TheBenchmark() { }\n    }\n\n    public class TypeWithBenchmarksAndParams\n    {\n        [Params(100, 200)]\n        public int A { get; set; }\n\n        [Benchmark] public void TheBenchmark() { }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Helpers/LinuxOsReleaseHelperTests.cs",
    "content": "using System;\nusing BenchmarkDotNet.Helpers;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests.Helpers\n{\n    public class LinuxOsReleaseHelperTests\n    {\n        [Theory]\n        [InlineData(\"\"\"\n                    NAME=\"Ubuntu\"\n                    VERSION=\"20.04.1 LTS (Focal Fossa)\"\n                    ID=ubuntu\n                    ID_LIKE=debian\n                    PRETTY_NAME=\"Ubuntu 20.04.1 LTS\"\n                    VERSION_ID=\"20.04\"\n                    HOME_URL=\"https://www.ubuntu.com/\"\n                    SUPPORT_URL=\"https://help.ubuntu.com/\"\n                    BUG_REPORT_URL=\"https://bugs.launchpad.net/ubuntu/\"\n                    PRIVACY_POLICY_URL=\"https://www.ubuntu.com/legal/terms-and-policies/privacy-policy\"\n                    VERSION_CODENAME=focal\n                    UBUNTU_CODENAME=focal\n                    \"\"\", \"Ubuntu 20.04.1 LTS (Focal Fossa)\")]\n        [InlineData(\"\"\"\n                    PRETTY_NAME=\"Debian GNU/Linux 10 (buster)\"\n                    NAME=\"Debian GNU/Linux\"\n                    VERSION_ID=\"10\"\n                    VERSION=\"10 (buster)\"\n                    VERSION_CODENAME=buster\n                    ID=debian\n                    HOME_URL=\"https://www.debian.org/\"\n                    SUPPORT_URL=\"https://www.debian.org/support\"\n                    BUG_REPORT_URL=\"https://bugs.debian.org/\"\n                    \"\"\", \"Debian GNU/Linux 10 (buster)\")]\n        [InlineData(\"\"\"\n                    NAME=Fedora\n                    VERSION=\"32 (Thirty Two)\"\n                    ID=fedora\n                    VERSION_ID=32\n                    VERSION_CODENAME=\"\"\n                    PLATFORM_ID=\"platform:f32\"\n                    PRETTY_NAME=\"Fedora 32 (Thirty Two)\"\n                    ANSI_COLOR=\"0;34\"\n                    LOGO=fedora-logo-icon\n                    CPE_NAME=\"cpe:/o:fedoraproject:fedora:32\"\n                    HOME_URL=\"https://fedoraproject.org/\"\n                    DOCUMENTATION_URL=\"https://docs.fedoraproject.org/en-US/fedora/f32/system-administrators-guide/\"\n                    SUPPORT_URL=\"https://fedoraproject.org/wiki/Communicating_and_getting_help\"\n                    BUG_REPORT_URL=\"https://bugzilla.redhat.com/\"\n                    REDHAT_BUGZILLA_PRODUCT=\"Fedora\"\n                    REDHAT_BUGZILLA_PRODUCT_VERSION=32\n                    REDHAT_SUPPORT_PRODUCT=\"Fedora\"\n                    REDHAT_SUPPORT_PRODUCT_VERSION=32\n                    PRIVACY_POLICY_URL=\"https://fedoraproject.org/wiki/Legal:PrivacyPolicy\"\n                    \"\"\", \"Fedora 32 (Thirty Two)\")]\n        [InlineData(\"\"\"\n                    NAME=\"CentOS Linux\"\n                    VERSION=\"8 (Core)\"\n                    ID=\"centos\"\n                    ID_LIKE=\"rhel fedora\"\n                    VERSION_ID=\"8\"\n                    PLATFORM_ID=\"platform:el8\"\n                    PRETTY_NAME=\"CentOS Linux 8 (Core)\"\n                    ANSI_COLOR=\"0;31\"\n                    CPE_NAME=\"cpe:/o:centos:centos:8\"\n                    HOME_URL=\"https://www.centos.org/\"\n                    BUG_REPORT_URL=\"https://bugs.centos.org/\"\n\n                    CENTOS_MANTISBT_PROJECT=\"CentOS-8\"\n                    CENTOS_MANTISBT_PROJECT_VERSION=\"8\"\n                    REDHAT_SUPPORT_PRODUCT=\"centos\"\n                    REDHAT_SUPPORT_PRODUCT_VERSION=\"8\"\n                    \"\"\", \"CentOS Linux 8 (Core)\")]\n        [InlineData(\"\"\"\n                    NAME=\"Arch Linux\"\n                    PRETTY_NAME=\"Arch Linux\"\n                    ID=arch\n                    BUILD_ID=rolling\n                    ANSI_COLOR=\"38;2;23;147;209\"\n                    HOME_URL=\"https://archlinux.org/\"\n                    DOCUMENTATION_URL=\"https://wiki.archlinux.org/\"\n                    SUPPORT_URL=\"https://bbs.archlinux.org/\"\n                    BUG_REPORT_URL=\"https://bugs.archlinux.org/\"\n                    LOGO=archlinux\n                    \"\"\", \"Arch Linux\")]\n        [InlineData(\"\"\"\n                    NAME=\"openSUSE Leap\"\n                    VERSION=\"15.2\"\n                    ID=\"opensuse-leap\"\n                    ID_LIKE=\"suse opensuse\"\n                    VERSION_ID=\"15.2\"\n                    PRETTY_NAME=\"openSUSE Leap 15.2\"\n                    ANSI_COLOR=\"0;32\"\n                    CPE_NAME=\"cpe:/o:opensuse:leap:15.2\"\n                    BUG_REPORT_URL=\"https://bugs.opensuse.org\"\n                    HOME_URL=\"https://www.opensuse.org/\"\n                    \"\"\", \"openSUSE Leap 15.2\")]\n        [InlineData(\"\"\"\n                    NAME=\"Manjaro Linux\"\n                    ID=manjaro\n                    PRETTY_NAME=\"Manjaro Linux\"\n                    ANSI_COLOR=\"1;32\"\n                    HOME_URL=\"https://manjaro.org/\"\n                    SUPPORT_URL=\"https://manjaro.org/\"\n                    BUG_REPORT_URL=\"https://bugs.manjaro.org/\"\n                    LOGO=manjarolinux\n                    \"\"\", \"Manjaro Linux\")]\n        [InlineData(\"\"\"\n                    NAME=\"Linux Mint\"\n                    VERSION=\"20 (Ulyana)\"\n                    ID=linuxmint\n                    ID_LIKE=ubuntu\n                    PRETTY_NAME=\"Linux Mint 20\"\n                    VERSION_ID=\"20\"\n                    HOME_URL=\"https://www.linuxmint.com/\"\n                    SUPPORT_URL=\"https://forums.linuxmint.com/\"\n                    BUG_REPORT_URL=\"http://linuxmint-troubleshooting-guide.readthedocs.io/en/latest/\"\n                    PRIVACY_POLICY_URL=\"https://www.linuxmint.com/\"\n                    VERSION_CODENAME=ulyana\n                    UBUNTU_CODENAME=focal\n                    \"\"\", \"Linux Mint 20 (Ulyana)\")]\n        [InlineData(\"\"\"\n                    NAME=\"Alpine Linux\"\n                    ID=alpine\n                    VERSION_ID=3.12.0\n                    PRETTY_NAME=\"Alpine Linux v3.12\"\n                    HOME_URL=\"https://alpinelinux.org/\"\n                    BUG_REPORT_URL=\"https://bugs.alpinelinux.org/\"\n                    \"\"\", \"Alpine Linux v3.12\")]\n        [InlineData(\"\"\"\n                    NAME=\"Solus\"\n                    VERSION=\"4.1\"\n                    ID=\"solus\"\n                    PRETTY_NAME=\"Solus\"\n                    ANSI_COLOR=\"1;34\"\n                    HOME_URL=\"https://getsol.us\"\n                    SUPPORT_URL=\"https://getsol.us/articles/contributing/getting-involved/en/\"\n                    BUG_REPORT_URL=\"https://dev.getsol.us/\"\n                    \"\"\", \"Solus 4.1\")]\n        [InlineData(\"\"\"\n                    NAME=\"Red Hat Enterprise Linux\"\n                    VERSION=\"8.2 (Ootpa)\"\n                    ID=\"rhel\"\n                    ID_LIKE=\"fedora\"\n                    VERSION_ID=\"8.2\"\n                    PLATFORM_ID=\"platform:el8\"\n                    PRETTY_NAME=\"Red Hat Enterprise Linux 8.2 (Ootpa)\"\n                    ANSI_COLOR=\"0;31\"\n                    CPE_NAME=\"cpe:/o:redhat:enterprise_linux:8.2:GA\"\n                    HOME_URL=\"https://www.redhat.com/\"\n                    BUG_REPORT_URL=\"https://bugzilla.redhat.com/\"\n                    REDHAT_BUGZILLA_PRODUCT=\"Red Hat Enterprise Linux 8\"\n                    REDHAT_BUGZILLA_PRODUCT_VERSION=8.2\n                    REDHAT_SUPPORT_PRODUCT=\"Red Hat Enterprise Linux\"\n                    REDHAT_SUPPORT_PRODUCT_VERSION=\"8.2\"\n                    \"\"\", \"Red Hat Enterprise Linux 8.2 (Ootpa)\")]\n        [InlineData(\"\"\"\n                    PRETTY_NAME=\"Kali GNU/Linux Rolling\"\n                    NAME=\"Kali GNU/Linux\"\n                    ID=kali\n                    VERSION=\"2020.2\"\n                    VERSION_ID=\"2020.2\"\n                    VERSION_CODENAME=\"kali-rolling\"\n                    ID_LIKE=debian\n                    ANSI_COLOR=\"1;31\"\n                    HOME_URL=\"https://www.kali.org/\"\n                    SUPPORT_URL=\"https://forums.kali.org/\"\n                    BUG_REPORT_URL=\"https://bugs.kali.org/\"\n                    \"\"\", \"Kali GNU/Linux 2020.2\")]\n        [InlineData(\"\"\"\n                    NAME=\"elementary OS\"\n                    VERSION=\"5.1.7 Hera\"\n                    ID=elementary\n                    ID_LIKE=ubuntu\n                    PRETTY_NAME=\"elementary OS 5.1.7 Hera\"\n                    LOGO=distributor-logo\n                    VERSION_ID=\"5.1.7\"\n                    HOME_URL=\"https://elementary.io/\"\n                    SUPPORT_URL=\"https://elementary.io/support\"\n                    BUG_REPORT_URL=\"https://github.com/elementary/os/issues/new\"\n                    PRIVACY_POLICY_URL=\"https://elementary.io/privacy-policy\"\n                    VERSION_CODENAME=hera\n                    UBUNTU_CODENAME=bionic\n                    \"\"\", \"elementary OS 5.1.7 Hera\")]\n        [InlineData(\"\"\"\n                    NAME=\"Zorin OS\"\n                    VERSION=\"15.2\"\n                    ID=zorin\n                    ID_LIKE=ubuntu\n                    PRETTY_NAME=\"Zorin OS 15.2\"\n                    VERSION_ID=\"15\"\n                    HOME_URL=\"https://www.zorinos.com/\"\n                    SUPPORT_URL=\"https://www.zorinos.com/help\"\n                    BUG_REPORT_URL=\"https://www.zorinos.com/contact\"\n                    PRIVACY_POLICY_URL=\"https://www.zorinos.com/legal/privacy\"\n                    VERSION_CODENAME=bionic\n                    UBUNTU_CODENAME=bionic\n                    \"\"\", \"Zorin OS 15.2\")]\n        public void LinuxOsReleaseHelperTest(string osReleaseContent, string expectedName)\n        {\n            string[] lines = osReleaseContent.Split(['\\r', '\\n'], StringSplitOptions.RemoveEmptyEntries);\n            string? actualName = LinuxOsReleaseHelper.GetNameByOsRelease(lines);\n            Assert.Equal(expectedName, actualName);\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Infra/VerifyHelper.cs",
    "content": "﻿using VerifyTests;\n\nnamespace BenchmarkDotNet.Tests.Infra;\n\npublic static class VerifyHelper\n{\n    public static VerifySettings Create(string? typeName = null)\n    {\n        var result = new VerifySettings();\n        result.UseDirectory(\"VerifiedFiles\");\n        result.DisableDiff();\n        if (typeName != null)\n            result.UseTypeName(typeName);\n        return result;\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Jobs/JobIdGeneratorTests.cs",
    "content": "﻿using BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Toolchains.CsProj;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests.Jobs;\n\npublic class JobIdGeneratorTests\n{\n    [Theory]\n    [MemberData(nameof(GetTheoryData), DisableDiscoveryEnumeration = true)]\n    public void AutoGenerateJobId(string expectedId, Job job)\n    {\n        // Act\n        var result = job.ResolvedId;\n\n        // Assert\n        Assert.Equal(expectedId, result);\n    }\n\n    public static TheoryData<string, Job> GetTheoryData() => new TheoryData<string, Job>()\n    {\n        {\"Job-OOTPKI\", Job.Default.WithToolchain(CsProjCoreToolchain.NetCoreApp80) },\n        {\"Job-QAODSR\", Job.Default.WithToolchain(CsProjCoreToolchain.NetCoreApp90) },\n        {\"Job-KHMDUZ\", Job.Default.WithToolchain(CsProjCoreToolchain.NetCoreApp80).WithRuntime(CoreRuntime.Core80) },\n    };\n}\n"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Jobs/JobIdTests.cs",
    "content": "﻿using BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Jobs;\nusing System.Linq;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests.Jobs;\n\npublic class JobIdTests\n{\n    [Theory]\n    [MemberData(nameof(GetTheoryData), DisableDiscoveryEnumeration = true)]\n    public void AutoGenerateJobId(string expectedId, Job job)\n    {\n        // Act\n        var result = job.ResolvedId;\n\n        // Assert\n        Assert.Equal(expectedId, result);\n    }\n\n    public static TheoryData<string, Job> GetTheoryData() => new()\n    {\n        {\"InProcess\", Job.InProcess },\n\n        // If baseJob don't have id. Set \"InProcess\".\n        {\"InProcess\", InProcessAttribute.GetJob(Job.Default, InProcessToolchainType.Auto, true) },\n\n        // If baseJob has exisiting id, it should not be overwritten.\n        {\"Dry\", InProcessAttribute.GetJob(Job.Dry, InProcessToolchainType.Auto, true) },\n    };\n}\n"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/KnownIssue.cs",
    "content": "namespace BenchmarkDotNet.Tests\n{\n    public class KnownIssue\n    {\n        public static KnownIssue Issue2299 => new(2299, \"Non-supported Mono on Linux\", false);\n\n        public int Number { get; }\n        public string Description { get; }\n        public bool IsFixed { get; }\n\n        public KnownIssue(int number, string description, bool isFixed)\n        {\n            Number = number;\n            Description = description;\n            IsFixed = isFixed;\n        }\n\n        public string IgnoreMessage => $\"This test is ignored because of the issue #{Number} '{Description}'\";\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/LevenshteinDistanceCalculatorTests.cs",
    "content": "using BenchmarkDotNet.ConsoleArguments;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests\n{\n    public class LevenshteinDistanceCalculatorTests\n    {\n        private readonly LevenshteinDistanceCalculator calculator;\n\n        public LevenshteinDistanceCalculatorTests()\n        {\n            calculator = new LevenshteinDistanceCalculator();\n        }\n\n        [Fact]\n        public void EmptyEmpty()\n        {\n            Assert.Equal(0, calculator.Calculate(\"\", \"\"));\n        }\n\n        [Fact]\n        public void SelfSelf()\n        {\n            Assert.Equal(0, calculator.Calculate(\"string\", \"string\"));\n        }\n\n        [Fact]\n        public void TheOnlyDifference()\n        {\n            Assert.Equal(1, calculator.Calculate(\"strng\", \"string\"));\n        }\n\n        [Fact]\n        public void AllDifferences()\n        {\n            Assert.Equal(5, calculator.Calculate(\"abcde\", \"fghij\"));\n        }\n\n        [Fact]\n        public void EmptyString()\n        {\n            Assert.Equal(5, calculator.Calculate(\"\", \"fghij\"));\n        }\n\n        [Fact]\n        public void Symmetric()\n        {\n            string first = \"first\";\n            string second = \"second\";\n            Assert.Equal(calculator.Calculate(first, second), calculator.Calculate(second, first));\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Loggers/LoggerWithPrefixTests.cs",
    "content": "using System;\nusing BenchmarkDotNet.Loggers;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests.Loggers\n{\n    public class LoggerWithPrefixTests\n    {\n        private readonly LoggerWithPrefix loggerWithPrefix;\n        private readonly AccumulationLogger logger;\n\n        public LoggerWithPrefixTests()\n        {\n            logger = new AccumulationLogger();\n            loggerWithPrefix = new LoggerWithPrefix(logger, \"prefix\");\n        }\n\n        [Fact]\n        public void Write()\n        {\n            loggerWithPrefix.Write(\"1\");\n            loggerWithPrefix.Write(\"2\");\n            Assert.Equal(\"prefix12\", logger.GetLog());\n        }\n\n        [Fact]\n        public void WriteLine()\n        {\n            loggerWithPrefix.WriteLine(\"1\");\n            loggerWithPrefix.WriteLine(\"2\");\n            Assert.Equal($\"prefix1{Environment.NewLine}prefix2{Environment.NewLine}\", logger.GetLog());\n        }\n\n        [Fact]\n        public void Write_EmptyLine()\n        {\n            loggerWithPrefix.Write(string.Empty);\n            loggerWithPrefix.Write(string.Empty);\n            Assert.Equal(string.Empty, logger.GetLog());\n        }\n\n        [Fact]\n        public void WriteLine_EmptyLine()\n        {\n            loggerWithPrefix.WriteLine(string.Empty);\n            loggerWithPrefix.WriteLine(string.Empty);\n            Assert.Equal($\"{Environment.NewLine}{Environment.NewLine}\", logger.GetLog());\n        }\n\n        [Fact]\n        public void WriteLineWithoutArg()\n        {\n            loggerWithPrefix.WriteLine();\n            loggerWithPrefix.WriteLine();\n            Assert.Equal($\"{Environment.NewLine}{Environment.NewLine}\", logger.GetLog());\n        }\n\n        [Fact]\n        public void Write_StringWithOneNewLine()\n        {\n            loggerWithPrefix.Write($\"1{Environment.NewLine}2\");\n            Assert.Equal($\"prefix1{Environment.NewLine}prefix2\", logger.GetLog());\n        }\n\n        [Fact]\n        public void WriteLine_StringWithNewLine()\n        {\n            loggerWithPrefix.WriteLine($\"1{Environment.NewLine}2\");\n            Assert.Equal($\"prefix1{Environment.NewLine}prefix2{Environment.NewLine}\", logger.GetLog());\n        }\n\n        [Fact]\n        public void Write_StringWithMultipleNewLine()\n        {\n            loggerWithPrefix.Write($\"1{Environment.NewLine}2{Environment.NewLine}3\");\n            Assert.Equal($\"prefix1{Environment.NewLine}prefix2{Environment.NewLine}prefix3\", logger.GetLog());\n        }\n\n        [Fact]\n        public void WriteLine_StringWithMultipleNewLine()\n        {\n            loggerWithPrefix.WriteLine($\"1{Environment.NewLine}2{Environment.NewLine}3\");\n            Assert.Equal($\"prefix1{Environment.NewLine}prefix2{Environment.NewLine}prefix3{Environment.NewLine}\", logger.GetLog());\n        }\n\n        [Fact]\n        public void Write_StringWithEmptyNewLine()\n        {\n            loggerWithPrefix.Write($\"1{Environment.NewLine}{Environment.NewLine}2\");\n            Assert.Equal($\"prefix1{Environment.NewLine}{Environment.NewLine}prefix2\", logger.GetLog());\n        }\n\n        [Fact]\n        public void WriteLine_StringWithEmptyNewLine()\n        {\n            loggerWithPrefix.WriteLine($\"1{Environment.NewLine}{Environment.NewLine}2\");\n            Assert.Equal($\"prefix1{Environment.NewLine}{Environment.NewLine}prefix2{Environment.NewLine}\", logger.GetLog());\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Loggers/OutputLogger.cs",
    "content": "﻿using System;\nusing System.Runtime.CompilerServices;\nusing BenchmarkDotNet.Loggers;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.Tests.Loggers\n{\n    public class OutputLogger : AccumulationLogger\n    {\n        private readonly ITestOutputHelper testOutputHelper;\n        private string currentLine = \"\";\n\n        public OutputLogger(ITestOutputHelper testOutputHelper)\n        {\n            this.testOutputHelper = testOutputHelper ?? throw new ArgumentNullException(nameof(testOutputHelper));\n        }\n\n        [MethodImpl(MethodImplOptions.Synchronized)]\n        public override void Write(LogKind logKind, string text)\n        {\n            currentLine += text;\n            base.Write(logKind, text);\n        }\n\n        [MethodImpl(MethodImplOptions.Synchronized)]\n        public override void WriteLine()\n        {\n            testOutputHelper.WriteLine(currentLine);\n            currentLine = \"\";\n            base.WriteLine();\n        }\n\n        [MethodImpl(MethodImplOptions.Synchronized)]\n        public override void WriteLine(LogKind logKind, string text)\n        {\n            testOutputHelper.WriteLine(currentLine + text);\n            currentLine = \"\";\n            base.WriteLine(logKind, text);\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Mathematics/NumeralSystemTests.cs",
    "content": "﻿using BenchmarkDotNet.Mathematics;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests.Mathematics\n{\n    public class NumeralSystemTests\n    {\n        [Fact]\n        public void ArabicTest()\n        {\n            Check(NumeralSystem.Arabic, [\"1\", \"2\", \"3\", \"4\", \"5\"]);\n        }\n\n        [Fact]\n        public void StarsTest()\n        {\n            Check(NumeralSystem.Stars, [\"*\", \"**\", \"***\", \"****\", \"*****\"]);\n        }\n\n        [Fact]\n        public void RomanTest()\n        {\n            Check(NumeralSystem.Roman, [\"I\", \"II\", \"III\", \"IV\", \"V\", \"VI\", \"VII\", \"VIII\", \"IX\", \"X\"]);\n        }\n\n        private static void Check(NumeralSystem system, string[] expected)\n        {\n            for (int i = 1; i <= expected.Length; i++)\n                Assert.Equal(expected[i - 1], system.ToPresentation(i));\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Mathematics/RankTests.cs",
    "content": "﻿using BenchmarkDotNet.Mathematics;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests.Mathematics\n{\n    public class RankTests\n    {\n        [Fact]\n        public void RankTest()\n        {\n            var s1 = new Statistics(100, 101, 100, 101, 100, 101, 100, 101, 100, 101, 100, 101, 100, 101, 100, 101, 100, 101, 100, 101);\n            var s2 = new Statistics(300, 301, 300, 301, 300, 301, 300, 301, 300, 301, 300, 301, 300, 301, 300, 301, 300, 301, 300, 301);\n            var s3 = new Statistics(200.3279, 200.3178, 200.4046, 200.3279, 200.3178, 200.4046, 200.3279, 200.3178, 200.4046, 200.3279, 200.3178, 200.4046);\n            var s4 = new Statistics(200.2298, 200.5738, 200.3582, 200.2298, 200.5738, 200.3582, 200.2298, 200.5738, 200.3582, 200.2298, 200.5738, 200.3582);\n            var s5 = new Statistics(195, 196, 195, 196, 195, 196, 195, 196, 195, 196, 195, 196, 195, 196, 195, 196, 195, 196, 195, 196);\n            int[] actualRanks = RankHelper.GetRanks(s1, s2, s3, s4, s5);\n            int[] expectedRanks = [1, 4, 3, 3, 2];\n            Assert.Equal(expectedRanks, actualRanks);\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Mathematics/RatioStatisticsTests.cs",
    "content": "﻿using BenchmarkDotNet.Mathematics;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests.Mathematics;\n\npublic class RatioStatisticsTests\n{\n    [Fact]\n    public void SelfDivisionTest()\n    {\n        var stat = new Statistics(100, 200, 300);\n\n        var divided = new RatioStatistics(stat, stat);\n\n        Assert.Equal(1, divided.Mean);\n        Assert.Equal(0, divided.StandardDeviation);\n    }\n}\n"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Mathematics/StatisticsTests.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing BenchmarkDotNet.Mathematics;\nusing BenchmarkDotNet.Tests.Common;\nusing JetBrains.Annotations;\nusing Pragmastat.Exceptions;\nusing Xunit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.Tests.Mathematics;\n\npublic class StatisticsTests(ITestOutputHelper output)\n{\n    private void Print(Statistics summary)\n    {\n        output.WriteLine(\"N = \" + summary.N);\n        output.WriteLine(\"Min = \" + summary.Min);\n        output.WriteLine(\"LowerFence = \" + summary.LowerFence);\n        output.WriteLine(\"Q1 = \" + summary.Q1);\n        output.WriteLine(\"Median = \" + summary.Median);\n        output.WriteLine(\"Mean = \" + summary.Mean);\n        output.WriteLine(\"Q3 = \" + summary.Q3);\n        output.WriteLine(\"UpperFence = \" + summary.UpperFence);\n        output.WriteLine(\"Max = \" + summary.Max);\n        output.WriteLine(\"InterquartileRange = \" + summary.InterquartileRange);\n        output.WriteLine(\"StandardDeviation = \" + summary.StandardDeviation);\n        output.WriteLine(\"Outlier = [\" + string.Join(\"; \", summary.AllOutliers) + \"]\");\n        output.WriteLine(\"CI = \" + summary.PerfolizerConfidenceInterval.ToString(TestCultureInfo.Instance));\n        output.WriteLine(\"Percentiles = \" + summary.Percentiles.ToString(TestCultureInfo.Instance));\n    }\n\n    [Fact]\n    public void StatisticsWithN0Test()\n    {\n        Assert.Throws<AssumptionException>(() => new Statistics());\n    }\n\n    [Fact]\n    public void StatisticsWithN1Test()\n    {\n        var summary = new Statistics(1);\n        Print(summary);\n        AssertEqual(1, summary.Min);\n        AssertEqual(1, summary.LowerFence);\n        AssertEqual(1, summary.Q1);\n        AssertEqual(1, summary.Median);\n        AssertEqual(1, summary.Mean);\n        AssertEqual(1, summary.Q3);\n        AssertEqual(1, summary.UpperFence);\n        AssertEqual(1, summary.Max);\n        AssertEqual(0, summary.InterquartileRange);\n        AssertEqual(0, summary.StandardDeviation);\n        AssertEqual([], summary.AllOutliers);\n        AssertEqual(1, summary.Percentiles.P0);\n        AssertEqual(1, summary.Percentiles.P25);\n        AssertEqual(1, summary.Percentiles.P50);\n        AssertEqual(1, summary.Percentiles.P85);\n        AssertEqual(1, summary.Percentiles.P95);\n        AssertEqual(1, summary.Percentiles.P100);\n    }\n\n    [Fact]\n    public void StatisticsWithN2Test()\n    {\n        var summary = new Statistics(1, 2);\n        Print(summary);\n        AssertEqual(1, summary.Min);\n        AssertEqual(0.5, summary.LowerFence);\n        AssertEqual(1.25, summary.Q1);\n        AssertEqual(1.5, summary.Median);\n        AssertEqual(1.5, summary.Mean);\n        AssertEqual(1.75, summary.Q3);\n        AssertEqual(2.5, summary.UpperFence);\n        AssertEqual(2, summary.Max);\n        AssertEqual(0.5, summary.InterquartileRange);\n        AssertEqual(0.70711, summary.StandardDeviation, AbsoluteEqualityComparer.E4);\n        AssertEqual([], summary.AllOutliers);\n        AssertEqual(1, summary.Percentiles.P0);\n        AssertEqual(1.25, summary.Percentiles.P25);\n        AssertEqual(1.5, summary.Percentiles.P50);\n        AssertEqual(1.85, summary.Percentiles.P85);\n        AssertEqual(1.95, summary.Percentiles.P95);\n        AssertEqual(2, summary.Percentiles.P100);\n    }\n\n    [Fact]\n    public void StatisticsWithN3Test()\n    {\n        var summary = new Statistics(1, 2, 4);\n        Print(summary);\n        AssertEqual(1, summary.Min);\n        AssertEqual(-0.75, summary.LowerFence);\n        AssertEqual(1.5, summary.Q1);\n        AssertEqual(2, summary.Median);\n        AssertEqual(2.333333, summary.Mean, AbsoluteEqualityComparer.E4);\n        AssertEqual(3, summary.Q3);\n        AssertEqual(5.25, summary.UpperFence);\n        AssertEqual(4, summary.Max);\n        AssertEqual(1.5, summary.InterquartileRange);\n        AssertEqual(1.52753, summary.StandardDeviation, AbsoluteEqualityComparer.E4);\n        AssertEqual([], summary.AllOutliers);\n        AssertEqual(1, summary.Percentiles.P0);\n        AssertEqual(1.5, summary.Percentiles.P25);\n        AssertEqual(2, summary.Percentiles.P50);\n        AssertEqual(3.4, summary.Percentiles.P85);\n        AssertEqual(3.8, summary.Percentiles.P95);\n        AssertEqual(4, summary.Percentiles.P100);\n    }\n\n    [Fact]\n    public void StatisticsWithN7Test()\n    {\n        var summary = new Statistics(1, 2, 4, 8, 16, 32, 64);\n        Print(summary);\n        AssertEqual(1, summary.Min);\n        AssertEqual(-28.5, summary.LowerFence);\n        AssertEqual(3, summary.Q1);\n        AssertEqual(8, summary.Median);\n        AssertEqual(18.1428571429, summary.Mean, AbsoluteEqualityComparer.E5);\n        AssertEqual(24, summary.Q3);\n        AssertEqual(55.5, summary.UpperFence);\n        AssertEqual(64, summary.Max);\n        AssertEqual(21, summary.InterquartileRange);\n        AssertEqual(22.9378, summary.StandardDeviation, AbsoluteEqualityComparer.E4);\n        AssertEqual([64.0], summary.AllOutliers);\n        AssertEqual(1, summary.Percentiles.P0);\n        AssertEqual(3, summary.Percentiles.P25);\n        AssertEqual(8, summary.Percentiles.P50);\n        AssertEqual(35.2, summary.Percentiles.P85, AbsoluteEqualityComparer.E4);\n        AssertEqual(54.4, summary.Percentiles.P95, AbsoluteEqualityComparer.E4);\n        AssertEqual(64, summary.Percentiles.P100);\n    }\n\n    [Fact]\n    public void OutlierTest()\n    {\n        var summary = new Statistics(1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 10, 10.1);\n        Print(summary);\n        AssertEqual([10, 10.1], summary.AllOutliers);\n        AssertEqual([10, 10.1], summary.UpperOutliers);\n        AssertEqual([], summary.LowerOutliers);\n    }\n\n    [Fact]\n    public void ConfidenceIntervalTest()\n    {\n        var summary = new Statistics(Enumerable.Range(1, 30));\n        Print(summary);\n        Assert.Equal(\"99.9%\", summary.PerfolizerConfidenceInterval.ConfidenceLevel.ToString());\n        AssertEqual(15.5, summary.PerfolizerConfidenceInterval.Estimation);\n        AssertEqual(9.618329, summary.PerfolizerConfidenceInterval.Lower, AbsoluteEqualityComparer.E4);\n        AssertEqual(21.38167, summary.PerfolizerConfidenceInterval.Upper, AbsoluteEqualityComparer.E4);\n    }\n\n    [Fact]\n    public void PercentileValuesWithN30Test()\n    {\n        var summary = new Statistics(Enumerable.Range(1, 30));\n        Print(summary);\n        AssertEqual(1, summary.Percentiles.P0);\n        AssertEqual(8.25, summary.Percentiles.P25);\n        AssertEqual(15.5, summary.Percentiles.P50);\n        AssertEqual(20.43, summary.Percentiles.P67, AbsoluteEqualityComparer.E4);\n        AssertEqual(24.2, summary.Percentiles.P80, AbsoluteEqualityComparer.E4);\n        AssertEqual(25.65, summary.Percentiles.P85);\n        AssertEqual(27.1, summary.Percentiles.P90);\n        AssertEqual(28.55, summary.Percentiles.P95, AbsoluteEqualityComparer.E4);\n        AssertEqual(30, summary.Percentiles.P100);\n    }\n\n    [Fact]\n    public void PercentileValuesWithN90Test()\n    {\n        var a = Enumerable.Range(1, 30);\n        var b = Enumerable.Repeat(0, 30).Concat(a);\n        var c = b.Concat(Enumerable.Repeat(31, 30));\n        var summary = new Statistics(c);\n        Print(summary);\n        AssertEqual(0, summary.Percentiles.P0);\n        AssertEqual(0, summary.Percentiles.P25);\n        AssertEqual(15.5, summary.Percentiles.P50);\n        AssertEqual(30.63, summary.Percentiles.P67, AbsoluteEqualityComparer.E4);\n        AssertEqual(31, summary.Percentiles.P80);\n        AssertEqual(31, summary.Percentiles.P85);\n        AssertEqual(31, summary.Percentiles.P90);\n        AssertEqual(31, summary.Percentiles.P95);\n        AssertEqual(31, summary.Percentiles.P100);\n    }\n\n    [AssertionMethod]\n    private static void AssertEqual(double a, double b, IEqualityComparer<double>? comparer = null)\n    {\n        Assert.Equal(a, b, comparer ?? AbsoluteEqualityComparer.E9);\n    }\n\n    [AssertionMethod]\n    private static void AssertEqual(double[] a, double[] b, IEqualityComparer<double>? comparer = null)\n    {\n        Assert.Equal(a, b, comparer ?? AbsoluteEqualityComparer.E9);\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Mocks/MockClock.cs",
    "content": "﻿using Perfolizer.Horology;\n\nnamespace BenchmarkDotNet.Tests.Mocks\n{\n    public class MockClock : IClock\n    {\n        public MockClock(Frequency frequency)\n        {\n            Frequency = frequency;\n        }\n\n        public string Title => \"Mock\";\n        public bool IsAvailable => true;\n        public Frequency Frequency { get; }\n\n        private long counter;\n        public long GetTimestamp() => counter++;\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Mocks/MockEngine.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing BenchmarkDotNet.Characteristics;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Running;\nusing JetBrains.Annotations;\nusing Perfolizer.Horology;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.Tests.Mocks\n{\n    public class MockEngine : IEngine\n    {\n        private readonly ITestOutputHelper output;\n        private readonly Func<IterationData, TimeInterval> measure;\n\n        public EngineParameters Parameters { get; }\n\n        internal MockEngine(ITestOutputHelper output, Job job, Func<IterationData, TimeInterval> measure)\n        {\n            this.output = output;\n            this.measure = measure;\n            Parameters = new EngineParameters\n            {\n                TargetJob = job,\n                WorkloadActionUnroll = _ => { },\n                WorkloadActionNoUnroll = _ => { },\n                OverheadActionUnroll = _ => { },\n                OverheadActionNoUnroll = _ => { },\n                GlobalSetupAction = () => { },\n                GlobalCleanupAction = () => { },\n                IterationSetupAction = () => { },\n                IterationCleanupAction = () => { },\n                BenchmarkName = \"\",\n                Host = default!,\n                InProcessDiagnoserHandler = default!\n            };\n        }\n\n        public void Dispose() { }\n\n        private Measurement RunIteration(IterationData data)\n        {\n            double nanoseconds = measure(data).Nanoseconds;\n            var measurement = new Measurement(1, data.mode, data.stage, data.index, data.invokeCount, nanoseconds);\n            WriteLine(measurement.ToString());\n            return measurement;\n        }\n\n        public RunResults Run() => default;\n\n        internal List<Measurement> Run(EngineStage stage)\n        {\n            var measurements = stage.GetMeasurementList();\n            while (stage.GetShouldRunIteration(measurements, out var iterationData))\n            {\n                var measurement = RunIteration(iterationData);\n                measurements.Add(measurement);\n            }\n            return measurements;\n        }\n\n        public void WriteLine() => output.WriteLine(\"\");\n        public void WriteLine(string line) => output.WriteLine(line);\n\n        public IResolver Resolver => new CompositeResolver(BenchmarkRunnerClean.DefaultResolver, EngineResolver.Instance);\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Mocks/MockFactory.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Collections.Immutable;\nusing System.Linq;\nusing System.Reflection;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Columns;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Disassemblers;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Helpers;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Tests.Builders;\nusing BenchmarkDotNet.Toolchains;\nusing BenchmarkDotNet.Toolchains.Results;\nusing BenchmarkDotNet.Validators;\nusing Perfolizer.Horology;\nusing Perfolizer.Metrology;\nusing static BenchmarkDotNet.Reports.SummaryTable.SummaryTableColumn;\nusing Measurement = BenchmarkDotNet.Reports.Measurement;\nusing MethodInfo = System.Reflection.MethodInfo;\n\nnamespace BenchmarkDotNet.Tests.Mocks\n{\n    public static class MockFactory\n    {\n        public static Summary CreateSummary(Type benchmarkType, params IColumnHidingRule[] columHidingRules)\n        {\n            var runInfo = BenchmarkConverter.TypeToBenchmarks(benchmarkType);\n            return new Summary(\n                \"MockSummary\",\n                runInfo.BenchmarksCases.Select((benchmark, index) => CreateReport(benchmark, 30, (index + 1) * 100)).ToImmutableArray(),\n                new HostEnvironmentInfoBuilder().WithoutDotNetSdkVersion().Build(),\n                string.Empty,\n                string.Empty,\n                TimeSpan.FromMinutes(1),\n                TestCultureInfo.Instance,\n                [],\n                ImmutableArray.Create<IColumnHidingRule>(columHidingRules));\n        }\n\n        public static Summary CreateSummaryWithBiasedDistribution(Type benchmarkType, int min, int median, int max, int n)\n        {\n            var runInfo = BenchmarkConverter.TypeToBenchmarks(benchmarkType);\n            return new Summary(\n                $\"MockSummary-N{n}\",\n                runInfo.BenchmarksCases.Select((benchmark, index) => CreateReportWithBiasedDistribution(\n                    benchmark,\n                    (index + 1) * min,\n                    (index + 1) * median,\n                    (index + 1) * max,\n                    n,\n                    [])).ToImmutableArray(),\n                new HostEnvironmentInfoBuilder().WithoutDotNetSdkVersion().Build(),\n                string.Empty,\n                string.Empty,\n                TimeSpan.FromMinutes(1),\n                TestCultureInfo.Instance,\n                [],\n                []);\n        }\n\n        public static Summary CreateSummary(IConfig config) => new Summary(\n            \"MockSummary\",\n            CreateReports(config),\n            new HostEnvironmentInfoBuilder().WithoutDotNetSdkVersion().Build(),\n            string.Empty,\n            string.Empty,\n            TimeSpan.FromMinutes(1),\n            config.CultureInfo ?? DefaultCultureInfo.Instance,\n            [],\n            [],\n            config.SummaryStyle);\n\n\n        public static Summary CreateSummary(IConfig config, bool hugeSd, Metric[] metrics)\n            => CreateSummary<MockBenchmarkClass>(config, hugeSd, metrics);\n\n        public static Summary CreateSummary<TBenchmark>(IConfig config, bool hugeSd, Metric[] metrics) => new Summary(\n            \"MockSummary\",\n            CreateBenchmarks<TBenchmark>(config).Select(b => CreateReport(b, hugeSd, metrics)).ToImmutableArray(),\n            new HostEnvironmentInfoBuilder().Build(),\n            string.Empty,\n            string.Empty,\n            TimeSpan.FromMinutes(1),\n            TestCultureInfo.Instance,\n            [],\n            []);\n\n        public static Summary CreateSummary<TBenchmark>(IConfig config, bool hugeSd, Func<BenchmarkCase, Metric[]> metricsBuilder) => new Summary(\n            \"MockSummary\",\n            CreateBenchmarks<TBenchmark>(config).Select(b => CreateReport(b, hugeSd, metricsBuilder(b))).ToImmutableArray(),\n            new HostEnvironmentInfoBuilder().Build(),\n            string.Empty,\n            string.Empty,\n            TimeSpan.FromMinutes(1),\n            TestCultureInfo.Instance,\n            [],\n            []);\n\n        public static SummaryStyle CreateSummaryStyle(bool printUnitsInHeader = false, bool printUnitsInContent = true, bool printZeroValuesInContent = false,\n            SizeUnit? sizeUnit = null, TimeUnit? timeUnit = null, TextJustification textColumnJustification = TextJustification.Left,\n            TextJustification numericColumnJustification = TextJustification.Left)\n            => new SummaryStyle(DefaultCultureInfo.Instance, printUnitsInHeader, sizeUnit, timeUnit, printUnitsInContent: printUnitsInContent,\n                printZeroValuesInContent: printZeroValuesInContent, textColumnJustification: textColumnJustification,\n                numericColumnJustification: numericColumnJustification);\n\n        private static ImmutableArray<BenchmarkReport> CreateReports(IConfig config)\n            => CreateBenchmarks<MockBenchmarkClass>(config).Select(CreateSimpleReport).ToImmutableArray();\n\n        private static BenchmarkCase[] CreateBenchmarks<TBenchmarks>(IConfig config)\n            => BenchmarkConverter.TypeToBenchmarks(typeof(TBenchmarks), config).BenchmarksCases;\n\n        private static BenchmarkReport CreateSimpleReport(BenchmarkCase benchmarkCase) => CreateReport(benchmarkCase, 1, 1);\n\n        private static BenchmarkReport CreateReport(BenchmarkCase benchmarkCase, int n, double nanoseconds)\n        {\n            var buildResult = BuildResult.Success(GenerateResult.Success(ArtifactsPaths.Empty, []));\n            var measurements = Enumerable.Range(0, n)\n                .Select(index => new Measurement(1, IterationMode.Workload, IterationStage.Result, index + 1, 1, nanoseconds + index).ToString())\n                .ToList();\n            var executeResult = new ExecuteResult(true, 0, default, measurements, [$\"// Runtime=extra output line\"], [], 1);\n            return new BenchmarkReport(true, benchmarkCase, buildResult, buildResult, [executeResult], []);\n        }\n\n        private static BenchmarkReport CreateReport(BenchmarkCase benchmarkCase, bool hugeSd, Metric[] metrics)\n        {\n            var buildResult = BuildResult.Success(GenerateResult.Success(ArtifactsPaths.Empty, []));\n            bool isFoo = benchmarkCase.Descriptor.WorkloadMethodDisplayInfo == \"Foo\";\n            bool isBar = benchmarkCase.Descriptor.WorkloadMethodDisplayInfo == \"Bar\";\n            var measurements = new List<Measurement>\n            {\n                new Measurement(1, IterationMode.Workload, IterationStage.Result, 1, 1, 1),\n                new Measurement(1, IterationMode.Workload, IterationStage.Result, 2, 1, hugeSd && isFoo ? 2 : 1),\n                new Measurement(1, IterationMode.Workload, IterationStage.Result, 3, 1, hugeSd && isBar ? 3 : 1),\n                new Measurement(1, IterationMode.Workload, IterationStage.Result, 4, 1, hugeSd && isFoo ? 2 : 1),\n                new Measurement(1, IterationMode.Workload, IterationStage.Result, 5, 1, hugeSd && isBar ? 3 : 1),\n                new Measurement(1, IterationMode.Workload, IterationStage.Result, 6, 1, 1)\n            };\n            var executeResult = new ExecuteResult(measurements, default);\n            return new BenchmarkReport(true, benchmarkCase, buildResult, buildResult, [executeResult], metrics);\n        }\n\n        private static BenchmarkReport CreateReportWithBiasedDistribution(BenchmarkCase benchmarkCase, int min, int median, int max, int n, Metric[] metrics)\n        {\n            var buildResult = BuildResult.Success(GenerateResult.Success(ArtifactsPaths.Empty, []));\n            bool isFoo = benchmarkCase.Descriptor.WorkloadMethodDisplayInfo == \"Foo\";\n            bool isBar = benchmarkCase.Descriptor.WorkloadMethodDisplayInfo == \"Bar\";\n            var measurements = from i in Enumerable.Range(0, Math.Max(1, n / 9))\n                               from m in isFoo ?\n                               [\n                                    new Measurement(1, IterationMode.Workload, IterationStage.Result, 1, 1, min), // 1\n                                    new Measurement(1, IterationMode.Workload, IterationStage.Result, 2, 1, min + ((median - min) / 2) + 1), // 3\n                                    new Measurement(1, IterationMode.Workload, IterationStage.Result, 4, 1, median), // 4\n                                    new Measurement(1, IterationMode.Workload, IterationStage.Result, 5, 1, median), // 4\n                                    new Measurement(1, IterationMode.Workload, IterationStage.Result, 5, 1, median), // 4\n                                    new Measurement(1, IterationMode.Workload, IterationStage.Result, 7, 1, median + ((max - median) / 2)), // 7\n                                    new Measurement(1, IterationMode.Workload, IterationStage.Result, 8, 1, median + ((max - median) / 2)), // 7\n                                    new Measurement(1, IterationMode.Workload, IterationStage.Result, 9, 1, max),    // 10\n                                    new Measurement(1, IterationMode.Workload, IterationStage.Result, 9, 1, max),    // 10\n                               ] : new[]\n                               {\n                                    new Measurement(1, IterationMode.Workload, IterationStage.Result, 1, 1, min), // 1\n                                    new Measurement(1, IterationMode.Workload, IterationStage.Result, 1, 1, min), // 1\n                                    new Measurement(1, IterationMode.Workload, IterationStage.Result, 2, 1, min + ((median - min) / 2) + 1), // 3\n                                    new Measurement(1, IterationMode.Workload, IterationStage.Result, 2, 1, min + ((median - min) / 2) + 1), // 3\n                                    new Measurement(1, IterationMode.Workload, IterationStage.Result, 4, 1, median), // 4\n                                    new Measurement(1, IterationMode.Workload, IterationStage.Result, 5, 1, median), // 4\n                                    new Measurement(1, IterationMode.Workload, IterationStage.Result, 5, 1, median), // 4\n                                    new Measurement(1, IterationMode.Workload, IterationStage.Result, 7, 1, median + ((max - median) / 2)), // 7\n                                    new Measurement(1, IterationMode.Workload, IterationStage.Result, 9, 1, max),    // 10\n                               }\n                               select m;\n            var executeResult = new ExecuteResult(measurements.Take(n).ToList(), default);\n            return new BenchmarkReport(true, benchmarkCase, buildResult, buildResult, [executeResult], metrics);\n        }\n\n        [LongRunJob]\n        public class MockBenchmarkClass\n        {\n            [Benchmark] public void Foo() { }\n\n            [Benchmark] public void Bar() { }\n        }\n\n        public static readonly Type MockType = typeof(MockBenchmarkClass);\n\n        public static readonly MethodInfo MockMethodInfo = MockType.GetTypeInfo().GetMethods()\n            .Single(method => method.Name == nameof(MockBenchmarkClass.Foo));\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Mocks/MockRunner.cs",
    "content": "using BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Exporters;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Tests.Mocks.Toolchain;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.Tests.Mocks\n{\n    public static class MockRunner\n    {\n        public static Summary Run<T>(ITestOutputHelper output, Func<string, double[]> measurer)\n            => Run<T>(output, benchmarkCase => measurer(benchmarkCase.Descriptor.WorkloadMethod.Name)\n                        .Select((value, i) => new Measurement(1, IterationMode.Workload, IterationStage.Result, i, 1, value))\n                        .ToList());\n\n        public static Summary Run<T>(ITestOutputHelper output, Func<BenchmarkCase, List<Measurement>> measurer)\n        {\n            var job = new Job(\"MockJob\")\n            {\n                Infrastructure =\n                {\n                    Toolchain = new MockToolchain(measurer)\n                }\n            }.Freeze();\n\n            var logger = new AccumulationLogger();\n\n            var config = DefaultConfig.Instance\n                .WithOptions(ConfigOptions.DisableOptimizationsValidator)\n                .AddJob(job)\n                .AddLogger(logger);\n            var summary = BenchmarkRunner.Run<T>(config);\n\n            var exporter = MarkdownExporter.Mock;\n            exporter.ExportToLog(summary, logger);\n            output.WriteLine(logger.GetLog());\n\n            return summary;\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Mocks/Toolchain/MockToolchain.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Collections.Immutable;\nusing BenchmarkDotNet.Characteristics;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Toolchains;\nusing BenchmarkDotNet.Toolchains.Parameters;\nusing BenchmarkDotNet.Toolchains.Results;\nusing BenchmarkDotNet.Validators;\n\nnamespace BenchmarkDotNet.Tests.Mocks.Toolchain\n{\n    public class MockToolchain : IToolchain\n    {\n        public MockToolchain(Func<BenchmarkCase, List<Measurement>> measurer)\n            => Executor = new MockExecutor(measurer);\n\n        public string Name => nameof(MockToolchain);\n        public IGenerator Generator => new MockGenerator();\n        public IBuilder Builder => new MockBuilder();\n        public IExecutor Executor { get; private set; }\n        public bool IsInProcess => false;\n        public IEnumerable<ValidationError> Validate(BenchmarkCase benchmarkCase, IResolver resolver) => [];\n\n        public override string ToString() => GetType().Name;\n\n        private class MockGenerator : IGenerator\n        {\n            public GenerateResult GenerateProject(BuildPartition buildPartition, ILogger logger, string rootArtifactsFolderPath)\n                => GenerateResult.Success(ArtifactsPaths.Empty, []);\n        }\n\n        private class MockBuilder : IBuilder\n        {\n            public BuildResult Build(GenerateResult generateResult, BuildPartition buildPartition, ILogger logger) => BuildResult.Success(generateResult);\n        }\n\n        private class MockExecutor : IExecutor\n        {\n            private readonly Func<BenchmarkCase, List<Measurement>> measurer;\n\n            public MockExecutor(Func<BenchmarkCase, List<Measurement>> measurer) => this.measurer = measurer;\n\n            public ExecuteResult Execute(ExecuteParameters executeParameters) => new(measurer(executeParameters.BenchmarkCase));\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/MonoDisassemblyOutputParserTests.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing BenchmarkDotNet.Disassemblers;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests\n{\n    public class MonoDisassemblyOutputParserTests\n    {\n        [Fact]\n        public void CanParseMonoDisassemblyOutputFromMac()\n        {\n            const string input = @\"\nCFA: [0] def_cfa: %rsp+0x8\nCFA: [0] offset: unknown at cfa-0x8\nCFA: [4] def_cfa_offset: 0x10\nCFA: [8] offset: %r15 at cfa-0x10\nBasic block 0 starting at offset 0xb\nBasic block 2 starting at offset 0xb\nBasic block 1 starting at offset 0x27\nCFA: [2f] def_cfa: %rsp+0x8\nMethod void BenchmarkDotNet.Samples.CPU.Cpu_Atomics:NoLock () emitted at 0x1027cdf80 to 0x1027cdfb0 (code length 48) [BenchmarkDotNet.Samples.exe]\n/var/folders/ld/p9yn04fs3ys6h_dkyxvv95_40000gn/T/.WuSVhL:\n(__TEXT,__text) section\nchmarkDotNet_Samples_CPU_Cpu_Atomics_NoLock:\n0000000000000000\tsubq\t$0x8, %rsp\n0000000000000004\tmovq\t%r15, (%rsp)\n0000000000000008\tmovq\t%rdi, %r15\n000000000000000b\tmovslq\t0x18(%r15), %rax\n000000000000000f\tincl\t%eax\n0000000000000011\tmovl\t%eax, 0x18(%r15)\n0000000000000015\tincl\t%eax\n0000000000000017\tmovl\t%eax, 0x18(%r15)\n000000000000001b\tincl\t%eax\n000000000000001d\tmovl\t%eax, 0x18(%r15)\n0000000000000021\tincl\t%eax\n0000000000000023\tmovl\t%eax, 0x18(%r15)\n0000000000000027\tmovq\t(%rsp), %r15\n000000000000002b\taddq\t$0x8, %rsp\n000000000000002f\tretq\";\n\n            var expected = new DisassemblyResult()\n            {\n                Methods =\n                [\n                    new DisassembledMethod()\n                    {\n                        Name = \"NoLock\",\n                        Maps =\n                        [\n                            new Map()\n                            {\n                                SourceCodes =\n                                [\n                                    new MonoCode { Text = \"subq\\t$0x8, %rsp\" },\n\n                                    new MonoCode { Text = \"movq\\t%r15, (%rsp)\" },\n                                    new MonoCode { Text = \"movq\\t%rdi, %r15\" },\n                                    new MonoCode { Text = \"movslq\\t0x18(%r15), %rax\" },\n\n                                    new MonoCode { Text = \"incl\\t%eax\" },\n                                    new MonoCode { Text = \"movl\\t%eax, 0x18(%r15)\" },\n\n                                    new MonoCode { Text = \"incl\\t%eax\" },\n                                    new MonoCode { Text = \"movl\\t%eax, 0x18(%r15)\" },\n\n                                    new MonoCode { Text = \"incl\\t%eax\" },\n                                    new MonoCode { Text = \"movl\\t%eax, 0x18(%r15)\" },\n\n                                    new MonoCode { Text = \"incl\\t%eax\" },\n                                    new MonoCode { Text = \"movl\\t%eax, 0x18(%r15)\" },\n\n                                    new MonoCode { Text = \"movq\\t(%rsp), %r15\" },\n                                    new MonoCode { Text = \"addq\\t$0x8, %rsp\" },\n                                    new MonoCode { Text = \"retq\" }\n                                ]\n                            }\n                        ]\n                    }\n                ]\n            };\n\n            Check(input, expected, \"NoLock\");\n        }\n\n        [Fact]\n        public void CanParseMonoDisassemblyOutputFromWindows()\n        {\n            const string input = @\"\nCFA: [0] def_cfa: %rsp+0x8\nCFA: [0] offset: unknown at cfa-0x8\nCFA: [4] def_cfa_offset: 0x30\nCFA: [8] offset: %rsi at cfa-0x30\nCFA: [d] offset: %r14 at cfa-0x28\nCFA: [12] offset: %r15 at cfa-0x20\nBasic block 0 starting at offset 0x12\nBasic block 3 starting at offset 0x12\nBasic block 5 starting at offset 0x20\nBasic block 4 starting at offset 0x37\nBasic block 6 starting at offset 0x4a\nBasic block 1 starting at offset 0x52\nCFA: [64] def_cfa: %rsp+0x8\nMethod int BenchmarkDotNet.Samples.My:NoLock () emitted at 000001D748E912E0 to 000001D748E91345 (code length 101) [BenchmarkDotNet.Samples.dll]\n\n/test.o:     file format pe-x86-64\n\n\nDisassembly of section .text:\n\n0000000000000000 <chmarkDotNet_Samples_My_NoLock>:\n   0:\t48 83 ec 28          \tsub    $0x28,%rsp\n   4:\t48 89 34 24          \tmov    %rsi,(%rsp)\n   8:\t4c 89 74 24 08       \tmov    %r14,0x8(%rsp)\n   d:\t4c 89 7c 24 10       \tmov    %r15,0x10(%rsp)\n  12:\t45 33 ff             \txor    %r15d,%r15d\n  15:\t45 33 f6             \txor    %r14d,%r14d\n  18:\teb 1d                \tjmp    37 <chmarkDotNet_Samples_My_NoLock+0x37>\n  1a:\t48 8d 64 24 00       \tlea    0x0(%rsp),%rsp\n  1f:\t90                   \tnop\n  20:\t49 8b c7             \tmov    %r15,%rax\n  23:\t49 8b ce             \tmov    %r14,%rcx\n  26:\tba 02 00 00 00       \tmov    $0x2,%edx\n  2b:\t0f af ca             \timul   %edx,%ecx\n  2e:\t4c 8b f8             \tmov    %rax,%r15\n  31:\t44 03 f9             \tadd    %ecx,%r15d\n  34:\t41 ff c6             \tinc    %r14d\n  37:\t41 83 fe 0d          \tcmp    $0xd,%r14d\n  3b:\t40 0f 9c c6          \tsetl   %sil\n  3f:\t48 0f b6 f6          \tmovzbq %sil,%rsi\n  43:\t48 8b c6             \tmov    %rsi,%rax\n  46:\t85 c0                \ttest   %eax,%eax\n  48:\t75 d6                \tjne    20 <chmarkDotNet_Samples_My_NoLock+0x20>\n  4a:\t44 89 7c 24 18       \tmov    %r15d,0x18(%rsp)\n  4f:\t49 8b c7             \tmov    %r15,%rax\n  52:\t48 8b 34 24          \tmov    (%rsp),%rsi\n  56:\t4c 8b 74 24 08       \tmov    0x8(%rsp),%r14\n  5b:\t4c 8b 7c 24 10       \tmov    0x10(%rsp),%r15\n  60:\t48 83 c4 28          \tadd    $0x28,%rsp\n  64:\tc3                   \tretq\n  65:   90                      nop\n  66:   90                      nop\n\";\n\n            var expected = new DisassemblyResult()\n            {\n                Methods =\n                [\n                    new DisassembledMethod()\n                    {\n                        Name = \"NoLock\",\n                        Maps =\n                        [\n                            new Map()\n                            {\n                                SourceCodes =\n                                [\n                                    new MonoCode { Text = \"sub    $0x28,%rsp\" },\n                                    new MonoCode { Text = \"mov    %rsi,(%rsp)\" },\n                                    new MonoCode { Text = \"mov    %r14,0x8(%rsp)\" },\n                                    new MonoCode { Text = \"mov    %r15,0x10(%rsp)\" },\n                                    new MonoCode { Text = \"xor    %r15d,%r15d\" },\n                                    new MonoCode { Text = \"xor    %r14d,%r14d\" },\n                                    new MonoCode { Text = \"jmp    37 <chmarkDotNet_Samples_My_NoLock+0x37>\" },\n                                    new MonoCode { Text = \"lea    0x0(%rsp),%rsp\" },\n                                    new MonoCode { Text = \"nop\" },\n                                    new MonoCode { Text = \"mov    %r15,%rax\" },\n                                    new MonoCode { Text = \"mov    %r14,%rcx\" },\n                                    new MonoCode { Text = \"mov    $0x2,%edx\" },\n                                    new MonoCode { Text = \"imul   %edx,%ecx\" },\n                                    new MonoCode { Text = \"mov    %rax,%r15\" },\n                                    new MonoCode { Text = \"add    %ecx,%r15d\" },\n                                    new MonoCode { Text = \"inc    %r14d\" },\n                                    new MonoCode { Text = \"cmp    $0xd,%r14d\" },\n                                    new MonoCode { Text = \"setl   %sil\" },\n                                    new MonoCode { Text = \"movzbq %sil,%rsi\" },\n                                    new MonoCode { Text = \"mov    %rsi,%rax\" },\n                                    new MonoCode { Text = \"test   %eax,%eax\" },\n                                    new MonoCode { Text = \"jne    20 <chmarkDotNet_Samples_My_NoLock+0x20>\" },\n                                    new MonoCode { Text = \"mov    %r15d,0x18(%rsp)\" },\n                                    new MonoCode { Text = \"mov    %r15,%rax\" },\n                                    new MonoCode { Text = \"mov    (%rsp),%rsi\" },\n                                    new MonoCode { Text = \"mov    0x8(%rsp),%r14\" },\n                                    new MonoCode { Text = \"mov    0x10(%rsp),%r15\" },\n                                    new MonoCode { Text = \"add    $0x28,%rsp\" },\n                                    new MonoCode { Text = \"retq\" },\n                                ]\n                            }\n                        ]\n                    }\n                ]\n            };\n\n            Check(input, expected, \"NoLock\");\n        }\n\n        [Fact]\n        public void CanParseMonoDisassemblyOutputFromWindowsWithoutTools()\n        {\n            const string input = @\"\nBasic block 0 starting at offset 0xd\nBasic block 3 starting at offset 0xd\nBasic block 5 starting at offset 0x18\nBasic block 4 starting at offset 0x1c\nBasic block 6 starting at offset 0x21\nBasic block 1 starting at offset 0x24\nCFA: [31] def_cfa: %rsp+0x8\nMethod int BenchmarkDotNet.Samples.Intro.IntroDisasm:Foo () emitted at 0000027E7E4E12E0 to 0000027E7E4E1312 (code length 50) [BenchmarkDotNet.Samples.dll]\n'as' is not recognized as an internal or external command,\noperable program or batch file.\n'x86_64-w64-mingw32-objdump.exe' is not recognized as an internal or external command,\noperable program or batch file.\n\";\n\n            var expected = new DisassemblyResult\n            {\n                Methods =\n                [\n                    new DisassembledMethod\n                    {\n                        Name = \"Foo\",\n                        Maps =\n                        [\n                            new Map\n                            {\n                                SourceCodes = input\n                                    .Split('\\r', '\\n')\n                                    .Where(line => !string.IsNullOrWhiteSpace(line))\n                                    .Select(line => new MonoCode{ Text = line })\n                                    .ToArray()\n                            }\n                        ]\n                    }\n                ],\n                Errors =\n                [\n                    @\"It's impossible to get Mono disasm because you don't have some required tools:\n'as' is not recognized as an internal or external command\n'x86_64-w64-mingw32-objdump.exe' is not recognized as an internal or external command\"\n                ]\n            };\n\n            Check(input, expected, \"Foo\");\n        }\n\n        [Fact]\n        public void CanParseInvalidMonoDisassemblyOutput()\n        {\n            const string input = @\"lalala\";\n\n            var expected = new DisassemblyResult\n            {\n                Methods =\n                [\n                    new DisassembledMethod\n                    {\n                        Name = \"Foo\",\n                        Maps =\n                        [\n                            new Map\n                            {\n                                SourceCodes = input\n                                    .Split('\\r', '\\n')\n                                    .Where(line => !string.IsNullOrWhiteSpace(line))\n                                    .Select(line => new MonoCode { Text = line })\n                                    .ToArray()\n                            }\n                        ]\n                    }\n                ],\n                Errors =\n                [\n                    @\"It's impossible to find assembly instructions in the mono output\"\n                ]\n            };\n\n            Check(input, expected, \"Foo\");\n        }\n\n\n        private static void Check(string input, DisassemblyResult expected, string methodName)\n        {\n            var disassemblyResult = MonoDisassembler.OutputParser.Parse(\n                input.Split([\"\\r\\n\", \"\\n\"], StringSplitOptions.None),\n                methodName, commandLine: string.Empty);\n\n            Assert.Equal(expected.Methods.Single().Name, disassemblyResult.Methods.Single().Name);\n            Assert.Equal(expected.Methods[0].Maps[0].SourceCodes.Length, disassemblyResult.Methods[0].Maps[0].SourceCodes.Length);\n\n            for (int i = 0; i < expected.Methods[0].Maps[0].SourceCodes.Length; i++)\n                Assert.Equal(((MonoCode)expected.Methods[0].Maps[0].SourceCodes[i]).Text,\n                    ((MonoCode)disassemblyResult.Methods[0].Maps[0].SourceCodes[i]).Text);\n\n            Assert.Equal(expected.Errors.Length, disassemblyResult.Errors.Length);\n            for (int i = 0; i < expected.Errors.Length; i++)\n                Assert.Equal(expected.Errors[i].Replace(\"\\r\", \"\").Replace(\"\\n\", \"\"), disassemblyResult.Errors[i].Replace(\"\\r\", \"\").Replace(\"\\n\", \"\"));\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Order/DefaultOrdererTests.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Collections.Immutable;\nusing System.Globalization;\nusing System.Linq;\nusing BenchmarkDotNet.Columns;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Order;\nusing BenchmarkDotNet.Parameters;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Tests.Mocks;\nusing BenchmarkDotNet.Validators;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests.Order\n{\n    public class DefaultOrdererTests\n    {\n        private static Summary CreateMockSummary() => new(\"\", [], HostEnvironmentInfo.GetCurrent(),\n            \"\", \"\", TimeSpan.Zero, CultureInfo.InvariantCulture, [], []);\n\n        private static BenchmarkCase CreateBenchmarkCase(string category, int parameter, params BenchmarkLogicalGroupRule[] rules) => new(\n            new Descriptor(MockFactory.MockType, MockFactory.MockMethodInfo, categories: [category]),\n            new Job(),\n            new ParameterInstances(\n            [\n                new ParameterInstance(new ParameterDefinition(\"P\", false, [], false, parameterType: null!, 0), parameter, SummaryStyle.Default)\n            ]),\n            DefaultConfig.Instance.AddLogicalGroupRules(rules).CreateImmutableConfig()\n        );\n\n        private static string GetId(BenchmarkCase benchmarkCase) => benchmarkCase.Descriptor.Categories.First() + benchmarkCase.Parameters.Items.First().Value;\n\n        [Fact]\n        public void CategoriesHasHigherPriorityThanParameters()\n        {\n            var summary = CreateMockSummary();\n            var benchmarkCases = new List<BenchmarkCase>\n            {\n                CreateBenchmarkCase(\"A\", 1),\n                CreateBenchmarkCase(\"B\", 1),\n                CreateBenchmarkCase(\"A\", 2),\n                CreateBenchmarkCase(\"B\", 2)\n            }.ToImmutableArray();\n            string[] sortedBenchmarkCases = DefaultOrderer.Instance.GetSummaryOrder(benchmarkCases, summary).Select(GetId).ToArray();\n            Assert.Equal([\"A1\", \"A2\", \"B1\", \"B2\"], sortedBenchmarkCases);\n        }\n\n        [Fact]\n        public void OrderCanBeOverriden()\n        {\n            BenchmarkLogicalGroupRule[] rules =\n            [\n                BenchmarkLogicalGroupRule.ByParams,\n                BenchmarkLogicalGroupRule.ByCategory,\n            ];\n            var summary = CreateMockSummary();\n            var benchmarkCases = new List<BenchmarkCase>\n            {\n                CreateBenchmarkCase(\"A\", 1, rules),\n                CreateBenchmarkCase(\"B\", 1, rules),\n                CreateBenchmarkCase(\"A\", 2, rules),\n                CreateBenchmarkCase(\"B\", 2, rules)\n            }.ToImmutableArray();\n            string[] sortedBenchmarkCases = DefaultOrderer.Instance.GetSummaryOrder(benchmarkCases, summary).Select(GetId).ToArray();\n            Assert.Equal([\"A1\", \"B1\", \"A2\", \"B2\"], sortedBenchmarkCases);\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Order/JobOrderTests.cs",
    "content": "﻿using BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Toolchains;\nusing BenchmarkDotNet.Toolchains.CsProj;\nusing System.Linq;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests.Order;\n\npublic class JobOrderTests\n{\n    [Fact]\n    public void TestJobOrders_ByJobId()\n    {\n        // Arrange\n        Job[] jobs =\n        [\n            Job.Dry.WithToolchain(CsProjCoreToolchain.NetCoreApp80)\n                   .WithRuntime(CoreRuntime.Core80)\n                   .WithId(\"v1.4.1\"),\n            Job.Dry.WithToolchain(CsProjCoreToolchain.NetCoreApp90)\n                   .WithRuntime(CoreRuntime.Core90)\n                   .WithId(\"v1.4.10\"),\n            Job.Dry.WithToolchain(CsProjCoreToolchain.NetCoreApp10_0)\n                   .WithRuntime(CoreRuntime.Core10_0)\n                   .WithId(\"v1.4.2\"),\n        ];\n\n        // Verify jobs are sorted by JobId's default order (numeric order).\n        {\n            // Act\n            var comparer = JobComparer.Default;\n            var results = jobs.OrderBy(x => x, comparer)\n                              .Select(x => x.Job.Id)\n                              .ToArray();\n\n            // Assert\n            Assert.Equal([\"v1.4.1\", \"v1.4.2\", \"v1.4.10\"], results);\n        }\n\n        // Verify jobs are sorted by JobId's ordinal order.\n        {\n            // Act\n            var comparer = JobComparer.Ordinal;\n            var results = jobs.OrderBy(d => d, comparer)\n                              .Select(x => x.Job.Id)\n                              .ToArray();\n            // Assert\n            Assert.Equal([\"v1.4.1\", \"v1.4.10\", \"v1.4.2\"], results);\n        }\n    }\n\n    [Fact]\n    public void TestJobOrders_ByRuntime()\n    {\n        // Arrange\n        Job[] jobs =\n        [\n            Job.Dry.WithToolchain(CsProjCoreToolchain.NetCoreApp10_0)\n                   .WithRuntime(CoreRuntime.Core80),\n            Job.Dry.WithToolchain(CsProjCoreToolchain.NetCoreApp90)\n                   .WithRuntime(CoreRuntime.Core90),\n            Job.Dry.WithToolchain(CsProjCoreToolchain.NetCoreApp80)\n                   .WithRuntime(CoreRuntime.Core10_0),\n        ];\n\n        // Act\n        // Verify jobs are sorted by Runtime name order.\n        var results = jobs.OrderBy(d => d, JobComparer.Default)\n                          .Select(x => x.Job.Environment.GetRuntime().Name)\n                          .ToArray();\n\n        // Assert\n        var expected = new[]\n        {\n            CoreRuntime.Core80.Name,\n            CoreRuntime.Core90.Name,\n            CoreRuntime.Core10_0.Name\n        };\n        Assert.Equal(expected, results);\n    }\n\n    [Fact]\n    public void TestJobOrders_ByToolchain()\n    {\n        // Arrange\n        Job[] jobs =\n        [\n            Job.Dry.WithToolchain(CsProjCoreToolchain.NetCoreApp10_0),\n            Job.Dry.WithToolchain(CsProjCoreToolchain.NetCoreApp90),\n            Job.Dry.WithToolchain(CsProjCoreToolchain.NetCoreApp80),\n        ];\n\n        // Act\n        // Verify jobs are sorted by Toolchain name order.\n        var results = jobs.OrderBy(d => d, JobComparer.Default)\n                          .Select(x => x.Job.GetToolchain().Name)\n                          .ToArray();\n\n        // Assert\n        var expected = new[]\n        {\n            CsProjCoreToolchain.NetCoreApp80.Name,\n            CsProjCoreToolchain.NetCoreApp90.Name,\n            CsProjCoreToolchain.NetCoreApp10_0.Name,\n        };\n        Assert.Equal(expected, results);\n    }\n\n    [Theory]\n    [InlineData(\"item1\", \"item1\", 0)]\n    [InlineData(\"item123\", \"item123\", 0)]\n    // Compare different values\n    [InlineData(\"item1\", \"item2\", -1)]\n    [InlineData(\"item2\", \"item1\", 1)]\n    [InlineData(\"item2\", \"item10\", -1)]\n    [InlineData(\"item10\", \"item2\", 1)]\n    [InlineData(\"item1a\", \"item1b\", -1)]\n    [InlineData(\"item1b\", \"item1a\", 1)]\n    [InlineData(\"item\", \"item1\", -1)]\n    [InlineData(\"item10\", \"item\", 1)]\n    [InlineData(\".NET 8\", \".NET 10\", -1)]\n    [InlineData(\".NET 10\", \".NET 8\", 1)]\n    [InlineData(\"v1.4.1\", \"v1.4.10\", -1)]\n    [InlineData(\"v1.4.10\", \"v1.4.2\", 1)]\n    // Compare zero paddeed numeric string.\n    [InlineData(\"item01\", \"item1\", 0)]\n    [InlineData(\"item001\", \"item1\", 0)]\n    [InlineData(\"item1\", \"item001\", 0)]\n    [InlineData(\"item1\", \"item01\", 0)]\n    [InlineData(\"item9\", \"item09\", 0)]\n    [InlineData(\".NET 08\", \".NET 10\", -1)]\n    [InlineData(\".NET 10\", \".NET 08\", 1)]\n    // Arguments that contains null\n    [InlineData(\"\", \"a\", -1)]\n    [InlineData(\"a\", \"\", 1)]\n    [InlineData(\"\", \"\", 0)]\n    public void TestNumericComparer(string a, string b, int expectedSign)\n    {\n        var jobA = new Job(a);\n        var jobB = new Job(b);\n\n        int result = JobComparer.Default.Compare(jobA, jobB);\n        Assert.Equal(expectedSign, NormalizeSign(result));\n\n        static int NormalizeSign(int value)\n            => value == 0 ? 0 : value < 0 ? -1 : 1;\n    }\n}\n"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/ParameterComparerTests.cs",
    "content": "﻿using System;\nusing BenchmarkDotNet.Parameters;\nusing System.Linq;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests\n{\n    public class ParameterComparerTests\n    {\n        private static readonly ParameterDefinition sharedDefinition = new ParameterDefinition(\"Testing\", isStatic: false, values: [], isArgument: false, parameterType: null!, 0);\n\n        [Fact]\n        public void BasicComparisionTest()\n        {\n            var comparer = ParameterComparer.Instance;\n\n            var originalData = new[]\n            {\n                new ParameterInstances(\n                [\n                    new ParameterInstance(sharedDefinition, 5, summaryStyle: null!)\n                ]),\n                new ParameterInstances(\n                [\n                    new ParameterInstance(sharedDefinition, 1, null)\n                ]),\n                new ParameterInstances(\n                [\n                    new ParameterInstance(sharedDefinition, 3, null)\n                ])\n            };\n            var sortedData = originalData.OrderBy(d => d, comparer).ToArray();\n\n            Assert.Equal(1, sortedData[0].Items[0].Value);\n            Assert.Equal(3, sortedData[1].Items[0].Value);\n            Assert.Equal(5, sortedData[2].Items[0].Value);\n        }\n\n        [Fact]\n        public void MultiParameterComparisionTest()\n        {\n            var comparer = ParameterComparer.Instance;\n\n            var originalData = new[]\n            {\n                new ParameterInstances(\n                [\n                    new ParameterInstance(sharedDefinition, 5, null),\n                    new ParameterInstance(sharedDefinition, \"z\", null),\n                    new ParameterInstance(sharedDefinition, 1.0, null)\n                ]),\n                new ParameterInstances(\n                [\n                    new ParameterInstance(sharedDefinition, 5, null),\n                    new ParameterInstance(sharedDefinition, \"a\", null),\n                    new ParameterInstance(sharedDefinition, 0.0, null)\n                ]),\n                new ParameterInstances(\n                [\n                    new ParameterInstance(sharedDefinition, 5, null),\n                    new ParameterInstance(sharedDefinition, \"a\", null),\n                    new ParameterInstance(sharedDefinition, 1.0, null)\n                ]),\n                new ParameterInstances(\n                [\n                    new ParameterInstance(sharedDefinition, 3, null),\n                    new ParameterInstance(sharedDefinition, \"a\", null),\n                    new ParameterInstance(sharedDefinition, 97.5, null)\n                ])\n            };\n\n            // We should sort by the parameters in order, i.e. first by 5/3, then if they match by \"z\"/\"a\"\n            var sortedData = originalData.OrderBy(d => d, comparer).ToArray();\n\n            Assert.Equal(3, sortedData[0].Items[0].Value);\n            Assert.Equal(\"a\", sortedData[0].Items[1].Value);\n            Assert.Equal(97.5, sortedData[0].Items[2].Value);\n\n            Assert.Equal(5, sortedData[1].Items[0].Value);\n            Assert.Equal(\"a\", sortedData[1].Items[1].Value);\n            Assert.Equal(0.0, sortedData[1].Items[2].Value);\n\n            Assert.Equal(5, sortedData[2].Items[0].Value);\n            Assert.Equal(\"a\", sortedData[2].Items[1].Value);\n            Assert.Equal(1.0, sortedData[2].Items[2].Value);\n\n            Assert.Equal(5, sortedData[3].Items[0].Value);\n            Assert.Equal(\"z\", sortedData[3].Items[1].Value);\n            Assert.Equal(1.0, sortedData[3].Items[2].Value);\n        }\n\n        [Fact]\n        public void AlphaNumericComparisionTest()\n        {\n            var comparer = ParameterComparer.Instance;\n\n            var originalData = new[]\n            {\n                new ParameterInstances(\n                [\n                    new ParameterInstance(sharedDefinition, 100, null)\n                ]),\n                new ParameterInstances(\n                [\n                    new ParameterInstance(sharedDefinition, 1000, null)\n                ]),\n                new ParameterInstances(\n                [\n                    new ParameterInstance(sharedDefinition, 2000, null)\n                ]),\n                new ParameterInstances(\n                [\n                    new ParameterInstance(sharedDefinition, 500, null)\n                ])\n            };\n\n            var sortedData = originalData.OrderBy(d => d, comparer).ToArray();\n\n            // Check that we sort by numeric value, not string order!!\n            Assert.Equal(100, sortedData[0].Items[0].Value);\n            Assert.Equal(500, sortedData[1].Items[0].Value);\n            Assert.Equal(1000, sortedData[2].Items[0].Value);\n            Assert.Equal(2000, sortedData[3].Items[0].Value);\n        }\n\n        [Fact]\n        public void IComparableComparisionTest()\n        {\n            var comparer = ParameterComparer.Instance;\n\n            var originalData = new[]\n            {\n                new ParameterInstances(\n                [\n                    new ParameterInstance(sharedDefinition, new ComplexParameter(1, \"first\"), null)\n                ]),\n                new ParameterInstances(\n                [\n                    new ParameterInstance(sharedDefinition, new ComplexParameter(3, \"third\"), null)\n                ]),\n                new ParameterInstances(\n                [\n                    new ParameterInstance(sharedDefinition, new ComplexParameter(2, \"second\"), null)\n                ]),\n                new ParameterInstances(\n                [\n                    new ParameterInstance(sharedDefinition, new ComplexParameter(4, \"fourth\"), null)\n                ])\n            };\n\n            var sortedData = originalData.OrderBy(d => d, comparer).ToArray();\n\n            // Check that we sort by numeric value, not string order!!\n            Assert.Equal(1, ((ComplexParameter)sortedData[0].Items[0].Value!).Value);\n            Assert.Equal(2, ((ComplexParameter)sortedData[1].Items[0].Value!).Value);\n            Assert.Equal(3, ((ComplexParameter)sortedData[2].Items[0].Value!).Value);\n            Assert.Equal(4, ((ComplexParameter)sortedData[3].Items[0].Value!).Value);\n        }\n\n        [Fact]\n        public void ValueTupleWithNonIComparableInnerTypesComparisionTest()\n        {\n            var comparer = ParameterComparer.Instance;\n            var originalData = new[]\n            {\n                new ParameterInstances(\n                [\n                    new ParameterInstance(sharedDefinition, (new ComplexNonIComparableParameter(), 1), null)\n                ]),\n                new ParameterInstances(\n                [\n                    new ParameterInstance(sharedDefinition, (new ComplexNonIComparableParameter(), 3), null)\n                ]),\n                new ParameterInstances(\n                [\n                    new ParameterInstance(sharedDefinition, (new ComplexNonIComparableParameter(), 2), null)\n                ]),\n                new ParameterInstances(\n                [\n                    new ParameterInstance(sharedDefinition, (new ComplexNonIComparableParameter(), 4), null)\n                ])\n            };\n\n            var sortedData = originalData.OrderBy(d => d, comparer).ToArray();\n\n            Assert.Equal(1, (((ComplexNonIComparableParameter, int))sortedData[0].Items[0].Value!).Item2);\n            Assert.Equal(2, (((ComplexNonIComparableParameter, int))sortedData[1].Items[0].Value!).Item2);\n            Assert.Equal(3, (((ComplexNonIComparableParameter, int))sortedData[2].Items[0].Value!).Item2);\n            Assert.Equal(4, (((ComplexNonIComparableParameter, int))sortedData[3].Items[0].Value!).Item2);\n        }\n\n        [Fact]\n        public void TupleWithNonIComparableInnerTypesComparisionTest()\n        {\n            var comparer = ParameterComparer.Instance;\n            var originalData = new[]\n            {\n                new ParameterInstances(\n                [\n                    new ParameterInstance(sharedDefinition, Tuple.Create(new ComplexNonIComparableParameter(), 1), null)\n                ]),\n                new ParameterInstances(\n                [\n                    new ParameterInstance(sharedDefinition, Tuple.Create(new ComplexNonIComparableParameter(), 3), null)\n                ]),\n                new ParameterInstances(\n                [\n                    new ParameterInstance(sharedDefinition, Tuple.Create(new ComplexNonIComparableParameter(), 2), null)\n                ]),\n                new ParameterInstances(\n                [\n                    new ParameterInstance(sharedDefinition, Tuple.Create(new ComplexNonIComparableParameter(), 4), null)\n                ])\n            };\n\n            var sortedData = originalData.OrderBy(d => d, comparer).ToArray();\n\n            Assert.Equal(1, ((Tuple<ComplexNonIComparableParameter, int>)sortedData[0].Items[0].Value!).Item2);\n            Assert.Equal(2, ((Tuple<ComplexNonIComparableParameter, int>)sortedData[1].Items[0].Value!).Item2);\n            Assert.Equal(3, ((Tuple<ComplexNonIComparableParameter, int>)sortedData[2].Items[0].Value!).Item2);\n            Assert.Equal(4, ((Tuple<ComplexNonIComparableParameter, int>)sortedData[3].Items[0].Value!).Item2);\n        }\n\n        private class ComplexParameter : IComparable<ComplexParameter>, IComparable\n        {\n            public ComplexParameter(int value, string name)\n            {\n                Value = value;\n                Name = name;\n            }\n\n            public int Value { get; }\n\n            public string Name { get; }\n\n            public override string ToString()\n            {\n                return Name;\n            }\n\n            public int CompareTo(ComplexParameter? other)\n            {\n                if (other == null)\n                {\n                    return 1;\n                }\n\n                return Value.CompareTo(other.Value);\n            }\n\n            public int CompareTo(object? obj)\n            {\n                if (obj == null)\n                {\n                    return 1;\n                }\n\n                if (obj is not ComplexParameter other)\n                {\n                    throw new ArgumentException();\n                }\n\n                return CompareTo(other);\n            }\n        }\n\n        private class ComplexNonIComparableParameter\n        {\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/ParameterInstanceTests.cs",
    "content": "﻿using BenchmarkDotNet.Parameters;\nusing BenchmarkDotNet.Reports;\nusing System;\nusing System.Collections.Generic;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests\n{\n    public class ParameterInstanceTests\n    {\n        private static readonly ParameterDefinition definition = new ParameterDefinition(\"Testing\", isStatic: false, values: [], isArgument: false, parameterType: null!, 0);\n\n        [Theory]\n        [InlineData(5)]\n        [InlineData('e')]\n        [InlineData(\"short\")]\n        public void ShortParameterValuesDisplayOriginalValue(object value)\n        {\n            var parameter = new ParameterInstance(definition, value, null);\n\n            Assert.Equal(value.ToString(), parameter.ToDisplayText());\n        }\n\n        [Theory]\n        [InlineData(\"text/plain,text/html;q=0.9,application/xhtml+xml;q=0.9,application/xml;q=0.8,*/*;q=0.7\", \"text/(...)q=0.7 [86]\")]\n        [InlineData(\"All the world's a stage, and all the men and women merely players: they have their exits and their entrances; and one man in his time plays many parts, his acts being seven ages.\", \"All (...)ges. [178]\")]\n        [InlineData(\"this is a test to see what happens when we call tolower.\", \"this (...)ower. [56]\")]\n        public void VeryLongParameterValuesAreTrimmed(string initialLongText, string expectedDisplayText)\n        {\n            var parameter = new ParameterInstance(definition, initialLongText, null);\n\n            Assert.NotEqual(initialLongText, parameter.ToDisplayText());\n\n            Assert.Equal(expectedDisplayText, parameter.ToDisplayText());\n        }\n\n        [Theory]\n        [InlineData(\"0123456789012345\", \"0123456789012345\")]\n        [InlineData(\"01234567890123456\", \"01234567890123456\")]\n        [InlineData(\"012345678901234567\", \"012345678901234567\")]\n        [InlineData(\"0123456789012345678\", \"0123456789012345678\")]\n        [InlineData(\"01234567890123456789\", \"01234567890123456789\")]\n        [InlineData(\"012345678901234567890\", \"01234(...)67890 [21]\")]\n        public void TrimmingTheValuesMakesThemActuallyShorter(string initialLongText, string expectedDisplayText)\n        {\n            var parameter = new ParameterInstance(definition, initialLongText, null);\n\n            Assert.Equal(expectedDisplayText, parameter.ToDisplayText());\n        }\n\n        [Theory]\n        [InlineData(typeof(ATypeWithAVeryVeryVeryVeryVeryVeryLongNameeeeeeeee), nameof(ATypeWithAVeryVeryVeryVeryVeryVeryLongNameeeeeeeee))]\n        [InlineData(typeof(Guid), nameof(Guid))]\n        [InlineData(typeof(Guid?), \"Guid?\")]\n        [InlineData(typeof(List<int>), \"List<Int32>\")]\n        public void TypeParameterValuesDisplayNotTrimmedTypeNameWithoutNamespace(Type type, string expectedName)\n        {\n            var parameter = new ParameterInstance(definition, type, null);\n\n            Assert.Equal(expectedName, parameter.ToDisplayText());\n        }\n\n        [Theory]\n        [InlineData(\"012345678901234567890\", 21, \"012345678901234567890\")] // the default is 20\n        [InlineData(\"0123456789012345678901234567890123456789\", 30, \"0123456789(...)0123456789 [40]\")]\n        [InlineData(\"😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀\", 20, \"😀😀(...)😀😀 [54]\")]\n        [InlineData(\"a😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀\", 20, \"a😀😀(...)😀😀 [55]\")]\n        [InlineData(\"😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀b\", 20, \"😀😀(...)😀😀b [55]\")]\n        [InlineData(\"a😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀b\", 20, \"a😀😀(...)😀😀b [56]\")]\n        public void MaxParameterColumnWidthCanBeCustomized(string initialLongText, int maxParameterColumnWidth, string expectedDisplayText)\n        {\n            var summaryStyle = SummaryStyle.Default.WithMaxParameterColumnWidth(maxParameterColumnWidth);\n            var parameter = new ParameterInstance(definition, initialLongText, summaryStyle);\n\n            Assert.Equal(expectedDisplayText, parameter.ToDisplayText());\n        }\n\n        [Theory]\n        [InlineData(-100)]\n        [InlineData(0)]\n        [InlineData(10)]\n        public void MaxParameterColumnWidthCanNotBeSetToValueLessThanDefault(int newWidth)\n            => Assert.Throws<ArgumentOutOfRangeException>(() => SummaryStyle.Default.WithMaxParameterColumnWidth(newWidth));\n    }\n\n    public class ATypeWithAVeryVeryVeryVeryVeryVeryLongNameeeeeeeee { }\n}\n"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/ParamsSourceTests.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Running;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests\n{\n    public class ParamsSourceTests\n    {\n        // #1809\n        [Fact]\n        public void NullIsSupportedAsElementOfParamsSource()\n        {\n            BenchmarkConverter.TypeToBenchmarks(typeof(ParamsSourceWithNull));\n        }\n\n        public class ParamsSourceWithNull\n        {\n            public static IEnumerable<object?> Values()\n            {\n                yield return null;\n                yield return ValueTuple.Create(10);\n                yield return (10, 20);\n                yield return (10, 20, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9);\n            }\n\n            [ParamsSource(nameof(Values))]\n            public required object? O { get; set; }\n\n            [Benchmark]\n            public object? FooBar() => O;\n        }\n\n        // #2980\n        [Fact]\n        public void WriteOnlyPropertyDoesThrowNullReferenceException()\n        {\n            var exception = Assert.Throws<InvalidBenchmarkDeclarationException>(\n                () => BenchmarkConverter.TypeToBenchmarks(typeof(ClassWithWriteOnlyProperty)));\n\n            Assert.Contains(nameof(ClassWithWriteOnlyProperty.WriteOnlyValues), exception.Message);\n            Assert.Contains(\"no public, accessible method/property\", exception.Message);\n        }\n\n        public class ClassWithWriteOnlyProperty\n        {\n            private int _writeOnlyValue;\n\n            public int WriteOnlyValues\n            {\n                set { _writeOnlyValue = value; }\n            }\n\n#pragma warning disable BDN1305 // Test intentionally uses write-only property\n            [ParamsSource(nameof(WriteOnlyValues))]\n            public int MyParam { get; set; }\n#pragma warning restore BDN1305\n\n            [Benchmark]\n            public void Run() { }\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Perfonar/Infra/PerfonarMock.cs",
    "content": "using BenchmarkDotNet.Properties;\nusing Perfolizer.Models;\n\nnamespace BenchmarkDotNet.Tests.Perfonar.Infra;\n\npublic static class PerfonarMock\n{\n    public static readonly EngineInfo Engine = new()\n    {\n        Name = BenchmarkDotNetInfo.BenchmarkDotNetCaption,\n        Version = \"0.1729.0-mock\"\n    };\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Perfonar/Infra/PerfonarTestExtensions.cs",
    "content": "using Perfolizer.Metrology;\nusing Perfolizer.Models;\n\nnamespace BenchmarkDotNet.Tests.Perfonar.Infra;\n\npublic static class PerfonarTestExtensions\n{\n    public static EntryInfo AddMetrics(this EntryInfo entry, params string[] metrics)\n    {\n        for (int i = 0; i < metrics.Length; i++)\n        {\n            var measurement = PerfolizerMeasurementFormatter.Instance.Parse(metrics[i]);\n            entry.Add(new EntryInfo\n            {\n                IterationIndex = i,\n                Value = measurement.NominalValue,\n                Unit = measurement.Unit\n            });\n        }\n        return entry;\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Perfonar/PerfonarTests.cs",
    "content": "using System.Collections.Generic;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Models;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Tests.Builders;\nusing BenchmarkDotNet.Tests.Infra;\nusing BenchmarkDotNet.Tests.Perfonar.Infra;\nusing JetBrains.Annotations;\nusing Perfolizer.Models;\nusing Perfolizer.Json;\nusing Perfolizer.Perfonar.Base;\nusing Perfolizer.Perfonar.Tables;\nusing VerifyXunit;\nusing Xunit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.Tests.Perfonar;\n\npublic class PerfonarTests(ITestOutputHelper output)\n{\n    [Theory]\n    [MemberData(nameof(EntryDataKeys))]\n    public Task PerfonarIndexTest(string key) => VerifyString(key, new PerfonarIndex(TableDataMap[key].RootEntry).Dump());\n\n    [Theory]\n    [MemberData(nameof(EntryDataKeys))]\n    public Task PerfonarTableTest(string key)\n    {\n        var table = TableDataMap[key];\n        string markdown = table.ToMarkdown(new PerfonarTableStyle());\n        string json = LightJsonSerializer.Serialize(table.RootEntry, new LightJsonSettings { Indent = true });\n        return VerifyString(key, markdown + \"\\n\" + json);\n    }\n\n    private static readonly IDictionary<string, PerfonarTable> TableDataMap = new Dictionary<string, PerfonarTable>\n    {\n        {\n            \"default01\", new PerfonarTable(\n                Root().Add(\n                    Benchmark(\"Foo\", \"10ns\", \"11ns\", \"12ns\"),\n                    Benchmark(\"Bar\", \"200ns\", \"201ns\", \"202ns\")\n                ),\n                GetDefaultTableConfig()\n            )\n        },\n        {\n            \"default02\", new PerfonarTable(\n                Root().Add(\n                    Job(RuntimeMoniker.Net481).Add(\n                        Benchmark(\"Foo\", \"10ns\", \"11ns\", \"12ns\"),\n                        Benchmark(\"Bar\", \"20ns\", \"21ns\", \"22ns\")),\n                    Job(RuntimeMoniker.Net70).Add(\n                        Benchmark(\"Foo\", \"30ns\", \"31ns\", \"32ns\"),\n                        Benchmark(\"Bar\", \"40ns\", \"41ns\", \"42ns\"))),\n                GetDefaultTableConfig()\n            )\n        },\n        {\n            \"default03\", new PerfonarTable(\n                Root().Add(\n                    Job(RuntimeMoniker.Net70, Jit.RyuJit).Add(\n                        Benchmark(\"Foo\", \"30ns\", \"31ns\", \"32ns\"),\n                        Benchmark(\"Bar\", \"40ns\", \"41ns\", \"42ns\"))),\n                GetDefaultTableConfig()\n            )\n        },\n        {\n            \"default04\", new PerfonarTable(\n                Root().Add(\n                    Job(RuntimeMoniker.Net481, Jit.LegacyJit).Add(\n                        Benchmark(\"Foo\", \"10ns\", \"11ns\", \"12ns\"),\n                        Benchmark(\"Bar\", \"20ns\", \"21ns\", \"22ns\")),\n                    Job(RuntimeMoniker.Net70, Jit.RyuJit).Add(\n                        Benchmark(\"Foo\", \"30ns\", \"31ns\", \"32ns\"),\n                        Benchmark(\"Bar\", \"40ns\", \"41ns\", \"42ns\"))),\n                GetDefaultTableConfig()\n            )\n        },\n        {\n            \"default05\", new PerfonarTable(\n                Root().Add(\n                    Enumerable.Range(0, 20).Select(index =>\n                        Job((RuntimeMoniker)index, Jit.RyuJit, index).Add(\n                            Benchmark(\"Foo\", index * 10 + 1 + \"ns\", index * 10 + 2 + \"ns\", index * 10 + 3 + \"ns\"),\n                            Benchmark(\"Bar\", index * 10 + 6 + \"ns\", index * 10 + 7 + \"ns\", index * 10 + 8 + \"ns\")\n                        )).ToArray()),\n                GetDefaultTableConfig()\n            )\n        },\n        {\n            \"sort01\", new PerfonarTable(\n                new EntryInfo().Add(Benchmark(\"Foo\", \"10ms\"), Benchmark(\"Bar\", \"20ms\")),\n                new PerfonarTableConfig\n                {\n                    ColumnDefinitions =\n                    {\n                        new PerfonarColumnDefinition(\".benchmark.method\"),\n                        new PerfonarColumnDefinition(\"=center\")\n                    },\n                    SortPolicies =\n                    [\n                        new PerfonarSortPolicy(\"=center\", PerfonarSortDirection.Descending)\n                    ]\n                })\n        },\n        {\n            \"params01\", new PerfonarTable(\n                new EntryInfo().Add(\n                    new EntryInfo\n                    {\n                        Parameters = new Dictionary<string, object> { { \"A\", 1 }, { \"B\", 2 } }\n                    }.Add(Benchmark(\"Foo\", \"10ms\"))).Add(\n                    new EntryInfo\n                    {\n                        Parameters = new Dictionary<string, object> { { \"A\", 10 }, { \"B\", 20 } }\n                    }.Add(Benchmark(\"Bar\", \"20ms\"))),\n                new PerfonarTableConfig\n                {\n                    ColumnDefinitions =\n                    {\n                        new PerfonarColumnDefinition(\".benchmark.method\"),\n                        new PerfonarColumnDefinition(\".parameters\"),\n                        new PerfonarColumnDefinition(\"=center\")\n                    }\n                }\n            )\n        }\n    };\n\n    [UsedImplicitly] public static TheoryData<string> EntryDataKeys = TheoryDataHelper.Create(TableDataMap.Keys);\n\n    private static EntryInfo Root() => new EntryInfo\n    {\n        Engine = PerfonarMock.Engine,\n        Host = new HostEnvironmentInfoBuilder().Build().ToPerfonar()\n    };\n\n    private static PerfonarTableConfig GetDefaultTableConfig() => new()\n    {\n        ColumnDefinitions =\n        [\n            new PerfonarColumnDefinition(\".engine\") { Cloud = \"primary\", IsSelfExplanatory = true, IsAtomic = true },\n            new PerfonarColumnDefinition(\".host.os\") { Cloud = \"primary\", IsSelfExplanatory = true, IsAtomic = true },\n            new PerfonarColumnDefinition(\".host.cpu\") { Cloud = \"primary\", IsSelfExplanatory = true, IsAtomic = true },\n            new PerfonarColumnDefinition(\".benchmark\") { Cloud = \"secondary\" },\n            new PerfonarColumnDefinition(\".job\") { Cloud = \"secondary\", Compressed = true },\n            new PerfonarColumnDefinition(\"=center\"),\n            new PerfonarColumnDefinition(\"=spread\")\n        ]\n    };\n\n    private static EntryInfo Job(RuntimeMoniker? runtime = null, Jit? jit = null, int? affinity = null) => new EntryInfo\n    {\n        Job = new JobInfo\n        {\n            Environment = new BdnEnvironment { Runtime = runtime, Jit = jit, Affinity = affinity }\n        }\n    };\n\n    private static EntryInfo Benchmark(string name, params string[] metrics) => new EntryInfo\n    {\n        Benchmark = new BdnBenchmark { Type = \"Bench\", Method = name }\n    }.AddMetrics(metrics);\n\n    private Task VerifyString(string key, string content)\n    {\n        output.WriteLine(content);\n        var settings = VerifyHelper.Create(\"Perfonar\");\n        settings.UseParameters(key);\n        return Verifier.Verify(content, settings);\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Perfonar/VerifiedFiles/Perfonar.PerfonarIndexTest_key=default01.verified.txt",
    "content": "﻿[Keys]\n  .benchmark\n  .benchmark.method\n  .benchmark.type\n  .engine\n  .engine.name\n  .engine.version\n  .host\n  .host.chronometerFrequency\n  .host.configuration\n  .host.cpu\n  .host.cpu.logicalCoreCount\n  .host.cpu.maxFrequencyHz\n  .host.cpu.nominalFrequencyHz\n  .host.cpu.physicalCoreCount\n  .host.cpu.physicalProcessorCount\n  .host.cpu.processorName\n  .host.dotNetSdkVersion\n  .host.hardwareTimerKind\n  .host.hasAttachedDebugger\n  .host.hasRyuJit\n  .host.os\n  .host.os.display\n  .host.runtimeVersion\n  .iterationIndex\n  .unit\n  .value\n\n[Entry0]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 0\n  .unit = ns\n  .value = 10\n[Entry1]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 1\n  .unit = ns\n  .value = 11\n[Entry2]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 2\n  .unit = ns\n  .value = 12\n[Entry3]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 0\n  .unit = ns\n  .value = 200\n[Entry4]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 1\n  .unit = ns\n  .value = 201\n[Entry5]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 2\n  .unit = ns\n  .value = 202"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Perfonar/VerifiedFiles/Perfonar.PerfonarIndexTest_key=default02.verified.txt",
    "content": "﻿[Keys]\n  .benchmark\n  .benchmark.method\n  .benchmark.type\n  .engine\n  .engine.name\n  .engine.version\n  .host\n  .host.chronometerFrequency\n  .host.configuration\n  .host.cpu\n  .host.cpu.logicalCoreCount\n  .host.cpu.maxFrequencyHz\n  .host.cpu.nominalFrequencyHz\n  .host.cpu.physicalCoreCount\n  .host.cpu.physicalProcessorCount\n  .host.cpu.processorName\n  .host.dotNetSdkVersion\n  .host.hardwareTimerKind\n  .host.hasAttachedDebugger\n  .host.hasRyuJit\n  .host.os\n  .host.os.display\n  .host.runtimeVersion\n  .iterationIndex\n  .job\n  .job.environment\n  .job.environment.runtime\n  .unit\n  .value\n\n[Entry0]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 0\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.runtime = Net481\n  .unit = ns\n  .value = 10\n[Entry1]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 1\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.runtime = Net481\n  .unit = ns\n  .value = 11\n[Entry2]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 2\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.runtime = Net481\n  .unit = ns\n  .value = 12\n[Entry3]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 0\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.runtime = Net481\n  .unit = ns\n  .value = 20\n[Entry4]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 1\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.runtime = Net481\n  .unit = ns\n  .value = 21\n[Entry5]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 2\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.runtime = Net481\n  .unit = ns\n  .value = 22\n[Entry6]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 0\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.runtime = Net70\n  .unit = ns\n  .value = 30\n[Entry7]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 1\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.runtime = Net70\n  .unit = ns\n  .value = 31\n[Entry8]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 2\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.runtime = Net70\n  .unit = ns\n  .value = 32\n[Entry9]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 0\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.runtime = Net70\n  .unit = ns\n  .value = 40\n[Entry10]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 1\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.runtime = Net70\n  .unit = ns\n  .value = 41\n[Entry11]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 2\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.runtime = Net70\n  .unit = ns\n  .value = 42"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Perfonar/VerifiedFiles/Perfonar.PerfonarIndexTest_key=default03.verified.txt",
    "content": "﻿[Keys]\n  .benchmark\n  .benchmark.method\n  .benchmark.type\n  .engine\n  .engine.name\n  .engine.version\n  .host\n  .host.chronometerFrequency\n  .host.configuration\n  .host.cpu\n  .host.cpu.logicalCoreCount\n  .host.cpu.maxFrequencyHz\n  .host.cpu.nominalFrequencyHz\n  .host.cpu.physicalCoreCount\n  .host.cpu.physicalProcessorCount\n  .host.cpu.processorName\n  .host.dotNetSdkVersion\n  .host.hardwareTimerKind\n  .host.hasAttachedDebugger\n  .host.hasRyuJit\n  .host.os\n  .host.os.display\n  .host.runtimeVersion\n  .iterationIndex\n  .job\n  .job.environment\n  .job.environment.jit\n  .job.environment.runtime\n  .unit\n  .value\n\n[Entry0]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 0\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net70\n  .unit = ns\n  .value = 30\n[Entry1]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 1\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net70\n  .unit = ns\n  .value = 31\n[Entry2]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 2\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net70\n  .unit = ns\n  .value = 32\n[Entry3]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 0\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net70\n  .unit = ns\n  .value = 40\n[Entry4]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 1\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net70\n  .unit = ns\n  .value = 41\n[Entry5]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 2\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net70\n  .unit = ns\n  .value = 42"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Perfonar/VerifiedFiles/Perfonar.PerfonarIndexTest_key=default04.verified.txt",
    "content": "﻿[Keys]\n  .benchmark\n  .benchmark.method\n  .benchmark.type\n  .engine\n  .engine.name\n  .engine.version\n  .host\n  .host.chronometerFrequency\n  .host.configuration\n  .host.cpu\n  .host.cpu.logicalCoreCount\n  .host.cpu.maxFrequencyHz\n  .host.cpu.nominalFrequencyHz\n  .host.cpu.physicalCoreCount\n  .host.cpu.physicalProcessorCount\n  .host.cpu.processorName\n  .host.dotNetSdkVersion\n  .host.hardwareTimerKind\n  .host.hasAttachedDebugger\n  .host.hasRyuJit\n  .host.os\n  .host.os.display\n  .host.runtimeVersion\n  .iterationIndex\n  .job\n  .job.environment\n  .job.environment.jit\n  .job.environment.runtime\n  .unit\n  .value\n\n[Entry0]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 0\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.jit = LegacyJit\n  .job.environment.runtime = Net481\n  .unit = ns\n  .value = 10\n[Entry1]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 1\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.jit = LegacyJit\n  .job.environment.runtime = Net481\n  .unit = ns\n  .value = 11\n[Entry2]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 2\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.jit = LegacyJit\n  .job.environment.runtime = Net481\n  .unit = ns\n  .value = 12\n[Entry3]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 0\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.jit = LegacyJit\n  .job.environment.runtime = Net481\n  .unit = ns\n  .value = 20\n[Entry4]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 1\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.jit = LegacyJit\n  .job.environment.runtime = Net481\n  .unit = ns\n  .value = 21\n[Entry5]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 2\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.jit = LegacyJit\n  .job.environment.runtime = Net481\n  .unit = ns\n  .value = 22\n[Entry6]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 0\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net70\n  .unit = ns\n  .value = 30\n[Entry7]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 1\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net70\n  .unit = ns\n  .value = 31\n[Entry8]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 2\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net70\n  .unit = ns\n  .value = 32\n[Entry9]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 0\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net70\n  .unit = ns\n  .value = 40\n[Entry10]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 1\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net70\n  .unit = ns\n  .value = 41\n[Entry11]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 2\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net70\n  .unit = ns\n  .value = 42"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Perfonar/VerifiedFiles/Perfonar.PerfonarIndexTest_key=default05.verified.txt",
    "content": "﻿[Keys]\n  .benchmark\n  .benchmark.method\n  .benchmark.type\n  .engine\n  .engine.name\n  .engine.version\n  .host\n  .host.chronometerFrequency\n  .host.configuration\n  .host.cpu\n  .host.cpu.logicalCoreCount\n  .host.cpu.maxFrequencyHz\n  .host.cpu.nominalFrequencyHz\n  .host.cpu.physicalCoreCount\n  .host.cpu.physicalProcessorCount\n  .host.cpu.processorName\n  .host.dotNetSdkVersion\n  .host.hardwareTimerKind\n  .host.hasAttachedDebugger\n  .host.hasRyuJit\n  .host.os\n  .host.os.display\n  .host.runtimeVersion\n  .iterationIndex\n  .job\n  .job.environment\n  .job.environment.affinity\n  .job.environment.jit\n  .job.environment.runtime\n  .unit\n  .value\n\n[Entry0]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 0\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 0\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = HostProcess\n  .unit = ns\n  .value = 1\n[Entry1]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 1\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 0\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = HostProcess\n  .unit = ns\n  .value = 2\n[Entry2]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 2\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 0\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = HostProcess\n  .unit = ns\n  .value = 3\n[Entry3]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 0\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 0\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = HostProcess\n  .unit = ns\n  .value = 6\n[Entry4]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 1\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 0\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = HostProcess\n  .unit = ns\n  .value = 7\n[Entry5]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 2\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 0\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = HostProcess\n  .unit = ns\n  .value = 8\n[Entry6]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 0\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 1\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = NotRecognized\n  .unit = ns\n  .value = 11\n[Entry7]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 1\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 1\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = NotRecognized\n  .unit = ns\n  .value = 12\n[Entry8]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 2\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 1\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = NotRecognized\n  .unit = ns\n  .value = 13\n[Entry9]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 0\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 1\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = NotRecognized\n  .unit = ns\n  .value = 16\n[Entry10]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 1\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 1\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = NotRecognized\n  .unit = ns\n  .value = 17\n[Entry11]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 2\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 1\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = NotRecognized\n  .unit = ns\n  .value = 18\n[Entry12]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 0\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 2\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Mono\n  .unit = ns\n  .value = 21\n[Entry13]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 1\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 2\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Mono\n  .unit = ns\n  .value = 22\n[Entry14]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 2\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 2\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Mono\n  .unit = ns\n  .value = 23\n[Entry15]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 0\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 2\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Mono\n  .unit = ns\n  .value = 26\n[Entry16]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 1\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 2\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Mono\n  .unit = ns\n  .value = 27\n[Entry17]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 2\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 2\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Mono\n  .unit = ns\n  .value = 28\n[Entry18]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 0\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 3\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net461\n  .unit = ns\n  .value = 31\n[Entry19]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 1\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 3\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net461\n  .unit = ns\n  .value = 32\n[Entry20]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 2\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 3\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net461\n  .unit = ns\n  .value = 33\n[Entry21]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 0\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 3\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net461\n  .unit = ns\n  .value = 36\n[Entry22]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 1\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 3\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net461\n  .unit = ns\n  .value = 37\n[Entry23]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 2\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 3\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net461\n  .unit = ns\n  .value = 38\n[Entry24]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 0\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 4\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net462\n  .unit = ns\n  .value = 41\n[Entry25]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 1\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 4\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net462\n  .unit = ns\n  .value = 42\n[Entry26]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 2\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 4\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net462\n  .unit = ns\n  .value = 43\n[Entry27]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 0\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 4\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net462\n  .unit = ns\n  .value = 46\n[Entry28]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 1\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 4\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net462\n  .unit = ns\n  .value = 47\n[Entry29]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 2\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 4\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net462\n  .unit = ns\n  .value = 48\n[Entry30]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 0\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 5\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net47\n  .unit = ns\n  .value = 51\n[Entry31]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 1\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 5\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net47\n  .unit = ns\n  .value = 52\n[Entry32]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 2\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 5\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net47\n  .unit = ns\n  .value = 53\n[Entry33]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 0\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 5\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net47\n  .unit = ns\n  .value = 56\n[Entry34]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 1\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 5\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net47\n  .unit = ns\n  .value = 57\n[Entry35]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 2\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 5\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net47\n  .unit = ns\n  .value = 58\n[Entry36]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 0\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 6\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net471\n  .unit = ns\n  .value = 61\n[Entry37]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 1\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 6\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net471\n  .unit = ns\n  .value = 62\n[Entry38]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 2\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 6\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net471\n  .unit = ns\n  .value = 63\n[Entry39]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 0\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 6\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net471\n  .unit = ns\n  .value = 66\n[Entry40]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 1\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 6\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net471\n  .unit = ns\n  .value = 67\n[Entry41]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 2\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 6\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net471\n  .unit = ns\n  .value = 68\n[Entry42]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 0\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 7\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net472\n  .unit = ns\n  .value = 71\n[Entry43]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 1\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 7\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net472\n  .unit = ns\n  .value = 72\n[Entry44]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 2\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 7\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net472\n  .unit = ns\n  .value = 73\n[Entry45]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 0\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 7\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net472\n  .unit = ns\n  .value = 76\n[Entry46]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 1\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 7\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net472\n  .unit = ns\n  .value = 77\n[Entry47]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 2\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 7\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net472\n  .unit = ns\n  .value = 78\n[Entry48]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 0\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 8\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net48\n  .unit = ns\n  .value = 81\n[Entry49]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 1\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 8\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net48\n  .unit = ns\n  .value = 82\n[Entry50]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 2\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 8\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net48\n  .unit = ns\n  .value = 83\n[Entry51]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 0\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 8\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net48\n  .unit = ns\n  .value = 86\n[Entry52]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 1\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 8\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net48\n  .unit = ns\n  .value = 87\n[Entry53]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 2\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 8\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net48\n  .unit = ns\n  .value = 88\n[Entry54]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 0\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 9\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net481\n  .unit = ns\n  .value = 91\n[Entry55]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 1\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 9\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net481\n  .unit = ns\n  .value = 92\n[Entry56]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 2\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 9\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net481\n  .unit = ns\n  .value = 93\n[Entry57]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 0\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 9\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net481\n  .unit = ns\n  .value = 96\n[Entry58]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 1\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 9\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net481\n  .unit = ns\n  .value = 97\n[Entry59]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 2\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 9\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net481\n  .unit = ns\n  .value = 98\n[Entry60]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 0\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 10\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = NetCoreApp20\n  .unit = ns\n  .value = 101\n[Entry61]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 1\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 10\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = NetCoreApp20\n  .unit = ns\n  .value = 102\n[Entry62]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 2\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 10\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = NetCoreApp20\n  .unit = ns\n  .value = 103\n[Entry63]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 0\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 10\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = NetCoreApp20\n  .unit = ns\n  .value = 106\n[Entry64]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 1\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 10\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = NetCoreApp20\n  .unit = ns\n  .value = 107\n[Entry65]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 2\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 10\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = NetCoreApp20\n  .unit = ns\n  .value = 108\n[Entry66]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 0\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 11\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = NetCoreApp21\n  .unit = ns\n  .value = 111\n[Entry67]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 1\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 11\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = NetCoreApp21\n  .unit = ns\n  .value = 112\n[Entry68]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 2\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 11\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = NetCoreApp21\n  .unit = ns\n  .value = 113\n[Entry69]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 0\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 11\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = NetCoreApp21\n  .unit = ns\n  .value = 116\n[Entry70]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 1\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 11\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = NetCoreApp21\n  .unit = ns\n  .value = 117\n[Entry71]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 2\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 11\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = NetCoreApp21\n  .unit = ns\n  .value = 118\n[Entry72]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 0\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 12\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = NetCoreApp22\n  .unit = ns\n  .value = 121\n[Entry73]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 1\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 12\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = NetCoreApp22\n  .unit = ns\n  .value = 122\n[Entry74]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 2\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 12\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = NetCoreApp22\n  .unit = ns\n  .value = 123\n[Entry75]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 0\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 12\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = NetCoreApp22\n  .unit = ns\n  .value = 126\n[Entry76]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 1\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 12\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = NetCoreApp22\n  .unit = ns\n  .value = 127\n[Entry77]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 2\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 12\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = NetCoreApp22\n  .unit = ns\n  .value = 128\n[Entry78]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 0\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 13\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = NetCoreApp30\n  .unit = ns\n  .value = 131\n[Entry79]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 1\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 13\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = NetCoreApp30\n  .unit = ns\n  .value = 132\n[Entry80]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 2\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 13\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = NetCoreApp30\n  .unit = ns\n  .value = 133\n[Entry81]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 0\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 13\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = NetCoreApp30\n  .unit = ns\n  .value = 136\n[Entry82]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 1\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 13\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = NetCoreApp30\n  .unit = ns\n  .value = 137\n[Entry83]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 2\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 13\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = NetCoreApp30\n  .unit = ns\n  .value = 138\n[Entry84]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 0\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 14\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = NetCoreApp31\n  .unit = ns\n  .value = 141\n[Entry85]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 1\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 14\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = NetCoreApp31\n  .unit = ns\n  .value = 142\n[Entry86]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 2\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 14\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = NetCoreApp31\n  .unit = ns\n  .value = 143\n[Entry87]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 0\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 14\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = NetCoreApp31\n  .unit = ns\n  .value = 146\n[Entry88]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 1\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 14\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = NetCoreApp31\n  .unit = ns\n  .value = 147\n[Entry89]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 2\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 14\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = NetCoreApp31\n  .unit = ns\n  .value = 148\n[Entry90]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 0\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 15\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net50\n  .unit = ns\n  .value = 151\n[Entry91]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 1\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 15\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net50\n  .unit = ns\n  .value = 152\n[Entry92]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 2\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 15\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net50\n  .unit = ns\n  .value = 153\n[Entry93]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 0\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 15\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net50\n  .unit = ns\n  .value = 156\n[Entry94]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 1\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 15\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net50\n  .unit = ns\n  .value = 157\n[Entry95]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 2\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 15\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net50\n  .unit = ns\n  .value = 158\n[Entry96]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 0\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 16\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net60\n  .unit = ns\n  .value = 161\n[Entry97]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 1\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 16\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net60\n  .unit = ns\n  .value = 162\n[Entry98]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 2\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 16\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net60\n  .unit = ns\n  .value = 163\n[Entry99]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 0\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 16\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net60\n  .unit = ns\n  .value = 166\n[Entry100]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 1\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 16\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net60\n  .unit = ns\n  .value = 167\n[Entry101]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 2\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 16\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net60\n  .unit = ns\n  .value = 168\n[Entry102]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 0\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 17\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net70\n  .unit = ns\n  .value = 171\n[Entry103]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 1\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 17\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net70\n  .unit = ns\n  .value = 172\n[Entry104]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 2\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 17\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net70\n  .unit = ns\n  .value = 173\n[Entry105]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 0\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 17\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net70\n  .unit = ns\n  .value = 176\n[Entry106]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 1\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 17\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net70\n  .unit = ns\n  .value = 177\n[Entry107]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 2\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 17\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net70\n  .unit = ns\n  .value = 178\n[Entry108]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 0\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 18\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net80\n  .unit = ns\n  .value = 181\n[Entry109]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 1\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 18\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net80\n  .unit = ns\n  .value = 182\n[Entry110]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 2\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 18\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net80\n  .unit = ns\n  .value = 183\n[Entry111]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 0\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 18\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net80\n  .unit = ns\n  .value = 186\n[Entry112]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 1\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 18\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net80\n  .unit = ns\n  .value = 187\n[Entry113]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 2\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 18\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net80\n  .unit = ns\n  .value = 188\n[Entry114]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 0\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 19\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net90\n  .unit = ns\n  .value = 191\n[Entry115]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 1\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 19\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net90\n  .unit = ns\n  .value = 192\n[Entry116]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 2\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 19\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net90\n  .unit = ns\n  .value = 193\n[Entry117]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 0\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 19\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net90\n  .unit = ns\n  .value = 196\n[Entry118]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 1\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 19\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net90\n  .unit = ns\n  .value = 197\n[Entry119]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .engine = BenchmarkDotNet v0.1729.0-mock\n  .engine.name = BenchmarkDotNet\n  .engine.version = 0.1729.0-mock\n  .host = <object>\n  .host.chronometerFrequency = 2531248\n  .host.configuration = CONFIGURATION\n  .host.cpu = MockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n  .host.cpu.logicalCoreCount = 8\n  .host.cpu.maxFrequencyHz = 3100000000\n  .host.cpu.nominalFrequencyHz = 3100000000\n  .host.cpu.physicalCoreCount = 4\n  .host.cpu.physicalProcessorCount = 1\n  .host.cpu.processorName = MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\n  .host.dotNetSdkVersion = 1.0.x.mock\n  .host.hardwareTimerKind = Tsc\n  .host.hasAttachedDebugger = False\n  .host.hasRyuJit = True\n  .host.os = Microsoft Windows NT 10.0.x.mock\n  .host.os.display = Microsoft Windows NT 10.0.x.mock\n  .host.runtimeVersion = Clr 4.0.x.mock\n  .iterationIndex = 2\n  .job = <object>\n  .job.environment = <object>\n  .job.environment.affinity = 19\n  .job.environment.jit = RyuJit\n  .job.environment.runtime = Net90\n  .unit = ns\n  .value = 198"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Perfonar/VerifiedFiles/Perfonar.PerfonarIndexTest_key=params01.verified.txt",
    "content": "﻿[Keys]\n  .benchmark\n  .benchmark.method\n  .benchmark.type\n  .iterationIndex\n  .parameters\n  .parameters.a\n  .parameters.b\n  .unit\n  .value\n\n[Entry0]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .iterationIndex = 0\n  .parameters = <dictionary>\n  .parameters.a = 1\n  .parameters.b = 2\n  .unit = ms\n  .value = 10\n[Entry1]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .iterationIndex = 0\n  .parameters = <dictionary>\n  .parameters.a = 10\n  .parameters.b = 20\n  .unit = ms\n  .value = 20"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Perfonar/VerifiedFiles/Perfonar.PerfonarIndexTest_key=sort01.verified.txt",
    "content": "﻿[Keys]\n  .benchmark\n  .benchmark.method\n  .benchmark.type\n  .iterationIndex\n  .unit\n  .value\n\n[Entry0]\n  .benchmark = Bench.Foo\n  .benchmark.method = Foo\n  .benchmark.type = Bench\n  .iterationIndex = 0\n  .unit = ms\n  .value = 10\n[Entry1]\n  .benchmark = Bench.Bar\n  .benchmark.method = Bar\n  .benchmark.type = Bench\n  .iterationIndex = 0\n  .unit = ms\n  .value = 20"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Perfonar/VerifiedFiles/Perfonar.PerfonarTableTest_key=default01.verified.txt",
    "content": "﻿BenchmarkDotNet v0.1729.0-mock, Microsoft Windows NT 10.0.x.mock\nMockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n\nType = Bench\n\n| Method |   Center |  Spread |\n|:-------|---------:|--------:|\n| Foo    |  11.0 ns | 0.81 ns |\n| Bar    | 201.0 ns | 0.81 ns |\n\n{\n  \"engine\": {\n    \"name\": \"BenchmarkDotNet\",\n    \"version\": \"0.1729.0-mock\"\n  },\n  \"host\": {\n    \"runtimeVersion\": \"Clr 4.0.x.mock\",\n    \"hasAttachedDebugger\": false,\n    \"hasRyuJit\": true,\n    \"configuration\": \"CONFIGURATION\",\n    \"dotNetSdkVersion\": \"1.0.x.mock\",\n    \"chronometerFrequency\": 2531248,\n    \"hardwareTimerKind\": \"Tsc\",\n    \"os\": {\n      \"display\": \"Microsoft Windows NT 10.0.x.mock\"\n    },\n    \"cpu\": {\n      \"processorName\": \"MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\",\n      \"physicalProcessorCount\": 1,\n      \"physicalCoreCount\": 4,\n      \"logicalCoreCount\": 8,\n      \"nominalFrequencyHz\": 3100000000,\n      \"maxFrequencyHz\": 3100000000\n    }\n  },\n  \"nested\": [\n    {\n      \"benchmark\": {\n        \"type\": \"Bench\",\n        \"method\": \"Foo\"\n      },\n      \"nested\": [\n        {\n          \"value\": 10,\n          \"unit\": \"ns\",\n          \"iterationIndex\": 0\n        },\n        {\n          \"value\": 11,\n          \"unit\": \"ns\",\n          \"iterationIndex\": 1\n        },\n        {\n          \"value\": 12,\n          \"unit\": \"ns\",\n          \"iterationIndex\": 2\n        }\n      ]\n    },\n    {\n      \"benchmark\": {\n        \"type\": \"Bench\",\n        \"method\": \"Bar\"\n      },\n      \"nested\": [\n        {\n          \"value\": 200,\n          \"unit\": \"ns\",\n          \"iterationIndex\": 0\n        },\n        {\n          \"value\": 201,\n          \"unit\": \"ns\",\n          \"iterationIndex\": 1\n        },\n        {\n          \"value\": 202,\n          \"unit\": \"ns\",\n          \"iterationIndex\": 2\n        }\n      ]\n    }\n  ]\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Perfonar/VerifiedFiles/Perfonar.PerfonarTableTest_key=default02.verified.txt",
    "content": "﻿BenchmarkDotNet v0.1729.0-mock, Microsoft Windows NT 10.0.x.mock\nMockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n\nType = Bench\n\n| Method | Runtime |  Center |  Spread |\n|:-------|:--------|--------:|--------:|\n| Foo    | Net481  | 11.0 ns | 0.81 ns |\n| Bar    | Net481  | 21.0 ns | 0.81 ns |\n| Foo    | Net70   | 31.0 ns | 0.81 ns |\n| Bar    | Net70   | 41.0 ns | 0.81 ns |\n\n{\n  \"engine\": {\n    \"name\": \"BenchmarkDotNet\",\n    \"version\": \"0.1729.0-mock\"\n  },\n  \"host\": {\n    \"runtimeVersion\": \"Clr 4.0.x.mock\",\n    \"hasAttachedDebugger\": false,\n    \"hasRyuJit\": true,\n    \"configuration\": \"CONFIGURATION\",\n    \"dotNetSdkVersion\": \"1.0.x.mock\",\n    \"chronometerFrequency\": 2531248,\n    \"hardwareTimerKind\": \"Tsc\",\n    \"os\": {\n      \"display\": \"Microsoft Windows NT 10.0.x.mock\"\n    },\n    \"cpu\": {\n      \"processorName\": \"MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\",\n      \"physicalProcessorCount\": 1,\n      \"physicalCoreCount\": 4,\n      \"logicalCoreCount\": 8,\n      \"nominalFrequencyHz\": 3100000000,\n      \"maxFrequencyHz\": 3100000000\n    }\n  },\n  \"nested\": [\n    {\n      \"job\": {\n        \"environment\": {\n          \"runtime\": \"net481\"\n        }\n      },\n      \"nested\": [\n        {\n          \"benchmark\": {\n            \"type\": \"Bench\",\n            \"method\": \"Foo\"\n          },\n          \"nested\": [\n            {\n              \"value\": 10,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 0\n            },\n            {\n              \"value\": 11,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 1\n            },\n            {\n              \"value\": 12,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 2\n            }\n          ]\n        },\n        {\n          \"benchmark\": {\n            \"type\": \"Bench\",\n            \"method\": \"Bar\"\n          },\n          \"nested\": [\n            {\n              \"value\": 20,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 0\n            },\n            {\n              \"value\": 21,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 1\n            },\n            {\n              \"value\": 22,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 2\n            }\n          ]\n        }\n      ]\n    },\n    {\n      \"job\": {\n        \"environment\": {\n          \"runtime\": \"net70\"\n        }\n      },\n      \"nested\": [\n        {\n          \"benchmark\": {\n            \"type\": \"Bench\",\n            \"method\": \"Foo\"\n          },\n          \"nested\": [\n            {\n              \"value\": 30,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 0\n            },\n            {\n              \"value\": 31,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 1\n            },\n            {\n              \"value\": 32,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 2\n            }\n          ]\n        },\n        {\n          \"benchmark\": {\n            \"type\": \"Bench\",\n            \"method\": \"Bar\"\n          },\n          \"nested\": [\n            {\n              \"value\": 40,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 0\n            },\n            {\n              \"value\": 41,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 1\n            },\n            {\n              \"value\": 42,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 2\n            }\n          ]\n        }\n      ]\n    }\n  ]\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Perfonar/VerifiedFiles/Perfonar.PerfonarTableTest_key=default03.verified.txt",
    "content": "﻿BenchmarkDotNet v0.1729.0-mock, Microsoft Windows NT 10.0.x.mock\nMockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n\nType = Bench, Runtime = Net70, Jit = RyuJit\n\n| Method |  Center |  Spread |\n|:-------|--------:|--------:|\n| Foo    | 31.0 ns | 0.81 ns |\n| Bar    | 41.0 ns | 0.81 ns |\n\n{\n  \"engine\": {\n    \"name\": \"BenchmarkDotNet\",\n    \"version\": \"0.1729.0-mock\"\n  },\n  \"host\": {\n    \"runtimeVersion\": \"Clr 4.0.x.mock\",\n    \"hasAttachedDebugger\": false,\n    \"hasRyuJit\": true,\n    \"configuration\": \"CONFIGURATION\",\n    \"dotNetSdkVersion\": \"1.0.x.mock\",\n    \"chronometerFrequency\": 2531248,\n    \"hardwareTimerKind\": \"Tsc\",\n    \"os\": {\n      \"display\": \"Microsoft Windows NT 10.0.x.mock\"\n    },\n    \"cpu\": {\n      \"processorName\": \"MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\",\n      \"physicalProcessorCount\": 1,\n      \"physicalCoreCount\": 4,\n      \"logicalCoreCount\": 8,\n      \"nominalFrequencyHz\": 3100000000,\n      \"maxFrequencyHz\": 3100000000\n    }\n  },\n  \"nested\": [\n    {\n      \"job\": {\n        \"environment\": {\n          \"runtime\": \"net70\",\n          \"jit\": \"ryuJit\"\n        }\n      },\n      \"nested\": [\n        {\n          \"benchmark\": {\n            \"type\": \"Bench\",\n            \"method\": \"Foo\"\n          },\n          \"nested\": [\n            {\n              \"value\": 30,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 0\n            },\n            {\n              \"value\": 31,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 1\n            },\n            {\n              \"value\": 32,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 2\n            }\n          ]\n        },\n        {\n          \"benchmark\": {\n            \"type\": \"Bench\",\n            \"method\": \"Bar\"\n          },\n          \"nested\": [\n            {\n              \"value\": 40,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 0\n            },\n            {\n              \"value\": 41,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 1\n            },\n            {\n              \"value\": 42,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 2\n            }\n          ]\n        }\n      ]\n    }\n  ]\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Perfonar/VerifiedFiles/Perfonar.PerfonarTableTest_key=default04.verified.txt",
    "content": "﻿BenchmarkDotNet v0.1729.0-mock, Microsoft Windows NT 10.0.x.mock\nMockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n\nType = Bench\n\n@Net481LegacyJit: Runtime = Net481, Jit = LegacyJit\n@Net70RyuJit:     Runtime = Net70, Jit = RyuJit\n\n| Method | Job             |  Center |  Spread |\n|:-------|:----------------|--------:|--------:|\n| Foo    | Net481LegacyJit | 11.0 ns | 0.81 ns |\n| Bar    | Net481LegacyJit | 21.0 ns | 0.81 ns |\n| Foo    | Net70RyuJit     | 31.0 ns | 0.81 ns |\n| Bar    | Net70RyuJit     | 41.0 ns | 0.81 ns |\n\n{\n  \"engine\": {\n    \"name\": \"BenchmarkDotNet\",\n    \"version\": \"0.1729.0-mock\"\n  },\n  \"host\": {\n    \"runtimeVersion\": \"Clr 4.0.x.mock\",\n    \"hasAttachedDebugger\": false,\n    \"hasRyuJit\": true,\n    \"configuration\": \"CONFIGURATION\",\n    \"dotNetSdkVersion\": \"1.0.x.mock\",\n    \"chronometerFrequency\": 2531248,\n    \"hardwareTimerKind\": \"Tsc\",\n    \"os\": {\n      \"display\": \"Microsoft Windows NT 10.0.x.mock\"\n    },\n    \"cpu\": {\n      \"processorName\": \"MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\",\n      \"physicalProcessorCount\": 1,\n      \"physicalCoreCount\": 4,\n      \"logicalCoreCount\": 8,\n      \"nominalFrequencyHz\": 3100000000,\n      \"maxFrequencyHz\": 3100000000\n    }\n  },\n  \"nested\": [\n    {\n      \"job\": {\n        \"environment\": {\n          \"runtime\": \"net481\",\n          \"jit\": \"legacyJit\"\n        }\n      },\n      \"nested\": [\n        {\n          \"benchmark\": {\n            \"type\": \"Bench\",\n            \"method\": \"Foo\"\n          },\n          \"nested\": [\n            {\n              \"value\": 10,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 0\n            },\n            {\n              \"value\": 11,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 1\n            },\n            {\n              \"value\": 12,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 2\n            }\n          ]\n        },\n        {\n          \"benchmark\": {\n            \"type\": \"Bench\",\n            \"method\": \"Bar\"\n          },\n          \"nested\": [\n            {\n              \"value\": 20,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 0\n            },\n            {\n              \"value\": 21,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 1\n            },\n            {\n              \"value\": 22,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 2\n            }\n          ]\n        }\n      ]\n    },\n    {\n      \"job\": {\n        \"environment\": {\n          \"runtime\": \"net70\",\n          \"jit\": \"ryuJit\"\n        }\n      },\n      \"nested\": [\n        {\n          \"benchmark\": {\n            \"type\": \"Bench\",\n            \"method\": \"Foo\"\n          },\n          \"nested\": [\n            {\n              \"value\": 30,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 0\n            },\n            {\n              \"value\": 31,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 1\n            },\n            {\n              \"value\": 32,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 2\n            }\n          ]\n        },\n        {\n          \"benchmark\": {\n            \"type\": \"Bench\",\n            \"method\": \"Bar\"\n          },\n          \"nested\": [\n            {\n              \"value\": 40,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 0\n            },\n            {\n              \"value\": 41,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 1\n            },\n            {\n              \"value\": 42,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 2\n            }\n          ]\n        }\n      ]\n    }\n  ]\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Perfonar/VerifiedFiles/Perfonar.PerfonarTableTest_key=default05.verified.txt",
    "content": "﻿BenchmarkDotNet v0.1729.0-mock, Microsoft Windows NT 10.0.x.mock\nMockIntel Core i7-6700HQ CPU 2.60GHz (Max: 3.10GHz), 1 CPU, 8 logical and 4 physical cores\n\nType = Bench, Jit = RyuJit\n\n@HostProcessAffinity0: Runtime = HostProcess, Affinity = 0\n@Squid:                Runtime = NotRecognized, Affinity = 1\n@MonoAffinity2:        Runtime = Mono, Affinity = 2\n@Net461Affinity3:      Runtime = Net461, Affinity = 3\n@Net462Affinity4:      Runtime = Net462, Affinity = 4\n@Net47Affinity5:       Runtime = Net47, Affinity = 5\n@Net471Affinity6:      Runtime = Net471, Affinity = 6\n@Net472Affinity7:      Runtime = Net472, Affinity = 7\n@Net48Affinity8:       Runtime = Net48, Affinity = 8\n@Net481Affinity9:      Runtime = Net481, Affinity = 9\n@Liger:                Runtime = NetCoreApp20, Affinity = 10\n@Rat:                  Runtime = NetCoreApp21, Affinity = 11\n@Skate:                Runtime = NetCoreApp22, Affinity = 12\n@Perch:                Runtime = NetCoreApp30, Affinity = 13\n@Roach:                Runtime = NetCoreApp31, Affinity = 14\n@Net50Affinity15:      Runtime = Net50, Affinity = 15\n@Net60Affinity16:      Runtime = Net60, Affinity = 16\n@Net70Affinity17:      Runtime = Net70, Affinity = 17\n@Net80Affinity18:      Runtime = Net80, Affinity = 18\n@Net90Affinity19:      Runtime = Net90, Affinity = 19\n\n| Method | Job                  |    Center |  Spread |\n|:-------|:---------------------|----------:|--------:|\n| Foo    | HostProcessAffinity0 |   2.00 ns | 0.81 ns |\n| Bar    | HostProcessAffinity0 |   7.00 ns | 0.81 ns |\n| Foo    | Squid                |  12.00 ns | 0.81 ns |\n| Bar    | Squid                |  17.00 ns | 0.81 ns |\n| Foo    | MonoAffinity2        |  22.00 ns | 0.81 ns |\n| Bar    | MonoAffinity2        |  27.00 ns | 0.81 ns |\n| Foo    | Net461Affinity3      |  32.00 ns | 0.81 ns |\n| Bar    | Net461Affinity3      |  37.00 ns | 0.81 ns |\n| Foo    | Net462Affinity4      |  42.00 ns | 0.81 ns |\n| Bar    | Net462Affinity4      |  47.00 ns | 0.81 ns |\n| Foo    | Net47Affinity5       |  52.00 ns | 0.81 ns |\n| Bar    | Net47Affinity5       |  57.00 ns | 0.81 ns |\n| Foo    | Net471Affinity6      |  62.00 ns | 0.81 ns |\n| Bar    | Net471Affinity6      |  67.00 ns | 0.81 ns |\n| Foo    | Net472Affinity7      |  72.00 ns | 0.81 ns |\n| Bar    | Net472Affinity7      |  77.00 ns | 0.81 ns |\n| Foo    | Net48Affinity8       |  82.00 ns | 0.81 ns |\n| Bar    | Net48Affinity8       |  87.00 ns | 0.81 ns |\n| Foo    | Net481Affinity9      |  92.00 ns | 0.81 ns |\n| Bar    | Net481Affinity9      |  97.00 ns | 0.81 ns |\n| Foo    | Liger                | 102.00 ns | 0.81 ns |\n| Bar    | Liger                | 107.00 ns | 0.81 ns |\n| Foo    | Rat                  | 112.00 ns | 0.81 ns |\n| Bar    | Rat                  | 117.00 ns | 0.81 ns |\n| Foo    | Skate                | 122.00 ns | 0.81 ns |\n| Bar    | Skate                | 127.00 ns | 0.81 ns |\n| Foo    | Perch                | 132.00 ns | 0.81 ns |\n| Bar    | Perch                | 137.00 ns | 0.81 ns |\n| Foo    | Roach                | 142.00 ns | 0.81 ns |\n| Bar    | Roach                | 147.00 ns | 0.81 ns |\n| Foo    | Net50Affinity15      | 152.00 ns | 0.81 ns |\n| Bar    | Net50Affinity15      | 157.00 ns | 0.81 ns |\n| Foo    | Net60Affinity16      | 162.00 ns | 0.81 ns |\n| Bar    | Net60Affinity16      | 167.00 ns | 0.81 ns |\n| Foo    | Net70Affinity17      | 172.00 ns | 0.81 ns |\n| Bar    | Net70Affinity17      | 177.00 ns | 0.81 ns |\n| Foo    | Net80Affinity18      | 182.00 ns | 0.81 ns |\n| Bar    | Net80Affinity18      | 187.00 ns | 0.81 ns |\n| Foo    | Net90Affinity19      | 192.00 ns | 0.81 ns |\n| Bar    | Net90Affinity19      | 197.00 ns | 0.81 ns |\n\n{\n  \"engine\": {\n    \"name\": \"BenchmarkDotNet\",\n    \"version\": \"0.1729.0-mock\"\n  },\n  \"host\": {\n    \"runtimeVersion\": \"Clr 4.0.x.mock\",\n    \"hasAttachedDebugger\": false,\n    \"hasRyuJit\": true,\n    \"configuration\": \"CONFIGURATION\",\n    \"dotNetSdkVersion\": \"1.0.x.mock\",\n    \"chronometerFrequency\": 2531248,\n    \"hardwareTimerKind\": \"Tsc\",\n    \"os\": {\n      \"display\": \"Microsoft Windows NT 10.0.x.mock\"\n    },\n    \"cpu\": {\n      \"processorName\": \"MockIntel(R) Core(TM) i7-6700HQ CPU 2.60GHz\",\n      \"physicalProcessorCount\": 1,\n      \"physicalCoreCount\": 4,\n      \"logicalCoreCount\": 8,\n      \"nominalFrequencyHz\": 3100000000,\n      \"maxFrequencyHz\": 3100000000\n    }\n  },\n  \"nested\": [\n    {\n      \"job\": {\n        \"environment\": {\n          \"runtime\": \"hostProcess\",\n          \"jit\": \"ryuJit\",\n          \"affinity\": 0\n        }\n      },\n      \"nested\": [\n        {\n          \"benchmark\": {\n            \"type\": \"Bench\",\n            \"method\": \"Foo\"\n          },\n          \"nested\": [\n            {\n              \"value\": 1,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 0\n            },\n            {\n              \"value\": 2,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 1\n            },\n            {\n              \"value\": 3,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 2\n            }\n          ]\n        },\n        {\n          \"benchmark\": {\n            \"type\": \"Bench\",\n            \"method\": \"Bar\"\n          },\n          \"nested\": [\n            {\n              \"value\": 6,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 0\n            },\n            {\n              \"value\": 7,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 1\n            },\n            {\n              \"value\": 8,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 2\n            }\n          ]\n        }\n      ]\n    },\n    {\n      \"job\": {\n        \"environment\": {\n          \"runtime\": \"notRecognized\",\n          \"jit\": \"ryuJit\",\n          \"affinity\": 1\n        }\n      },\n      \"nested\": [\n        {\n          \"benchmark\": {\n            \"type\": \"Bench\",\n            \"method\": \"Foo\"\n          },\n          \"nested\": [\n            {\n              \"value\": 11,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 0\n            },\n            {\n              \"value\": 12,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 1\n            },\n            {\n              \"value\": 13,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 2\n            }\n          ]\n        },\n        {\n          \"benchmark\": {\n            \"type\": \"Bench\",\n            \"method\": \"Bar\"\n          },\n          \"nested\": [\n            {\n              \"value\": 16,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 0\n            },\n            {\n              \"value\": 17,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 1\n            },\n            {\n              \"value\": 18,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 2\n            }\n          ]\n        }\n      ]\n    },\n    {\n      \"job\": {\n        \"environment\": {\n          \"runtime\": \"mono\",\n          \"jit\": \"ryuJit\",\n          \"affinity\": 2\n        }\n      },\n      \"nested\": [\n        {\n          \"benchmark\": {\n            \"type\": \"Bench\",\n            \"method\": \"Foo\"\n          },\n          \"nested\": [\n            {\n              \"value\": 21,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 0\n            },\n            {\n              \"value\": 22,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 1\n            },\n            {\n              \"value\": 23,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 2\n            }\n          ]\n        },\n        {\n          \"benchmark\": {\n            \"type\": \"Bench\",\n            \"method\": \"Bar\"\n          },\n          \"nested\": [\n            {\n              \"value\": 26,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 0\n            },\n            {\n              \"value\": 27,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 1\n            },\n            {\n              \"value\": 28,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 2\n            }\n          ]\n        }\n      ]\n    },\n    {\n      \"job\": {\n        \"environment\": {\n          \"runtime\": \"net461\",\n          \"jit\": \"ryuJit\",\n          \"affinity\": 3\n        }\n      },\n      \"nested\": [\n        {\n          \"benchmark\": {\n            \"type\": \"Bench\",\n            \"method\": \"Foo\"\n          },\n          \"nested\": [\n            {\n              \"value\": 31,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 0\n            },\n            {\n              \"value\": 32,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 1\n            },\n            {\n              \"value\": 33,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 2\n            }\n          ]\n        },\n        {\n          \"benchmark\": {\n            \"type\": \"Bench\",\n            \"method\": \"Bar\"\n          },\n          \"nested\": [\n            {\n              \"value\": 36,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 0\n            },\n            {\n              \"value\": 37,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 1\n            },\n            {\n              \"value\": 38,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 2\n            }\n          ]\n        }\n      ]\n    },\n    {\n      \"job\": {\n        \"environment\": {\n          \"runtime\": \"net462\",\n          \"jit\": \"ryuJit\",\n          \"affinity\": 4\n        }\n      },\n      \"nested\": [\n        {\n          \"benchmark\": {\n            \"type\": \"Bench\",\n            \"method\": \"Foo\"\n          },\n          \"nested\": [\n            {\n              \"value\": 41,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 0\n            },\n            {\n              \"value\": 42,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 1\n            },\n            {\n              \"value\": 43,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 2\n            }\n          ]\n        },\n        {\n          \"benchmark\": {\n            \"type\": \"Bench\",\n            \"method\": \"Bar\"\n          },\n          \"nested\": [\n            {\n              \"value\": 46,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 0\n            },\n            {\n              \"value\": 47,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 1\n            },\n            {\n              \"value\": 48,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 2\n            }\n          ]\n        }\n      ]\n    },\n    {\n      \"job\": {\n        \"environment\": {\n          \"runtime\": \"net47\",\n          \"jit\": \"ryuJit\",\n          \"affinity\": 5\n        }\n      },\n      \"nested\": [\n        {\n          \"benchmark\": {\n            \"type\": \"Bench\",\n            \"method\": \"Foo\"\n          },\n          \"nested\": [\n            {\n              \"value\": 51,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 0\n            },\n            {\n              \"value\": 52,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 1\n            },\n            {\n              \"value\": 53,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 2\n            }\n          ]\n        },\n        {\n          \"benchmark\": {\n            \"type\": \"Bench\",\n            \"method\": \"Bar\"\n          },\n          \"nested\": [\n            {\n              \"value\": 56,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 0\n            },\n            {\n              \"value\": 57,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 1\n            },\n            {\n              \"value\": 58,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 2\n            }\n          ]\n        }\n      ]\n    },\n    {\n      \"job\": {\n        \"environment\": {\n          \"runtime\": \"net471\",\n          \"jit\": \"ryuJit\",\n          \"affinity\": 6\n        }\n      },\n      \"nested\": [\n        {\n          \"benchmark\": {\n            \"type\": \"Bench\",\n            \"method\": \"Foo\"\n          },\n          \"nested\": [\n            {\n              \"value\": 61,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 0\n            },\n            {\n              \"value\": 62,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 1\n            },\n            {\n              \"value\": 63,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 2\n            }\n          ]\n        },\n        {\n          \"benchmark\": {\n            \"type\": \"Bench\",\n            \"method\": \"Bar\"\n          },\n          \"nested\": [\n            {\n              \"value\": 66,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 0\n            },\n            {\n              \"value\": 67,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 1\n            },\n            {\n              \"value\": 68,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 2\n            }\n          ]\n        }\n      ]\n    },\n    {\n      \"job\": {\n        \"environment\": {\n          \"runtime\": \"net472\",\n          \"jit\": \"ryuJit\",\n          \"affinity\": 7\n        }\n      },\n      \"nested\": [\n        {\n          \"benchmark\": {\n            \"type\": \"Bench\",\n            \"method\": \"Foo\"\n          },\n          \"nested\": [\n            {\n              \"value\": 71,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 0\n            },\n            {\n              \"value\": 72,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 1\n            },\n            {\n              \"value\": 73,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 2\n            }\n          ]\n        },\n        {\n          \"benchmark\": {\n            \"type\": \"Bench\",\n            \"method\": \"Bar\"\n          },\n          \"nested\": [\n            {\n              \"value\": 76,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 0\n            },\n            {\n              \"value\": 77,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 1\n            },\n            {\n              \"value\": 78,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 2\n            }\n          ]\n        }\n      ]\n    },\n    {\n      \"job\": {\n        \"environment\": {\n          \"runtime\": \"net48\",\n          \"jit\": \"ryuJit\",\n          \"affinity\": 8\n        }\n      },\n      \"nested\": [\n        {\n          \"benchmark\": {\n            \"type\": \"Bench\",\n            \"method\": \"Foo\"\n          },\n          \"nested\": [\n            {\n              \"value\": 81,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 0\n            },\n            {\n              \"value\": 82,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 1\n            },\n            {\n              \"value\": 83,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 2\n            }\n          ]\n        },\n        {\n          \"benchmark\": {\n            \"type\": \"Bench\",\n            \"method\": \"Bar\"\n          },\n          \"nested\": [\n            {\n              \"value\": 86,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 0\n            },\n            {\n              \"value\": 87,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 1\n            },\n            {\n              \"value\": 88,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 2\n            }\n          ]\n        }\n      ]\n    },\n    {\n      \"job\": {\n        \"environment\": {\n          \"runtime\": \"net481\",\n          \"jit\": \"ryuJit\",\n          \"affinity\": 9\n        }\n      },\n      \"nested\": [\n        {\n          \"benchmark\": {\n            \"type\": \"Bench\",\n            \"method\": \"Foo\"\n          },\n          \"nested\": [\n            {\n              \"value\": 91,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 0\n            },\n            {\n              \"value\": 92,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 1\n            },\n            {\n              \"value\": 93,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 2\n            }\n          ]\n        },\n        {\n          \"benchmark\": {\n            \"type\": \"Bench\",\n            \"method\": \"Bar\"\n          },\n          \"nested\": [\n            {\n              \"value\": 96,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 0\n            },\n            {\n              \"value\": 97,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 1\n            },\n            {\n              \"value\": 98,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 2\n            }\n          ]\n        }\n      ]\n    },\n    {\n      \"job\": {\n        \"environment\": {\n          \"runtime\": \"netCoreApp20\",\n          \"jit\": \"ryuJit\",\n          \"affinity\": 10\n        }\n      },\n      \"nested\": [\n        {\n          \"benchmark\": {\n            \"type\": \"Bench\",\n            \"method\": \"Foo\"\n          },\n          \"nested\": [\n            {\n              \"value\": 101,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 0\n            },\n            {\n              \"value\": 102,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 1\n            },\n            {\n              \"value\": 103,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 2\n            }\n          ]\n        },\n        {\n          \"benchmark\": {\n            \"type\": \"Bench\",\n            \"method\": \"Bar\"\n          },\n          \"nested\": [\n            {\n              \"value\": 106,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 0\n            },\n            {\n              \"value\": 107,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 1\n            },\n            {\n              \"value\": 108,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 2\n            }\n          ]\n        }\n      ]\n    },\n    {\n      \"job\": {\n        \"environment\": {\n          \"runtime\": \"netCoreApp21\",\n          \"jit\": \"ryuJit\",\n          \"affinity\": 11\n        }\n      },\n      \"nested\": [\n        {\n          \"benchmark\": {\n            \"type\": \"Bench\",\n            \"method\": \"Foo\"\n          },\n          \"nested\": [\n            {\n              \"value\": 111,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 0\n            },\n            {\n              \"value\": 112,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 1\n            },\n            {\n              \"value\": 113,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 2\n            }\n          ]\n        },\n        {\n          \"benchmark\": {\n            \"type\": \"Bench\",\n            \"method\": \"Bar\"\n          },\n          \"nested\": [\n            {\n              \"value\": 116,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 0\n            },\n            {\n              \"value\": 117,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 1\n            },\n            {\n              \"value\": 118,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 2\n            }\n          ]\n        }\n      ]\n    },\n    {\n      \"job\": {\n        \"environment\": {\n          \"runtime\": \"netCoreApp22\",\n          \"jit\": \"ryuJit\",\n          \"affinity\": 12\n        }\n      },\n      \"nested\": [\n        {\n          \"benchmark\": {\n            \"type\": \"Bench\",\n            \"method\": \"Foo\"\n          },\n          \"nested\": [\n            {\n              \"value\": 121,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 0\n            },\n            {\n              \"value\": 122,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 1\n            },\n            {\n              \"value\": 123,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 2\n            }\n          ]\n        },\n        {\n          \"benchmark\": {\n            \"type\": \"Bench\",\n            \"method\": \"Bar\"\n          },\n          \"nested\": [\n            {\n              \"value\": 126,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 0\n            },\n            {\n              \"value\": 127,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 1\n            },\n            {\n              \"value\": 128,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 2\n            }\n          ]\n        }\n      ]\n    },\n    {\n      \"job\": {\n        \"environment\": {\n          \"runtime\": \"netCoreApp30\",\n          \"jit\": \"ryuJit\",\n          \"affinity\": 13\n        }\n      },\n      \"nested\": [\n        {\n          \"benchmark\": {\n            \"type\": \"Bench\",\n            \"method\": \"Foo\"\n          },\n          \"nested\": [\n            {\n              \"value\": 131,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 0\n            },\n            {\n              \"value\": 132,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 1\n            },\n            {\n              \"value\": 133,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 2\n            }\n          ]\n        },\n        {\n          \"benchmark\": {\n            \"type\": \"Bench\",\n            \"method\": \"Bar\"\n          },\n          \"nested\": [\n            {\n              \"value\": 136,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 0\n            },\n            {\n              \"value\": 137,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 1\n            },\n            {\n              \"value\": 138,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 2\n            }\n          ]\n        }\n      ]\n    },\n    {\n      \"job\": {\n        \"environment\": {\n          \"runtime\": \"netCoreApp31\",\n          \"jit\": \"ryuJit\",\n          \"affinity\": 14\n        }\n      },\n      \"nested\": [\n        {\n          \"benchmark\": {\n            \"type\": \"Bench\",\n            \"method\": \"Foo\"\n          },\n          \"nested\": [\n            {\n              \"value\": 141,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 0\n            },\n            {\n              \"value\": 142,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 1\n            },\n            {\n              \"value\": 143,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 2\n            }\n          ]\n        },\n        {\n          \"benchmark\": {\n            \"type\": \"Bench\",\n            \"method\": \"Bar\"\n          },\n          \"nested\": [\n            {\n              \"value\": 146,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 0\n            },\n            {\n              \"value\": 147,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 1\n            },\n            {\n              \"value\": 148,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 2\n            }\n          ]\n        }\n      ]\n    },\n    {\n      \"job\": {\n        \"environment\": {\n          \"runtime\": \"net50\",\n          \"jit\": \"ryuJit\",\n          \"affinity\": 15\n        }\n      },\n      \"nested\": [\n        {\n          \"benchmark\": {\n            \"type\": \"Bench\",\n            \"method\": \"Foo\"\n          },\n          \"nested\": [\n            {\n              \"value\": 151,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 0\n            },\n            {\n              \"value\": 152,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 1\n            },\n            {\n              \"value\": 153,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 2\n            }\n          ]\n        },\n        {\n          \"benchmark\": {\n            \"type\": \"Bench\",\n            \"method\": \"Bar\"\n          },\n          \"nested\": [\n            {\n              \"value\": 156,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 0\n            },\n            {\n              \"value\": 157,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 1\n            },\n            {\n              \"value\": 158,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 2\n            }\n          ]\n        }\n      ]\n    },\n    {\n      \"job\": {\n        \"environment\": {\n          \"runtime\": \"net60\",\n          \"jit\": \"ryuJit\",\n          \"affinity\": 16\n        }\n      },\n      \"nested\": [\n        {\n          \"benchmark\": {\n            \"type\": \"Bench\",\n            \"method\": \"Foo\"\n          },\n          \"nested\": [\n            {\n              \"value\": 161,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 0\n            },\n            {\n              \"value\": 162,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 1\n            },\n            {\n              \"value\": 163,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 2\n            }\n          ]\n        },\n        {\n          \"benchmark\": {\n            \"type\": \"Bench\",\n            \"method\": \"Bar\"\n          },\n          \"nested\": [\n            {\n              \"value\": 166,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 0\n            },\n            {\n              \"value\": 167,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 1\n            },\n            {\n              \"value\": 168,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 2\n            }\n          ]\n        }\n      ]\n    },\n    {\n      \"job\": {\n        \"environment\": {\n          \"runtime\": \"net70\",\n          \"jit\": \"ryuJit\",\n          \"affinity\": 17\n        }\n      },\n      \"nested\": [\n        {\n          \"benchmark\": {\n            \"type\": \"Bench\",\n            \"method\": \"Foo\"\n          },\n          \"nested\": [\n            {\n              \"value\": 171,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 0\n            },\n            {\n              \"value\": 172,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 1\n            },\n            {\n              \"value\": 173,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 2\n            }\n          ]\n        },\n        {\n          \"benchmark\": {\n            \"type\": \"Bench\",\n            \"method\": \"Bar\"\n          },\n          \"nested\": [\n            {\n              \"value\": 176,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 0\n            },\n            {\n              \"value\": 177,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 1\n            },\n            {\n              \"value\": 178,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 2\n            }\n          ]\n        }\n      ]\n    },\n    {\n      \"job\": {\n        \"environment\": {\n          \"runtime\": \"net80\",\n          \"jit\": \"ryuJit\",\n          \"affinity\": 18\n        }\n      },\n      \"nested\": [\n        {\n          \"benchmark\": {\n            \"type\": \"Bench\",\n            \"method\": \"Foo\"\n          },\n          \"nested\": [\n            {\n              \"value\": 181,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 0\n            },\n            {\n              \"value\": 182,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 1\n            },\n            {\n              \"value\": 183,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 2\n            }\n          ]\n        },\n        {\n          \"benchmark\": {\n            \"type\": \"Bench\",\n            \"method\": \"Bar\"\n          },\n          \"nested\": [\n            {\n              \"value\": 186,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 0\n            },\n            {\n              \"value\": 187,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 1\n            },\n            {\n              \"value\": 188,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 2\n            }\n          ]\n        }\n      ]\n    },\n    {\n      \"job\": {\n        \"environment\": {\n          \"runtime\": \"net90\",\n          \"jit\": \"ryuJit\",\n          \"affinity\": 19\n        }\n      },\n      \"nested\": [\n        {\n          \"benchmark\": {\n            \"type\": \"Bench\",\n            \"method\": \"Foo\"\n          },\n          \"nested\": [\n            {\n              \"value\": 191,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 0\n            },\n            {\n              \"value\": 192,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 1\n            },\n            {\n              \"value\": 193,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 2\n            }\n          ]\n        },\n        {\n          \"benchmark\": {\n            \"type\": \"Bench\",\n            \"method\": \"Bar\"\n          },\n          \"nested\": [\n            {\n              \"value\": 196,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 0\n            },\n            {\n              \"value\": 197,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 1\n            },\n            {\n              \"value\": 198,\n              \"unit\": \"ns\",\n              \"iterationIndex\": 2\n            }\n          ]\n        }\n      ]\n    }\n  ]\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Perfonar/VerifiedFiles/Perfonar.PerfonarTableTest_key=params01.verified.txt",
    "content": "﻿| Method |  A |  B |  Center |\n|:-------|---:|---:|--------:|\n| Foo    |  1 |  2 | 10.0 ms |\n| Bar    | 10 | 20 | 20.0 ms |\n\n{\n  \"nested\": [\n    {\n      \"parameters\": {\n        \"a\": 1,\n        \"b\": 2\n      },\n      \"nested\": [\n        {\n          \"benchmark\": {\n            \"type\": \"Bench\",\n            \"method\": \"Foo\"\n          },\n          \"nested\": [\n            {\n              \"value\": 10,\n              \"unit\": \"ms\",\n              \"iterationIndex\": 0\n            }\n          ]\n        }\n      ]\n    },\n    {\n      \"parameters\": {\n        \"a\": 10,\n        \"b\": 20\n      },\n      \"nested\": [\n        {\n          \"benchmark\": {\n            \"type\": \"Bench\",\n            \"method\": \"Bar\"\n          },\n          \"nested\": [\n            {\n              \"value\": 20,\n              \"unit\": \"ms\",\n              \"iterationIndex\": 0\n            }\n          ]\n        }\n      ]\n    }\n  ]\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Perfonar/VerifiedFiles/Perfonar.PerfonarTableTest_key=sort01.verified.txt",
    "content": "﻿| Method |  Center |\n|:-------|--------:|\n| Bar    | 20.0 ms |\n| Foo    | 10.0 ms |\n\n{\n  \"nested\": [\n    {\n      \"benchmark\": {\n        \"type\": \"Bench\",\n        \"method\": \"Foo\"\n      },\n      \"nested\": [\n        {\n          \"value\": 10,\n          \"unit\": \"ms\",\n          \"iterationIndex\": 0\n        }\n      ]\n    },\n    {\n      \"benchmark\": {\n        \"type\": \"Bench\",\n        \"method\": \"Bar\"\n      },\n      \"nested\": [\n        {\n          \"value\": 20,\n          \"unit\": \"ms\",\n          \"iterationIndex\": 0\n        }\n      ]\n    }\n  ]\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Portability/HyperVTests.cs",
    "content": "﻿using BenchmarkDotNet.Portability;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests.Portability\n{\n    public class HyperVTests\n    {\n        private readonly VirtualMachineHypervisor hypervisor = HyperV.Default;\n\n        [Fact]\n        public void ContainsCorrectName()\n        {\n            Assert.Equal(\"Hyper-V\", hypervisor.Name);\n        }\n\n        [Theory]\n        [InlineData(\"Microsoft Corporation\", \"Virtual Machine\", true)]\n        [InlineData(\"microsoft corporation\", \"virtual machine\", true)]\n        [InlineData(\"microsoft\", \"virtual\", true)]\n        [InlineData(\"Dell\", \"virtual\", false)]\n        [InlineData(\"Dell\", \"ubuntu\", false)]\n        [InlineData(\"microsoft corporation\", null, false)]\n        [InlineData(null, \"virtual machine\", false)]\n        public void DetectsVirtualMachine(string? manufacturer, string? model, bool expectedResult)\n        {\n            bool result = hypervisor.IsVirtualMachine(manufacturer!, model!);\n            Assert.Equal(expectedResult, result);\n        }\n    }\n}\n"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Portability/VMWareTests.cs",
    "content": "﻿using BenchmarkDotNet.Portability;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests.Portability\n{\n    public class VMwareTests\n    {\n        private readonly VirtualMachineHypervisor hypervisor = VMware.Default;\n\n        [Fact]\n        public void ContainsCorrectName()\n        {\n            Assert.Equal(\"VMware\", hypervisor.Name);\n        }\n\n        [Theory]\n        [InlineData(\"VMWare Inc\", \"VMWare\", true)]\n        [InlineData(\"VMWare Inc\", \"vmWare\", true)]\n        [InlineData(\"redundant\", \"vmWare\", true)]\n        [InlineData(null, \"vmWare\", true)]\n        [InlineData(\"VMWare Inc\", \"redundant\", false)]\n        [InlineData(\"VMWare Inc\", null, false)]\n        public void DetectsVirtualMachine(string? manufacturer, string? model, bool expectedResult)\n        {\n            bool result = hypervisor.IsVirtualMachine(manufacturer!, model!);\n            Assert.Equal(expectedResult, result);\n        }\n    }\n}\n"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Portability/VirtualBoxTests.cs",
    "content": "﻿using BenchmarkDotNet.Portability;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests.Portability\n{\n    public class VirtualBoxTests\n    {\n        private readonly VirtualMachineHypervisor hypervisor = VirtualBox.Default;\n\n        [Fact]\n        public void ContainsCorrectName()\n        {\n            Assert.Equal(\"VirtualBox\", hypervisor.Name);\n        }\n\n        [Theory]\n        [InlineData(\"redundant\", \"virtualbox\", true)]\n        [InlineData(\"redundant\", \"VirtualBox\", true)]\n        [InlineData(\"redundant\", \"vmware\", false)]\n        [InlineData(\"redundant\", null, false)]\n        public void DetectsVirtualMachine(string manufacturer, string? model, bool expectedResult)\n        {\n            bool result = hypervisor.IsVirtualMachine(manufacturer, model!);\n            Assert.Equal(expectedResult, result);\n        }\n    }\n}\n"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Properties/AssemblyInfo.cs",
    "content": "﻿using System.Runtime.InteropServices;\n\n[assembly: Guid(\"16c47abf-43e0-4db4-8151-36ca7a4082ae\")]\n"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Properties/BenchmarkDotNetInfoTests.cs",
    "content": "using BenchmarkDotNet.Properties;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests.Properties;\n\npublic class BenchmarkDotNetInfoTests\n{\n    [Theory]\n    [InlineData(\"\", \"\")]\n    [InlineData(\"1.2.3.4\", \"1.2.3.4\")]\n    [InlineData(\"1729-foo\", \"1729-foo\")]\n    [InlineData(\"0.13.9+228a464e8be6c580ad9408e98f18813f6407fb5a\", \"0.13.9\")]\n    [InlineData(\"1-2+3\", \"1-2\")]\n    public void RemoveVersionMetadata(string input, string expectedOutput)\n    {\n        string? actualOutput = BenchmarkDotNetInfo.RemoveVersionMetadata(input);\n        Assert.Equal(expectedOutput, actualOutput);\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/ReflectionTests.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Tests.XUnit;\nusing JetBrains.Annotations;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests\n{\n    public class ReflectionTests\n    {\n        [Fact]\n        public void GetCorrectCSharpTypeNameReturnsCSharpFriendlyTypeName()\n        {\n            CheckCorrectTypeName(\"global::System.Int32\", typeof(int));\n            CheckCorrectTypeName(\"global::System.Int32[]\", typeof(int[]));\n            CheckCorrectTypeName(\"global::System.Int32[][]\", typeof(int[][]));\n            CheckCorrectTypeName(\"global::System.Int32[,]\", typeof(int[,]));\n            CheckCorrectTypeName(\"global::System.Tuple<global::System.Int16, global::System.Int32>[]\", typeof(Tuple<short, int>[]));\n            CheckCorrectTypeName(\"global::System.ValueTuple<global::System.Int16, global::System.Int32>[]\", typeof(ValueTuple<short, int>[]));\n            CheckCorrectTypeName(\"void\", typeof(void));\n            CheckCorrectTypeName(\"void*\", typeof(void*));\n            CheckCorrectTypeName(\"global::System.IEquatable<T>\", typeof(IEquatable<>));\n            CheckCorrectTypeName(\"global::System.Type\", typeof(Type));\n            // ReSharper disable once PossibleMistakenCallToGetType.2\n            CheckCorrectTypeName(\"global::System.Reflection.TypeInfo\", typeof(string).GetType()); // typeof(string).GetType() == System.RuntimeType which is not public\n        }\n\n        [Fact]\n        public void GetCorrectCSharpTypeNameSupportsGenericTypesPassedByReference()\n        {\n            var byRefGenericType = typeof(GenericByRef).GetMethod(nameof(GenericByRef.TheMethod))!.GetParameters().Single().ParameterType;\n\n            CheckCorrectTypeName(\"global::System.ValueTuple<global::System.Int32, global::System.Int16>\", byRefGenericType);\n        }\n\n        public class GenericByRef\n        {\n            public void TheMethod(ref (int, short) _) { }\n        }\n\n        [Fact]\n        public void GetCorrectCSharpTypeNameSupportsNestedTypes()\n        {\n            CheckCorrectTypeName(\"global::BenchmarkDotNet.Tests.ReflectionTests.Nested\", typeof(Nested));\n\n            CheckCorrectTypeName(\"global::BenchmarkDotNet.Tests.ReflectionTests.NestedNonGeneric1.NestedNonGeneric2\",\n                typeof(NestedNonGeneric1.NestedNonGeneric2));\n            CheckCorrectTypeName(\"global::BenchmarkDotNet.Tests.ReflectionTests.NestedNonGeneric1.NestedGeneric2<global::System.Int16, global::System.Boolean, global::System.Decimal>\",\n                typeof(NestedNonGeneric1.NestedGeneric2<short, bool, decimal>));\n\n            CheckCorrectTypeName(\"global::BenchmarkDotNet.Tests.ReflectionTests.NestedNonGeneric1.NestedGeneric2<global::System.Int16, global::System.Boolean, global::System.Decimal>.NestedNonGeneric3\",\n                typeof(NestedNonGeneric1.NestedGeneric2<short, bool, decimal>.NestedNonGeneric3));\n\n            CheckCorrectTypeName(\"global::BenchmarkDotNet.Tests.ReflectionTests.NestedGeneric1<global::System.Byte, global::System.SByte>\",\n                typeof(NestedGeneric1<byte, sbyte>));\n            CheckCorrectTypeName(\"global::BenchmarkDotNet.Tests.ReflectionTests.NestedGeneric1<global::System.Byte, global::System.SByte>.NonGeneric2\",\n                typeof(NestedGeneric1<byte, sbyte>.NonGeneric2));\n            CheckCorrectTypeName(\"global::BenchmarkDotNet.Tests.ReflectionTests.NestedGeneric1<global::System.Byte, global::System.SByte>.NonGeneric2.Generic3<global::System.Int16, global::System.Int32, global::System.Int64>\",\n                typeof(NestedGeneric1<byte, sbyte>.NonGeneric2.Generic3<short, int, long>));\n            CheckCorrectTypeName(\"global::BenchmarkDotNet.Tests.ReflectionTests.NestedGeneric1<global::System.Byte, global::System.SByte>.NonGeneric2.Generic3<global::System.Int16, global::System.Int32, global::System.Int64>.NonGeneric4\",\n                typeof(NestedGeneric1<byte, sbyte>.NonGeneric2.Generic3<short, int, long>.NonGeneric4));\n            CheckCorrectTypeName(\"global::BenchmarkDotNet.Tests.ReflectionTests.NestedGeneric1<global::System.Byte, global::System.SByte>.NonGeneric2.Generic3<global::System.Int16, global::System.Int32, global::System.Int64>.Generic4<global::System.Single, global::System.Double>\",\n                typeof(NestedGeneric1<byte, sbyte>.NonGeneric2.Generic3<short, int, long>.Generic4<float, double>));\n\n            CheckCorrectTypeName(\"global::BenchmarkDotNet.Tests.ReflectionTests.NestedGeneric1<T1, T2>\",\n                typeof(NestedGeneric1<,>));\n            CheckCorrectTypeName(\"global::BenchmarkDotNet.Tests.ReflectionTests.NestedGeneric1<T1, T2>.NonGeneric2.Generic3<V1, V2, V3>.NonGeneric4\",\n                typeof(NestedGeneric1<,>.NonGeneric2.Generic3<,,>.NonGeneric4));\n            CheckCorrectTypeName(\"global::BenchmarkDotNet.Tests.ReflectionTests.NestedGeneric1<T1, T2>.NonGeneric2.Generic3<V1, V2, V3>.Generic4<W1, W2>\",\n                typeof(NestedGeneric1<,>.NonGeneric2.Generic3<,,>.Generic4<,>));\n        }\n\n        [Fact]\n        public void GetCorrectCSharpTypeNameSupportsNestedTypesPassedByReference()\n        {\n            var byRefNestedType = typeof(Nested).GetMethod(nameof(Nested.TheMethod))!.GetParameters().Single().ParameterType;\n\n            CheckCorrectTypeName(\"global::BenchmarkDotNet.Tests.ReflectionTests.Nested\", byRefNestedType);\n        }\n\n        public class Nested\n        {\n            public void TheMethod(ref Nested _) { }\n        }\n\n        public class NestedNonGeneric1\n        {\n            public class NestedNonGeneric2 { }\n\n            public class NestedGeneric2<TA, TB, TC>\n            {\n                public class NestedNonGeneric3 { }\n            }\n        }\n\n        public class NestedGeneric1<T1, T2>\n        {\n            public class NonGeneric2\n            {\n                public class Generic3<V1, V2, V3>\n                {\n                    public class NonGeneric4 { }\n\n                    public class Generic4<W1, W2> { }\n                }\n            }\n        }\n\n        [AssertionMethod]\n        private static void CheckCorrectTypeName(string expectedName, Type type)\n        {\n            Assert.Equal(expectedName, type.GetCorrectCSharpTypeName());\n        }\n\n        [Fact]\n        public void GetDisplayNameReturnsTypeNameWithGenericArguments()\n        {\n            CheckCorrectDisplayName(\"Int32\", typeof(int));\n            CheckCorrectDisplayName(\"List<Int32>\", typeof(List<int>));\n            CheckCorrectDisplayName(\"List<ReflectionTests>\", typeof(List<ReflectionTests>));\n        }\n\n        [AssertionMethod]\n        private static void CheckCorrectDisplayName(string expectedName, Type type)\n        {\n            Assert.Equal(expectedName, type.GetDisplayName());\n        }\n\n        [Fact]\n        public void OnlyClosedGenericsWithPublicParameterlessCtorsAreSupported()\n        {\n            Assert.False(typeof(Generic<>).ContainsRunnableBenchmarks());\n            Assert.False(typeof(GenericNoPublicCtor<>).ContainsRunnableBenchmarks());\n            Assert.False(typeof(GenericNoPublicCtor<int>).ContainsRunnableBenchmarks());\n\n            Assert.True(typeof(Generic<int>).ContainsRunnableBenchmarks());\n        }\n\n        public class Generic<T>\n        {\n            [Benchmark] public T Create() => default!;\n        }\n\n        public class GenericNoPublicCtor<T>\n        {\n            private GenericNoPublicCtor() { }\n\n            [Benchmark] public T Create() => default!;\n        }\n\n        [FactEnvSpecific(\"The implicit cast operator is available only in .NET Core 2.1+ (See https://github.com/dotnet/corefx/issues/30121 for more)\",\n            EnvRequirement.DotNetCoreOnly)]\n        public void StringCanBeUsedAsReadOnlySpanOfCharArgument() => Assert.True(typeof(ReadOnlySpan<char>).IsStackOnlyWithImplicitCast(\"a string\"));\n\n        [Fact]\n        public void StackOnlyTypesWithImplicitCastOperatorAreSupportedAsArguments()\n        {\n            Assert.True(typeof(Span<byte>).IsStackOnlyWithImplicitCast(new byte[] { 1, 2, 3 }));\n            Assert.True(typeof(StackOnlyStruct<byte>).IsStackOnlyWithImplicitCast(new WithImplicitCastToStackOnlyStruct<byte>() { Array = [] }));\n\n            Assert.False(typeof(StackOnlyStruct<byte>).IsStackOnlyWithImplicitCast(new WithImplicitCastToStackOnlyStruct<bool>() { Array = [] })); // different T\n\n            Assert.False(typeof(List<byte>).IsStackOnlyWithImplicitCast(new byte[] { 1, 3, 3 }));\n        }\n\n        public ref struct StackOnlyStruct<T>\n        {\n            public Span<T> Span;\n        }\n\n        public class WithImplicitCastToStackOnlyStruct<T>\n        {\n            public required T[] Array;\n\n            public static implicit operator StackOnlyStruct<T>(WithImplicitCastToStackOnlyStruct<T> instance)\n                => new StackOnlyStruct<T> { Span = instance.Array };\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Reports/ColumnTests.cs",
    "content": "﻿using System.Linq;\nusing BenchmarkDotNet.Columns;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Exporters;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Tests.Mocks;\nusing Xunit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.Tests.Reports\n{\n    public class ColumnTests\n    {\n        private readonly ITestOutputHelper output;\n\n        public ColumnTests(ITestOutputHelper output)\n        {\n            this.output = output;\n        }\n\n        [Fact]\n        public void UniqueIdTest()\n        {\n            var config = ManualConfig.Create(DefaultConfig.Instance)\n                .AddColumn(StatisticColumn.Mean)\n                .AddColumn(StatisticColumn.Mean)\n                .AddColumn(StatisticColumn.StdDev)\n                .AddColumn(StatisticColumn.Mean)\n                .AddColumn(StatisticColumn.Mean)\n                .AddColumn(StatisticColumn.P67);\n\n            var summary = CreateSummary(config);\n            var columns = summary.GetColumns();\n            Assert.Equal(1, columns.Count(c => c.Id == StatisticColumn.Mean.Id));\n            Assert.Equal(1, columns.Count(c => c.Id == StatisticColumn.StdDev.Id));\n            Assert.Equal(1, columns.Count(c => c.Id == StatisticColumn.P67.Id));\n        }\n\n        private Summary CreateSummary(IConfig config)\n        {\n            var logger = new AccumulationLogger();\n            var summary = MockFactory.CreateSummary(config);\n            MarkdownExporter.Default.ExportToLog(summary, logger);\n            output.WriteLine(logger.GetLog());\n            return summary;\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Reports/DefaultColumnProvidersTests.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Columns;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Exporters;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Tests.Mocks;\nusing Xunit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.Tests.Reports\n{\n    public class DefaultColumnProvidersTests\n    {\n        private readonly ITestOutputHelper output;\n\n        public DefaultColumnProvidersTests(ITestOutputHelper output)\n        {\n            this.output = output;\n        }\n\n        [Theory]\n        [InlineData(false, \"Mean, Error, Ratio\")]\n        [InlineData(true, \"Mean, Error, Median, StdDev, Ratio, RatioSD\")]\n        public void DefaultStatisticsColumnsTest(bool hugeSd, string expectedColumnNames)\n        {\n            var summary = CreateSummary(hugeSd, []);\n            var columns = DefaultColumnProviders.Statistics.GetColumns(summary).ToList();\n            string columnNames = string.Join(\", \", columns.Select(c => c.ColumnName));\n            output.WriteLine(\"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\");\n            output.WriteLine(\"DefaultStatisticsColumns: \" + columnNames);\n            Assert.Equal(expectedColumnNames, columnNames);\n        }\n\n        [Fact]\n        public void EveyMetricHasItsOwnColumn()\n        {\n            var metrics = new[] { new Metric(new FakeMetricDescriptor(\"metric1\", \"some legend\"), 0.1), new Metric(new FakeMetricDescriptor(\"metric2\", \"another legend\"), 0.1) };\n            var summary = CreateSummary(false, metrics);\n\n            var columns = DefaultColumnProviders.Metrics.GetColumns(summary).ToArray();\n\n            Assert.Equal(\"metric1\", columns[0].Id);\n            Assert.Equal(\"metric2\", columns[1].Id);\n        }\n\n        // TODO: Union this with MockFactory\n        private Summary CreateSummary(bool hugeSd, Metric[] metrics)\n        {\n            var logger = new AccumulationLogger();\n            var summary = MockFactory.CreateSummary<MockBenchmarkClass>(DefaultConfig.Instance, hugeSd, metrics);\n            MarkdownExporter.Default.ExportToLog(summary, logger);\n            output.WriteLine(logger.GetLog());\n            return summary;\n        }\n\n        [LongRunJob]\n        public class MockBenchmarkClass\n        {\n            [Benchmark(Baseline = true)]\n            public void Foo() { }\n\n            [Benchmark]\n            public void Bar() { }\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Reports/DisplayPrecisionManagerTests.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing BenchmarkDotNet.Reports;\nusing JetBrains.Annotations;\nusing Xunit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.Tests.Reports\n{\n    public class DisplayPrecisionManagerTests\n    {\n        private readonly ITestOutputHelper output;\n\n        public DisplayPrecisionManagerTests(ITestOutputHelper output) => this.output = output;\n\n        private class TestData\n        {\n            public double[] Values { get; }\n\n            public List<(int? ParentPrecision, int ExpectedPrecision)> Configurations { get; }\n\n            public TestData(double[] values, int ppNull, int pp1, int pp2, int pp3, int pp4)\n            {\n                Values = values;\n                Configurations =\n                [\n                    (null, ppNull),\n                    (1, pp1),\n                    (2, pp2),\n                    (3, pp3),\n                    (4, pp4)\n                ];\n            }\n        }\n\n        private static readonly Dictionary<string, TestData> TestDataItems = new Dictionary<string, TestData>\n        {\n            { \"Min=1000     \", new TestData([1000.0], 1, 1, 2, 3, 4) },\n            { \"Min= 100     \", new TestData([0100.0], 1, 1, 2, 3, 4) },\n            { \"Min=  10     \", new TestData([010.00], 2, 2, 2, 3, 4) },\n            { \"Min=   1     \", new TestData([01.000], 3, 2, 3, 3, 4) },\n            { \"Min=   0.1   \", new TestData([0.1000], 4, 2, 3, 4, 4) },\n            { \"Min=   0.01  \", new TestData([0.0100], 4, 2, 3, 4, 4) },\n            { \"Min=   0.001 \", new TestData([0.0010], 4, 2, 3, 4, 4) },\n            { \"Min=   0.0001\", new TestData([0.0001], 4, 2, 3, 4, 4) },\n            { \"Min=   0.0000\", new TestData([0.0000], 1, 1, 2, 3, 4) },\n            { \"Empty\", new TestData([], 1, 1, 2, 3, 4) },\n            { \"NaN\", new TestData([double.NaN], 1, 1, 2, 3, 4) },\n            { \"Infinity\", new TestData([double.PositiveInfinity], 1, 1, 2, 3, 4) }\n        };\n\n        [UsedImplicitly]\n        public static TheoryData<string> TestDataNames => TheoryDataHelper.Create(TestDataItems.Keys);\n\n        [Theory]\n        [MemberData(nameof(TestDataNames))]\n        public void GeneralTest(string testDataName)\n        {\n            var testData = TestDataItems[testDataName];\n\n            output.WriteLine(\"Values: [\" + string.Join(\";\", testData.Values.Select(v => v.ToString(\"0.##\", TestCultureInfo.Instance))) + \"]\");\n\n            foreach (var configuration in testData.Configurations)\n            {\n                (var parentPrecision, int expectedPrecision) = configuration;\n\n                int actualPrecision = parentPrecision.HasValue\n                    ? DisplayPrecisionManager.CalcPrecision(testData.Values, parentPrecision.Value)\n                    : DisplayPrecisionManager.CalcPrecision(testData.Values);\n\n                string strParent = parentPrecision.HasValue ? 1234.5678.ToString(\"N\" + parentPrecision, TestCultureInfo.Instance) : \"NA\";\n                var strValues = testData.Values.Select(v => v.ToString(\"N\" + actualPrecision, TestCultureInfo.Instance)).ToList();\n                int maxWidth = strValues.Any() ? Math.Max(strValues.Max(s => s.Length), strParent.Length) + 6 : 0;\n                int parentWidth = maxWidth - (actualPrecision - parentPrecision) ?? 0;\n\n                output.WriteLine(\"******************************\");\n                output.WriteLine(\"Parent   Precision: \" + (parentPrecision.HasValue ? parentPrecision.Value.ToString() : \"<NA>\"));\n                output.WriteLine(\"Actual   Precision: \" + actualPrecision);\n                output.WriteLine(\"Expected Precision: \" + expectedPrecision);\n                output.WriteLine(\"Parent Value:\");\n                output.WriteLine(strParent.PadLeft(parentWidth));\n                output.WriteLine(\"Actual Formatted Values:\");\n                foreach (string strValue in strValues)\n                    output.WriteLine(strValue.PadLeft(maxWidth));\n                output.WriteLine(expectedPrecision == actualPrecision ? \"CORRECT\" : \"ERROR\");\n\n                Assert.Equal(expectedPrecision, actualPrecision);\n            }\n        }\n\n        [Theory]\n        [InlineData(4, 0.01)]\n        [InlineData(4, 0.123456)]\n        [InlineData(4, 0.1)]\n        [InlineData(1, 0.0)]\n        [InlineData(4, 0.9)]\n        [InlineData(3, 1)]\n        [InlineData(3, 1.5)]\n        [InlineData(3, 9.999999999)]\n        [InlineData(2, 10)]\n        [InlineData(2, 99.99999999)]\n        [InlineData(1, 100)]\n        [InlineData(1, 999.9999999)]\n        [InlineData(1, 10000)]\n        [InlineData(1, 100000)]\n        [InlineData(1, -100000)]\n        [InlineData(1, double.NaN)]\n        [InlineData(1, double.PositiveInfinity)]\n        public void ClassicTest(int expected, double value)\n        {\n            int actual = DisplayPrecisionManager.CalcPrecision([value]);\n            Assert.Equal(expected, actual);\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Reports/FakeMetricDescriptor.cs",
    "content": "﻿using BenchmarkDotNet.Columns;\nusing BenchmarkDotNet.Reports;\n\nnamespace BenchmarkDotNet.Tests.Reports\n{\n    internal sealed class FakeMetricDescriptor : IMetricDescriptor\n    {\n        public FakeMetricDescriptor(string id, string legend, string? numberFormat = null)\n        {\n            Id = id;\n            Legend = legend;\n            NumberFormat = numberFormat ?? \"\";\n        }\n\n        public string Id { get; }\n        public string DisplayName => Id;\n        public string Legend { get; }\n        public string NumberFormat { get; }\n        public UnitType UnitType { get; }\n        public string Unit { get; } = \"\";\n        public bool TheGreaterTheBetter { get; }\n        public int PriorityInCategory => 0;\n        public bool GetIsAvailable(Metric metric) => true;\n    }\n}\n"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Reports/RatioPrecisionTests.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Collections.Immutable;\nusing System.Linq;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Columns;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Exporters;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Tests.Builders;\nusing BenchmarkDotNet.Toolchains;\nusing BenchmarkDotNet.Toolchains.Results;\nusing BenchmarkDotNet.Validators;\nusing Xunit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.Tests.Reports\n{\n    public class RatioPrecisionTests\n    {\n        private readonly ITestOutputHelper output;\n\n        public RatioPrecisionTests(ITestOutputHelper output)\n        {\n            this.output = output;\n        }\n\n        [Theory]\n        [InlineData(new[] { 140, 1, 50 })]\n        [InlineData(new[] { 40, 1, 20 })]\n        [InlineData(new[] { 0, 1, 20 })]\n        // First value is baseline, others are benchmark measurements\n        public void RatioPrecisionTestWithBaseline(int[] values)\n        {\n            var summary = CreateSummary(values);\n            int ratioIndex = Array.FindIndex(summary.Table.FullHeader, c => c == BaselineRatioColumn.RatioMean.ColumnName);\n\n            foreach (var row in summary.Table.FullContent)\n            {\n                ContainsDecimalPointAndCheckDecimalPrecision(values, row[ratioIndex]);\n            }\n        }\n\n        private void ContainsDecimalPointAndCheckDecimalPrecision(int[] baseLineValues, string value)\n        {\n            if (value.Contains('.'))\n            {\n                Assert.Equal((1 / (double)baseLineValues[0]) < 0.01 ? 3 : 2, value.Split('.')[1].Length);\n            }\n        }\n\n        // TODO: Union this with MockFactory\n        private Summary CreateSummary(int[] values)\n        {\n            var logger = new AccumulationLogger();\n            var benchmarks = CreateBenchmarks(DefaultConfig.Instance).ToList();\n            var benchmarkReports = new List<BenchmarkReport>();\n            for (var x = 0; x < benchmarks.Count; x++)\n            {\n                var benchmark = benchmarks[x];\n                benchmarkReports.Add(CreateReport(benchmark, values[x]));\n            }\n\n            var summary = new Summary(\n                \"MockSummary\",\n                benchmarkReports.ToImmutableArray(),\n                new HostEnvironmentInfoBuilder().Build(),\n                string.Empty,\n                string.Empty,\n                TimeSpan.FromMinutes(1),\n                TestCultureInfo.Instance,\n                [],\n                []);\n            MarkdownExporter.Default.ExportToLog(summary, logger);\n            output.WriteLine(logger.GetLog());\n            return summary;\n        }\n\n        private static BenchmarkReport CreateReport(BenchmarkCase benchmarkCase, int measurementValue)\n        {\n            var buildResult = BuildResult.Success(GenerateResult.Success(ArtifactsPaths.Empty, []));\n            var measurements = new List<Measurement>\n                {\n                    new Measurement(1, IterationMode.Workload, IterationStage.Result, 1, 1, measurementValue),\n                    new Measurement(1, IterationMode.Workload, IterationStage.Result, 2, 1, measurementValue),\n                    new Measurement(1, IterationMode.Workload, IterationStage.Result, 3, 1, measurementValue),\n                    new Measurement(1, IterationMode.Workload, IterationStage.Result, 4, 1, measurementValue),\n                    new Measurement(1, IterationMode.Workload, IterationStage.Result, 5, 1, measurementValue),\n                    new Measurement(1, IterationMode.Workload, IterationStage.Result, 6, 1, measurementValue),\n                };\n            var executeResult = new ExecuteResult(measurements, default);\n            return new BenchmarkReport(true, benchmarkCase, buildResult, buildResult, [executeResult], []);\n        }\n\n        private static IEnumerable<BenchmarkCase> CreateBenchmarks(IConfig config) =>\n            BenchmarkConverter.TypeToBenchmarks(typeof(MockBenchmarkClass), config).BenchmarksCases;\n\n        [LongRunJob]\n        public class MockBenchmarkClass\n        {\n            [Benchmark(Baseline = true)]\n            public void Baseline() { }\n\n            [Benchmark]\n            public void Bar() { }\n\n            [Benchmark]\n            public void Foo() { }\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Reports/RatioStyleTests.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Collections.Immutable;\nusing System.Linq;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Columns;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Exporters;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Tests.Builders;\nusing BenchmarkDotNet.Toolchains;\nusing BenchmarkDotNet.Toolchains.Results;\nusing BenchmarkDotNet.Validators;\nusing JetBrains.Annotations;\nusing Xunit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.Tests.Reports\n{\n    public class RatioStyleTests\n    {\n        private readonly ITestOutputHelper output;\n\n        public RatioStyleTests(ITestOutputHelper output)\n        {\n            this.output = output;\n        }\n\n        private class TestData\n        {\n            public RatioStyle RatioStyle { get; }\n            public int[] MeanValues { get; }\n            public int Noise { get; }\n            public string[] ExpectedRatioValues { get; }\n\n            public TestData(RatioStyle ratioStyle, int[] meanValues, int noise, string[] expectedRatioValues)\n            {\n                RatioStyle = ratioStyle;\n                MeanValues = meanValues;\n                ExpectedRatioValues = expectedRatioValues;\n                Noise = noise;\n            }\n        }\n\n        private static readonly IDictionary<string, TestData> Data = new Dictionary<string, TestData>\n        {\n            { \"Percentage\", new TestData(RatioStyle.Percentage, [100, 15, 115], 1, [\"baseline\", \"-85%\", \"+15%\"]) },\n            { \"Trend\", new TestData(RatioStyle.Trend, [100, 15, 115], 1, [\"baseline\", \"6.84x faster\", \"1.15x slower\"]) }\n        };\n\n        [UsedImplicitly]\n        public static TheoryData<string> DataNames = TheoryDataHelper.Create(Data.Keys);\n\n        [Theory]\n        [MemberData(nameof(DataNames))]\n        // First value is baseline, others are benchmark measurements\n        public void RatioPrecisionTestWithBaseline(string testDataKey)\n        {\n            var testData = Data[testDataKey];\n            var summary = CreateSummary(testData.MeanValues, testData.RatioStyle, testData.Noise);\n            int ratioIndex = Array.FindIndex(summary.Table.FullHeader, c => c == BaselineRatioColumn.RatioMean.ColumnName);\n\n            for (int rowIndex = 0; rowIndex < summary.Table.FullContent.Length; rowIndex++)\n            {\n                var row = summary.Table.FullContent[rowIndex];\n                string actual = row[ratioIndex];\n                string expected = testData.ExpectedRatioValues[rowIndex];\n                Assert.Equal(expected, actual);\n            }\n        }\n\n        // TODO: Union this with MockFactory\n        private Summary CreateSummary(int[] values, RatioStyle ratioStyle, int noise)\n        {\n            var logger = new AccumulationLogger();\n            var config = DefaultConfig.Instance.WithSummaryStyle(SummaryStyle.Default.WithRatioStyle(ratioStyle: ratioStyle));\n            var benchmarks = CreateBenchmarks(config).ToList();\n            var benchmarkReports = new List<BenchmarkReport>();\n            for (var x = 0; x < benchmarks.Count; x++)\n            {\n                var benchmark = benchmarks[x];\n                benchmarkReports.Add(CreateReport(benchmark, values[x], noise));\n            }\n\n            var summary = new Summary(\n                \"MockSummary\",\n                benchmarkReports.ToImmutableArray(),\n                new HostEnvironmentInfoBuilder().Build(),\n                string.Empty,\n                string.Empty,\n                TimeSpan.FromMinutes(1),\n                TestCultureInfo.Instance,\n                [],\n                []);\n            MarkdownExporter.Default.ExportToLog(summary, logger);\n            output.WriteLine(logger.GetLog());\n            return summary;\n        }\n\n        private static BenchmarkReport CreateReport(BenchmarkCase benchmarkCase, int measurementValue, int noise)\n        {\n            var buildResult = BuildResult.Success(GenerateResult.Success(ArtifactsPaths.Empty, []));\n            var measurements = new List<Measurement>\n            {\n                new Measurement(1, IterationMode.Workload, IterationStage.Result, 1, 1, measurementValue),\n                new Measurement(1, IterationMode.Workload, IterationStage.Result, 2, 1, measurementValue + noise),\n                new Measurement(1, IterationMode.Workload, IterationStage.Result, 3, 1, measurementValue - noise),\n                new Measurement(1, IterationMode.Workload, IterationStage.Result, 4, 1, measurementValue + 2 * noise),\n                new Measurement(1, IterationMode.Workload, IterationStage.Result, 5, 1, measurementValue - 3 * noise)\n            };\n            var executeResult = new ExecuteResult(measurements, default);\n            return new BenchmarkReport(true, benchmarkCase, buildResult, buildResult, [executeResult], []);\n        }\n\n        private static IEnumerable<BenchmarkCase> CreateBenchmarks(IConfig config) =>\n            BenchmarkConverter.TypeToBenchmarks(typeof(MockBenchmarkClass), config).BenchmarksCases;\n\n        [LongRunJob]\n        public class MockBenchmarkClass\n        {\n            [Benchmark(Baseline = true)]\n            public void Baseline() { }\n\n            [Benchmark]\n            public void Bar() { }\n\n            [Benchmark]\n            public void Foo() { }\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Reports/SummaryTableTests.cs",
    "content": "﻿using System.Linq;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Columns;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Diagnosers;\nusing BenchmarkDotNet.Exporters;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Order;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Tests.Mocks;\nusing Xunit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.Tests.Reports\n{\n    public class SummaryTableTests\n    {\n        private readonly ITestOutputHelper output;\n\n        public SummaryTableTests(ITestOutputHelper output)\n        {\n            this.output = output;\n        }\n\n        private SummaryTable CreateTable()\n        {\n            var logger = new AccumulationLogger();\n            var config = DefaultConfig.Instance;\n            var summary = MockFactory.CreateSummary(config);\n            var table = new SummaryTable(summary);\n            MarkdownExporter.Default.ExportToLog(summary, logger);\n            output.WriteLine(logger.GetLog());\n            return table;\n        }\n\n        private SummaryTable.SummaryTableColumn CreateColumn(string header)\n        {\n            var column = CreateTable().Columns.FirstOrDefault(c => c.Header == header);\n            Assert.NotNull(column);\n            return column;\n        }\n\n        [Fact]\n        public void PlatformTest()\n        {\n            var gcModeColumn = CreateColumn(\"Platform\");\n            Assert.True(gcModeColumn.IsDefault);\n        }\n\n        [Fact]\n        public void NumericColumnIsRightJustified()\n        {\n            var config = ManualConfig.Create(DefaultConfig.Instance).AddColumn(StatisticColumn.Mean);\n            var summary = MockFactory.CreateSummary(config);\n            var table = new SummaryTable(summary);\n\n            Assert.Equal(SummaryTable.SummaryTableColumn.TextJustification.Right, table.Columns.First(c => c.Header == \"Mean\").Justify);\n        }\n\n        [Fact]\n        public void TextColumnIsLeftJustified()\n        {\n            var config = ManualConfig.Create(DefaultConfig.Instance).AddColumn(new ParamColumn(\"Param\"));\n            var summary = MockFactory.CreateSummary(config);\n            var table = new SummaryTable(summary);\n\n            Assert.Equal(SummaryTable.SummaryTableColumn.TextJustification.Left, table.Columns.First(c => c.Header == \"Param\").Justify);\n        }\n\n        [Fact]\n        public void NumericColumnWithLeftJustification()\n        {\n            var config = ManualConfig.Create(DefaultConfig.Instance).AddColumn(StatisticColumn.Mean);\n            config.SummaryStyle = MockFactory.CreateSummaryStyle(numericColumnJustification: SummaryTable.SummaryTableColumn.TextJustification.Left);\n            var summary = MockFactory.CreateSummary(config);\n            var table = new SummaryTable(summary);\n\n            Assert.Equal(SummaryTable.SummaryTableColumn.TextJustification.Left, table.Columns.First(c => c.Header == \"Mean\").Justify);\n        }\n\n        [Fact]\n        public void TextColumnWithRightJustification()\n        {\n            var config = ManualConfig.Create(DefaultConfig.Instance).AddColumn(new ParamColumn(\"Param\"));\n            config.SummaryStyle = MockFactory.CreateSummaryStyle(textColumnJustification: SummaryTable.SummaryTableColumn.TextJustification.Right);\n            var summary = MockFactory.CreateSummary(config);\n            var table = new SummaryTable(summary);\n\n            Assert.Equal(SummaryTable.SummaryTableColumn.TextJustification.Right, table.Columns.First(c => c.Header == \"Param\").Justify);\n        }\n\n        [Fact] // Issue #1070\n        public void CustomOrdererIsSupported()\n        {\n            var config = ManualConfig.Create(DefaultConfig.Instance)\n                .WithOrderer(new DefaultOrderer(SummaryOrderPolicy.FastestToSlowest, MethodOrderPolicy.Alphabetical));\n            var summary = MockFactory.CreateSummary(config);\n            Assert.True(summary.Orderer is DefaultOrderer defaultOrderer &&\n                        defaultOrderer.SummaryOrderPolicy == SummaryOrderPolicy.FastestToSlowest &&\n                        defaultOrderer.MethodOrderPolicy == MethodOrderPolicy.Alphabetical);\n        }\n\n        [Fact] // Issue #1168\n        public void ZeroValueInMetricColumnIsDashedByDefault()\n        {\n            // arrange\n            var config = ManualConfig.Create(DefaultConfig.Instance);\n            var metrics = new[] { new Metric(new FakeMetricDescriptor(\"metric1\", \"some legend\", \"0.0\"), 0.0) };\n\n            // act\n            var summary = MockFactory.CreateSummary(config, hugeSd: false, metrics);\n            var table = new SummaryTable(summary);\n            var actual = table.Columns.First(c => c.Header == \"metric1\").Content;\n\n            // assert\n            Assert.True(actual.All(value => \"-\" == value));\n        }\n\n        [Fact] // Issue #1168\n        public void ZeroValueInMetricColumnIsNotDashedWithCustomStyle()\n        {\n            // arrange\n            var config = ManualConfig.Create(DefaultConfig.Instance);\n            var metrics = new[] { new Metric(new FakeMetricDescriptor(\"metric1\", \"some legend\", \"0.0\"), 0.0) };\n            var style = config.SummaryStyle!.WithZeroMetricValuesInContent();\n\n            // act\n            var summary = MockFactory.CreateSummary(config, hugeSd: false, metrics);\n            var table = new SummaryTable(summary, style);\n            var actual = table.Columns.First(c => c.Header == \"metric1\").Content;\n\n            // assert\n            Assert.True(actual.All(value => \"0.0\" == value));\n        }\n\n        [Fact] // Issue #1783\n        public void NaNValueInMetricColumnIsQuestionMark()\n        {\n            // arrange\n            var config = ManualConfig.Create(DefaultConfig.Instance);\n            var metrics = new[] { new Metric(new FakeMetricDescriptor(\"metric1\", \"some legend\", \"0.0\"), double.NaN) };\n            var style = config.SummaryStyle!.WithZeroMetricValuesInContent();\n\n            // act\n            var summary = MockFactory.CreateSummary(config, hugeSd: false, metrics);\n            var table = new SummaryTable(summary, style);\n            var actual = table.Columns.First(c => c.Header == \"metric1\").Content;\n\n            // assert\n            Assert.True(actual.All(value => value == MetricColumn.UnknownRepresentation));\n        }\n\n        [Fact] // Issue #1783\n        public void MissingValueInMetricColumnIsNA()\n        {\n            // arrange\n            var config = ManualConfig.Create(DefaultConfig.Instance);\n            bool firstMetricsUsed = false;\n\n            // act\n            var summary = MockFactory.CreateSummary<MockFactory.MockBenchmarkClass>(config, hugeSd: false, benchmarkCase =>\n            {\n                if (!firstMetricsUsed)\n                {\n                    firstMetricsUsed = true;\n                    return [new Metric(new FakeMetricDescriptor(\"metric1\", \"some legend\", \"0.0\"), 0.0)];\n                }\n                return [];\n            });\n            var table = new SummaryTable(summary);\n            var actual = table.Columns.First(c => c.Header == \"metric1\").Content;\n\n            // assert\n            Assert.Equal([\"-\", \"NA\"], actual);\n        }\n\n        #region Issue #2673\n        [Fact]\n        public void DefaultExceptionDiagnoserConfig_WhenExceptionsIsNotZero()\n        {\n\n            // arrange\n            var config = ManualConfig.Create(DefaultConfig.Instance);\n            var exceptionConfig = new ExceptionDiagnoserConfig();\n\n            var exceptionsFrequencyMetricDescriptor = new ExceptionDiagnoser.ExceptionsFrequencyMetricDescriptor(exceptionConfig);\n\n            var metric = new Metric(exceptionsFrequencyMetricDescriptor, 5);\n            var metrics = new[] { metric };\n\n            // act\n            var summary = MockFactory.CreateSummary(config, hugeSd: false, metrics);\n            var table = new SummaryTable(summary);\n            var actual = table.Columns.First(c => c.Header == \"Exceptions\").Content;\n\n            // assert\n            Assert.Equal([\"5.0000\", \"5.0000\"], actual);\n        }\n\n        [Fact]\n        public void DefaultExceptionDiagnoserConfig_WhenExceptionsIsZero()\n        {\n\n\n            // arrange\n            var config = ManualConfig.Create(DefaultConfig.Instance);\n            var exceptionConfig = new ExceptionDiagnoserConfig();\n\n            var exceptionsFrequencyMetricDescriptor = new ExceptionDiagnoser.ExceptionsFrequencyMetricDescriptor(exceptionConfig);\n\n            var metric = new Metric(exceptionsFrequencyMetricDescriptor, 0);\n            var metrics = new[] { metric };\n\n            // act\n            var summary = MockFactory.CreateSummary(config, hugeSd: false, metrics);\n            var table = new SummaryTable(summary);\n            var actual = table.Columns.First(c => c.Header == \"Exceptions\").Content;\n\n            // assert\n            Assert.Equal([\"-\", \"-\"], actual);\n        }\n\n        [Fact]\n        public void HideExceptionDiagnoserConfig_WhenExceptionsIsNotZero()\n        {\n            // arrange\n            var config = ManualConfig.Create(DefaultConfig.Instance);\n            var exceptionConfig = new ExceptionDiagnoserConfig(displayExceptionsIfZeroValue: false);\n\n            var exceptionsFrequencyMetricDescriptor = new ExceptionDiagnoser.ExceptionsFrequencyMetricDescriptor(exceptionConfig);\n\n            var metric = new Metric(exceptionsFrequencyMetricDescriptor, 5);\n            var metrics = new[] { metric };\n\n            // act\n            var summary = MockFactory.CreateSummary(config, hugeSd: false, metrics);\n            var table = new SummaryTable(summary);\n            var actual = table.Columns.First(c => c.Header == \"Exceptions\").Content;\n\n            // assert\n            Assert.Equal([\"5.0000\", \"5.0000\"], actual);\n        }\n\n        [Fact]\n        public void HideExceptionDiagnoserConfig_WhenExceptionsIsZero()\n        {\n\n\n            // arrange\n            var config = ManualConfig.Create(DefaultConfig.Instance);\n            var exceptionConfig = new ExceptionDiagnoserConfig(displayExceptionsIfZeroValue: false);\n\n            var exceptionsFrequencyMetricDescriptor = new ExceptionDiagnoser.ExceptionsFrequencyMetricDescriptor(exceptionConfig);\n\n            var metric = new Metric(exceptionsFrequencyMetricDescriptor, 0);\n            var metrics = new[] { metric };\n\n            // act\n            var summary = MockFactory.CreateSummary(config, hugeSd: false, metrics);\n            var table = new SummaryTable(summary);\n            var isExist = table.Columns.Any(c => c.Header == \"Exceptions\");\n\n            // assert\n            Assert.False(isExist);\n        }\n\n        [Fact]\n        public void DefaultThreadingDiagnoserConfig_WhenDescriptorValuesAreNotZero()\n        {\n\n            // arrange\n            var config = ManualConfig.Create(DefaultConfig.Instance);\n            var threadingConfig = new ThreadingDiagnoserConfig();\n\n            var lockContentionCountMetricDescriptor = new ThreadingDiagnoser.LockContentionCountMetricDescriptor(threadingConfig);\n            var completedWorkItemCountMetricDescriptor = new ThreadingDiagnoser.CompletedWorkItemCountMetricDescriptor(threadingConfig);\n\n            var lockContentionCountMetric = new Metric(lockContentionCountMetricDescriptor, 5);\n            var completedWorkItemMetric = new Metric(completedWorkItemCountMetricDescriptor, 5);\n            var metrics = new[] { lockContentionCountMetric, completedWorkItemMetric };\n\n            // act\n            var summary = MockFactory.CreateSummary(config, hugeSd: false, metrics);\n            var table = new SummaryTable(summary);\n\n            var lockContentionCount = table.Columns.First(c => c.Header == \"Lock Contentions\").Content;\n            var completedWorkItemCount = table.Columns.First(c => c.Header == \"Completed Work Items\").Content;\n\n            // assert\n            Assert.Equal([\"5.0000\", \"5.0000\"], lockContentionCount);\n            Assert.Equal([\"5.0000\", \"5.0000\"], completedWorkItemCount);\n        }\n\n        [Fact]\n        public void DefaultThreadingDiagnoserConfig_WhenDescriptorValuesAreZero()\n        {\n\n            // arrange\n            var config = ManualConfig.Create(DefaultConfig.Instance);\n            var threadingConfig = new ThreadingDiagnoserConfig();\n\n            var lockContentionCountMetricDescriptor = new ThreadingDiagnoser.LockContentionCountMetricDescriptor(threadingConfig);\n            var completedWorkItemCountMetricDescriptor = new ThreadingDiagnoser.CompletedWorkItemCountMetricDescriptor(threadingConfig);\n\n            var lockContentionCountMetric = new Metric(lockContentionCountMetricDescriptor, 0);\n            var completedWorkItemMetric = new Metric(completedWorkItemCountMetricDescriptor, 0);\n            var metrics = new[] { lockContentionCountMetric, completedWorkItemMetric };\n\n            // act\n            var summary = MockFactory.CreateSummary(config, hugeSd: false, metrics);\n            var table = new SummaryTable(summary);\n\n            var lockContentionCount = table.Columns.First(c => c.Header == \"Lock Contentions\").Content;\n            var completedWorkItemCount = table.Columns.First(c => c.Header == \"Completed Work Items\").Content;\n\n            // assert\n            Assert.Equal([\"-\", \"-\"], lockContentionCount);\n            Assert.Equal([\"-\", \"-\"], completedWorkItemCount);\n        }\n\n        [Fact]\n        public void HideLockContentionCountThreadingDiagnoserConfig_WhenDescriptorValuesAreZero()\n        {\n\n            // arrange\n            var config = ManualConfig.Create(DefaultConfig.Instance);\n            var threadingConfig = new ThreadingDiagnoserConfig(displayLockContentionWhenZero: false);\n\n            var lockContentionCountMetricDescriptor = new ThreadingDiagnoser.LockContentionCountMetricDescriptor(threadingConfig);\n            var completedWorkItemCountMetricDescriptor = new ThreadingDiagnoser.CompletedWorkItemCountMetricDescriptor(threadingConfig);\n\n            var lockContentionCountMetric = new Metric(lockContentionCountMetricDescriptor, 0);\n            var completedWorkItemMetric = new Metric(completedWorkItemCountMetricDescriptor, 0);\n            var metrics = new[] { lockContentionCountMetric, completedWorkItemMetric };\n\n            // act\n            var summary = MockFactory.CreateSummary(config, hugeSd: false, metrics);\n            var table = new SummaryTable(summary);\n\n            string[]? lockContentionCount = table.Columns?.FirstOrDefault(c => c.Header == \"Lock Contentions\")?.Content ?? null;\n            string[]? completedWorkItemCount = table.Columns?.FirstOrDefault(c => c.Header == \"Completed Work Items\")?.Content ?? null;\n\n            // assert\n            Assert.Null(lockContentionCount);\n            Assert.Equal([\"-\", \"-\"], completedWorkItemCount!);\n        }\n\n        [Fact]\n        public void HideLockContentionCountThreadingDiagnoserConfig_WhenDescriptorValuesAreNotZero()\n        {\n\n            // arrange\n            var config = ManualConfig.Create(DefaultConfig.Instance);\n            var threadingConfig = new ThreadingDiagnoserConfig(displayLockContentionWhenZero: false);\n\n            var lockContentionCountMetricDescriptor = new ThreadingDiagnoser.LockContentionCountMetricDescriptor(threadingConfig);\n            var completedWorkItemCountMetricDescriptor = new ThreadingDiagnoser.CompletedWorkItemCountMetricDescriptor(threadingConfig);\n\n            var lockContentionCountMetric = new Metric(lockContentionCountMetricDescriptor, 5);\n            var completedWorkItemMetric = new Metric(completedWorkItemCountMetricDescriptor, 5);\n            var metrics = new[] { lockContentionCountMetric, completedWorkItemMetric };\n\n            // act\n            var summary = MockFactory.CreateSummary(config, hugeSd: false, metrics);\n            var table = new SummaryTable(summary);\n\n            string[]? lockContentionCount = table.Columns?.FirstOrDefault(c => c.Header == \"Lock Contentions\")?.Content ?? null;\n            string[]? completedWorkItemCount = table.Columns?.FirstOrDefault(c => c.Header == \"Completed Work Items\")?.Content ?? null;\n\n            // assert\n            Assert.Equal([\"5.0000\", \"5.0000\"], lockContentionCount!);\n            Assert.Equal([\"5.0000\", \"5.0000\"], completedWorkItemCount!);\n        }\n\n        [Fact]\n        public void HideCompletedWorkItemCountThreadingDiagnoserConfig_WhenDescriptorValuesAreZero()\n        {\n\n            // arrange\n            var config = ManualConfig.Create(DefaultConfig.Instance);\n            var threadingConfig = new ThreadingDiagnoserConfig(displayCompletedWorkItemCountWhenZero: false);\n\n            var lockContentionCountMetricDescriptor = new ThreadingDiagnoser.LockContentionCountMetricDescriptor(threadingConfig);\n            var completedWorkItemCountMetricDescriptor = new ThreadingDiagnoser.CompletedWorkItemCountMetricDescriptor(threadingConfig);\n\n            var lockContentionCountMetric = new Metric(lockContentionCountMetricDescriptor, 0);\n            var completedWorkItemMetric = new Metric(completedWorkItemCountMetricDescriptor, 0);\n            var metrics = new[] { lockContentionCountMetric, completedWorkItemMetric };\n\n            // act\n            var summary = MockFactory.CreateSummary(config, hugeSd: false, metrics);\n            var table = new SummaryTable(summary);\n\n            string[]? lockContentionCount = table.Columns?.FirstOrDefault(c => c.Header == \"Lock Contentions\")?.Content ?? null;\n            string[]? completedWorkItemCount = table.Columns?.FirstOrDefault(c => c.Header == \"Completed Work Items\")?.Content ?? null;\n\n            // assert\n            Assert.Null(completedWorkItemCount);\n            Assert.Equal([\"-\", \"-\"], lockContentionCount!);\n        }\n\n        [Fact]\n        public void HideCompletedWorkItemCountThreadingDiagnoserConfig_WhenDescriptorValuesAreNotZero()\n        {\n\n            // arrange\n            var config = ManualConfig.Create(DefaultConfig.Instance);\n            var threadingConfig = new ThreadingDiagnoserConfig(displayCompletedWorkItemCountWhenZero: false);\n\n            var lockContentionCountMetricDescriptor = new ThreadingDiagnoser.LockContentionCountMetricDescriptor(threadingConfig);\n            var completedWorkItemCountMetricDescriptor = new ThreadingDiagnoser.CompletedWorkItemCountMetricDescriptor(threadingConfig);\n\n            var lockContentionCountMetric = new Metric(lockContentionCountMetricDescriptor, 5);\n            var completedWorkItemMetric = new Metric(completedWorkItemCountMetricDescriptor, 5);\n            var metrics = new[] { lockContentionCountMetric, completedWorkItemMetric };\n\n            // act\n            var summary = MockFactory.CreateSummary(config, hugeSd: false, metrics);\n            var table = new SummaryTable(summary);\n\n            string[]? lockContentionCount = table.Columns?.FirstOrDefault(c => c.Header == \"Lock Contentions\")?.Content ?? null;\n            string[]? completedWorkItemCount = table.Columns?.FirstOrDefault(c => c.Header == \"Completed Work Items\")?.Content ?? null;\n\n            // assert\n            Assert.Equal([\"5.0000\", \"5.0000\"], lockContentionCount!);\n            Assert.Equal([\"5.0000\", \"5.0000\"], completedWorkItemCount!);\n        }\n\n        [Fact]\n        public void HideThreadingDiagnoserConfigs_WhenDescriptorValuesAreZero()\n        {\n\n            // arrange\n            var config = ManualConfig.Create(DefaultConfig.Instance);\n            var threadingConfig = new ThreadingDiagnoserConfig(displayCompletedWorkItemCountWhenZero: false, displayLockContentionWhenZero: false);\n\n            var lockContentionCountMetricDescriptor = new ThreadingDiagnoser.LockContentionCountMetricDescriptor(threadingConfig);\n            var completedWorkItemCountMetricDescriptor = new ThreadingDiagnoser.CompletedWorkItemCountMetricDescriptor(threadingConfig);\n\n            var lockContentionCountMetric = new Metric(lockContentionCountMetricDescriptor, 0);\n            var completedWorkItemMetric = new Metric(completedWorkItemCountMetricDescriptor, 0);\n            var metrics = new[] { lockContentionCountMetric, completedWorkItemMetric };\n\n            // act\n            var summary = MockFactory.CreateSummary(config, hugeSd: false, metrics);\n            var table = new SummaryTable(summary);\n\n            string[]? lockContentionCount = table.Columns?.FirstOrDefault(c => c.Header == \"Lock Contentions\")?.Content ?? null;\n            string[]? completedWorkItemCount = table.Columns?.FirstOrDefault(c => c.Header == \"Completed Work Items\")?.Content ?? null;\n\n            // assert\n            Assert.Null(lockContentionCount);\n            Assert.Null(completedWorkItemCount);\n        }\n\n        [Fact]\n        public void DisplayThreadingDiagnoserConfigs_WhenDescriptorValuesAreZero()\n        {\n\n            // arrange\n            var config = ManualConfig.Create(DefaultConfig.Instance);\n            var threadingConfig = new ThreadingDiagnoserConfig(displayCompletedWorkItemCountWhenZero: true, displayLockContentionWhenZero: true);\n            var lockContentionCountMetricDescriptor = new ThreadingDiagnoser.LockContentionCountMetricDescriptor(threadingConfig);\n            var completedWorkItemCountMetricDescriptor = new ThreadingDiagnoser.CompletedWorkItemCountMetricDescriptor(threadingConfig);\n\n            var lockContentionCountMetric = new Metric(lockContentionCountMetricDescriptor, 0);\n            var completedWorkItemMetric = new Metric(completedWorkItemCountMetricDescriptor, 0);\n            var metrics = new[] { lockContentionCountMetric, completedWorkItemMetric };\n\n            // act\n            var summary = MockFactory.CreateSummary(config, hugeSd: false, metrics);\n            var table = new SummaryTable(summary);\n\n            string[]? lockContentionCount = table.Columns?.FirstOrDefault(c => c.Header == \"Lock Contentions\")?.Content ?? null;\n            string[]? completedWorkItemCount = table.Columns?.FirstOrDefault(c => c.Header == \"Completed Work Items\")?.Content ?? null;\n\n            // assert\n            Assert.Equal([\"-\", \"-\"], lockContentionCount!);\n            Assert.Equal([\"-\", \"-\"], completedWorkItemCount!);\n        }\n        #endregion\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Reports/SummaryTests.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Collections.Immutable;\nusing System.Linq;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Columns;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Tests.Builders;\nusing BenchmarkDotNet.Toolchains;\nusing BenchmarkDotNet.Toolchains.Results;\nusing BenchmarkDotNet.Validators;\nusing Xunit;\nusing RunMode = BenchmarkDotNet.Jobs.RunMode;\n\nnamespace BenchmarkDotNet.Tests.Reports\n{\n    public class SummaryTests\n    {\n        /// <summary>\n        /// Ensures that passing null metrics to BenchmarkReport ctor does not result in NullReferenceException later in Summary ctor.\n        /// See also: <see href=\"https://github.com/dotnet/BenchmarkDotNet/issues/986\" />\n        /// </summary>\n        [Fact]\n        public void SummaryWithFailureReportDoesNotThrowNre()\n        {\n            IList<BenchmarkReport> reports = CreateReports(CreateConfig());\n\n            Assert.NotNull(CreateSummary(reports));\n        }\n\n        private static IConfig CreateConfig()\n        {\n            // We use runtime as selector later. It is chosen as selector just to be close to initial issue. Nothing particularly special about it.\n            Job coreJob = new Job(Job.Default).WithRuntime(CoreRuntime.Core80).ApplyAndFreeze(RunMode.Dry);\n            Job clrJob = new Job(Job.Default).WithRuntime(ClrRuntime.Net462).ApplyAndFreeze(RunMode.Dry);\n            return ManualConfig.Create(DefaultConfig.Instance).AddJob(coreJob).AddJob(clrJob);\n        }\n\n        private static BenchmarkReport[] CreateReports(IConfig config)\n        {\n            BenchmarkRunInfo benchmarkRunInfo = BenchmarkConverter.TypeToBenchmarks(typeof(MockBenchmarkClass), config);\n            return benchmarkRunInfo.BenchmarksCases.Select(CreateReport).ToArray();\n        }\n\n        private static BenchmarkReport CreateReport(BenchmarkCase benchmark)\n        {\n            return benchmark.Job.Environment.Runtime is ClrRuntime\n                ? CreateFailureReport(benchmark)\n                : CreateSuccessReport(benchmark);\n        }\n\n        private static BenchmarkReport CreateFailureReport(BenchmarkCase benchmark)\n        {\n            GenerateResult generateResult = GenerateResult.Failure(ArtifactsPaths.Empty, []);\n            BuildResult buildResult = BuildResult.Failure(generateResult, string.Empty);\n            // Null may be legitimately passed as metrics to BenchmarkReport ctor here:\n            // https://github.com/dotnet/BenchmarkDotNet/blob/89255c9fceb1b27c475a93d08c152349be4199e9/src/BenchmarkDotNet/Running/BenchmarkRunner.cs#L197\n            return new BenchmarkReport(false, benchmark, generateResult, buildResult, default, default);\n        }\n\n        private static BenchmarkReport CreateSuccessReport(BenchmarkCase benchmark)\n        {\n            GenerateResult generateResult = GenerateResult.Success(ArtifactsPaths.Empty, []);\n            BuildResult buildResult = BuildResult.Success(generateResult);\n            var metrics = new[] { new Metric(new FakeMetricDescriptor(), Math.E) };\n            return new BenchmarkReport(true, benchmark, generateResult, buildResult, [], metrics);\n        }\n\n        private static Summary CreateSummary(IList<BenchmarkReport> reports)\n        {\n            HostEnvironmentInfo hostEnvironmentInfo = new HostEnvironmentInfoBuilder().Build();\n            return new Summary(\"MockSummary\", reports.ToImmutableArray(), hostEnvironmentInfo, string.Empty, string.Empty, TimeSpan.FromMinutes(1.0), TestCultureInfo.Instance, [], []);\n        }\n\n        public class MockBenchmarkClass\n        {\n            [Benchmark(Baseline = true)]\n            public void Foo() { }\n        }\n\n        private sealed class FakeMetricDescriptor : IMetricDescriptor\n        {\n            public string Id { get; } = nameof(Id);\n            public string DisplayName { get; } = nameof(DisplayName);\n            public string Legend { get; } = nameof(Legend);\n            public string NumberFormat { get; } = \"N\";\n            public UnitType UnitType { get; }\n            public string Unit { get; } = nameof(Unit);\n            public bool TheGreaterTheBetter { get; }\n            public int PriorityInCategory => 0;\n            public bool GetIsAvailable(Metric metric) => true;\n        }\n    }\n}\n"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Running/BenchmarkConverterTests.BAC_Partial_DifferentFiles.cs",
    "content": "﻿using BenchmarkDotNet.Attributes;\n\nnamespace BenchmarkDotNet.Tests.Running\n{\n    public partial class BenchmarkConverterTests\n    {\n        public partial class BAC_Partial_DifferentFiles\n        {\n            [Benchmark] public void B() { }\n        }\n    }\n}\n"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Running/BenchmarkConverterTests.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Running;\nusing Perfolizer.Mathematics.OutlierDetection;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests.Running\n{\n    public partial class BenchmarkConverterTests\n    {\n        /// <summary>\n        /// https://github.com/dotnet/BenchmarkDotNet/issues/495\n        /// </summary>\n        [Fact]\n        public void ReadsAttributesFromBaseClass()\n        {\n            var derivedType = typeof(Derived);\n            BenchmarkCase benchmarkCase = BenchmarkConverter.TypeToBenchmarks(derivedType).BenchmarksCases.Single();\n\n            Assert.NotNull(benchmarkCase);\n            Assert.NotNull(benchmarkCase.Descriptor);\n\n            Assert.NotNull(benchmarkCase.Descriptor.IterationSetupMethod);\n            Assert.Equal(benchmarkCase.Descriptor.IterationSetupMethod.DeclaringType, derivedType);\n\n            Assert.NotNull(benchmarkCase.Descriptor.IterationCleanupMethod);\n            Assert.Equal(benchmarkCase.Descriptor.IterationCleanupMethod.DeclaringType, derivedType);\n\n            Assert.NotNull(benchmarkCase.Descriptor.GlobalCleanupMethod);\n            Assert.Equal(benchmarkCase.Descriptor.GlobalCleanupMethod.DeclaringType, derivedType);\n\n            Assert.NotNull(benchmarkCase.Descriptor.GlobalSetupMethod);\n            Assert.Equal(benchmarkCase.Descriptor.GlobalSetupMethod.DeclaringType, derivedType);\n        }\n\n        public abstract class Base\n        {\n            [GlobalSetup]\n            public abstract void GlobalSetup();\n\n            [GlobalCleanup]\n            public abstract void GlobalCleanup();\n\n            [IterationSetup]\n            public abstract void Setup();\n\n            [IterationCleanup]\n            public abstract void Cleanup();\n\n            [Benchmark]\n            public void Test()\n            {\n            }\n        }\n\n        public class Derived : Base\n        {\n            public override void GlobalSetup()\n            {\n            }\n\n            public override void GlobalCleanup()\n            {\n            }\n\n            public override void Setup()\n            {\n            }\n\n            public override void Cleanup()\n            {\n            }\n        }\n\n        [Fact]\n        public void IfIterationSetupIsProvidedTheBenchmarkShouldRunOncePerIteration()\n        {\n            var benchmark = BenchmarkConverter.TypeToBenchmarks(typeof(Derived)).BenchmarksCases.Single();\n\n            Assert.Equal(1, benchmark.Job.Run.InvocationCount);\n            Assert.Equal(1, benchmark.Job.Run.UnrollFactor);\n        }\n\n        [Fact]\n        public void IfIterationCleanupIsProvidedTheBenchmarkShouldRunOncePerIteration()\n        {\n            var benchmark = BenchmarkConverter.TypeToBenchmarks(typeof(WithIterationCleanupOnly)).BenchmarksCases.Single();\n\n            Assert.Equal(1, benchmark.Job.Run.InvocationCount);\n            Assert.Equal(1, benchmark.Job.Run.UnrollFactor);\n        }\n\n        public class WithIterationCleanupOnly\n        {\n            [IterationCleanup] public void Cleanup() { }\n            [Benchmark] public void Benchmark() { }\n        }\n\n        [Fact]\n        public void InvocationCountIsRespectedForBenchmarksWithIterationSetup()\n        {\n            const int InvocationCount = 100;\n\n            var benchmark = BenchmarkConverter.TypeToBenchmarks(typeof(Derived),\n                DefaultConfig.Instance.AddJob(Job.Default\n                    .WithInvocationCount(InvocationCount)))\n                .BenchmarksCases.Single();\n\n            Assert.Equal(InvocationCount, benchmark.Job.Run.InvocationCount);\n            Assert.NotNull(benchmark.Descriptor.IterationSetupMethod);\n        }\n\n        [Fact]\n        public void UnrollFactorIsRespectedForBenchmarksWithIterationSetup()\n        {\n            const int UnrollFactor = 13;\n\n            var benchmark = BenchmarkConverter.TypeToBenchmarks(typeof(Derived),\n                    DefaultConfig.Instance.AddJob(Job.Default\n                        .WithUnrollFactor(UnrollFactor)))\n                .BenchmarksCases.Single();\n\n            Assert.Equal(UnrollFactor, benchmark.Job.Run.UnrollFactor);\n            Assert.NotNull(benchmark.Descriptor.IterationSetupMethod);\n        }\n\n        [Fact]\n        public void JobMutatorsApplySettingsToAllNonMutatorJobs()\n        {\n            var info = BenchmarkConverter.TypeToBenchmarks(\n                    typeof(WithMutator),\n                    DefaultConfig.Instance\n                        .AddJob(Job.Default.WithRuntime(ClrRuntime.Net462))\n                        .AddJob(Job.Default.WithRuntime(CoreRuntime.Core80)));\n\n            Assert.Equal(2, info.BenchmarksCases.Length);\n            Assert.All(info.BenchmarksCases, benchmark => Assert.Equal(int.MaxValue, benchmark.Job.Run.MaxIterationCount));\n            Assert.Single(info.BenchmarksCases, benchmark => benchmark.Job.Environment.Runtime is ClrRuntime);\n            Assert.Single(info.BenchmarksCases, benchmark => benchmark.Job.Environment.Runtime is CoreRuntime);\n            Assert.All(info.BenchmarksCases, benchmark => Assert.False(benchmark.Job.Meta.IsMutator)); // the job does not became a mutator itself, this config should not be copied\n        }\n\n        [MaxIterationCount(int.MaxValue)]\n        public class WithMutator\n        {\n            [Benchmark] public void Method() { }\n        }\n\n        [Fact]\n        public void JobMutatorsApplySettingsToDefaultJobIfNoneOfTheConfigsContainsJob()\n        {\n            var info = BenchmarkConverter.TypeToBenchmarks(typeof(WithMutator));\n\n            var benchmark = info.BenchmarksCases.Single();\n\n            Assert.Equal(int.MaxValue, benchmark.Job.Run.MaxIterationCount);\n            Assert.False(benchmark.Job.Meta.IsMutator);\n        }\n\n        [Fact]\n        public void OrderOfAppliedAttributesDoesNotAffectMutators()\n        {\n            var info = BenchmarkConverter.TypeToBenchmarks(typeof(WithMutatorAfterJobAttribute));\n\n            var benchmark = info.BenchmarksCases.Single();\n\n            Assert.Equal(int.MaxValue, benchmark.Job.Run.MaxIterationCount);\n            Assert.True(benchmark.Job.Environment.Runtime is CoreRuntime);\n            Assert.False(benchmark.Job.Meta.IsMutator);\n        }\n\n        [MaxIterationCount(int.MaxValue)] // mutator attribute is before job attribute\n        [SimpleJob(runtimeMoniker: RuntimeMoniker.Net50)]\n        public class WithMutatorAfterJobAttribute\n        {\n            [Benchmark] public void Method() { }\n        }\n\n        [Fact]\n        public void FewMutatorsCanBeAppliedToSameType()\n        {\n            var info = BenchmarkConverter.TypeToBenchmarks(typeof(WithFewMutators));\n\n            var benchmarkCase = info.BenchmarksCases.Single();\n\n            Assert.Equal(1, benchmarkCase.Job.Run.InvocationCount);\n            Assert.Equal(1, benchmarkCase.Job.Run.UnrollFactor);\n            Assert.Equal(OutlierMode.DontRemove, benchmarkCase.Job.Accuracy.OutlierMode);\n            Assert.False(benchmarkCase.Job.Meta.IsMutator);\n        }\n\n        [RunOncePerIteration]\n        [Outliers(OutlierMode.DontRemove)]\n        public class WithFewMutators\n        {\n            [Benchmark] public void Method() { }\n        }\n\n        [Fact]\n        public void MethodDeclarationOrderIsPreserved()\n        {\n            foreach (Type type in new[] { typeof(BAC), typeof(BAC_Partial), typeof(BAC_Partial_DifferentFiles) })\n            {\n                var info = BenchmarkConverter.TypeToBenchmarks(type);\n\n                Assert.Equal(nameof(BAC.B), info.BenchmarksCases[0].Descriptor.WorkloadMethod.Name);\n                Assert.Equal(nameof(BAC.A), info.BenchmarksCases[1].Descriptor.WorkloadMethod.Name);\n                Assert.Equal(nameof(BAC.C), info.BenchmarksCases[2].Descriptor.WorkloadMethod.Name);\n            }\n        }\n\n        public class BAC\n        {\n            // BAC is not sorted in either descending or ascending way\n            [Benchmark] public void B() { }\n            [Benchmark] public void A() { }\n            [Benchmark] public void C() { }\n        }\n\n        public partial class BAC_Partial\n        {\n            [Benchmark] public void B() { }\n            [Benchmark] public void A() { }\n        }\n\n        public partial class BAC_Partial\n        {\n            [Benchmark] public void C() { }\n        }\n\n        public partial class BAC_Partial_DifferentFiles\n        {\n            [Benchmark] public void A() { }\n            [Benchmark] public void C() { }\n        }\n\n        [Fact]\n        public void ThrowsWhenSetupAndCleanupMethodsAreNonPublic()\n        {\n            var types = new[]\n            {\n                typeof(PrivateGlobalSetup),\n                typeof(PrivateGlobalCleanup),\n                typeof(PrivateIterationSetup),\n                typeof(PrivateIterationCleanup)\n            };\n\n            foreach (var type in types)\n            {\n                Assert.Throws<InvalidBenchmarkDeclarationException>(() => BenchmarkConverter.TypeToBenchmarks(type));\n            }\n        }\n\n        public class PrivateGlobalSetup\n        {\n            [GlobalSetup] private void X() { }\n            [Benchmark] public void A() { }\n        }\n\n        public class PrivateGlobalCleanup\n        {\n            [GlobalCleanup] private void X() { }\n            [Benchmark] public void A() { }\n        }\n\n        public class PrivateIterationSetup\n        {\n            [IterationSetup] private void X() { }\n            [Benchmark] public void A() { }\n        }\n\n        public class PrivateIterationCleanup\n        {\n            [IterationCleanup] private void X() { }\n            [Benchmark] public void A() { }\n        }\n    }\n}\n"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Running/JobRuntimePropertiesComparerTests.cs",
    "content": "﻿using System.Linq;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Tests.XUnit;\nusing BenchmarkDotNet.Toolchains.CsProj;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests.Running\n{\n    public class JobRuntimePropertiesComparerTests\n    {\n        [Fact]\n        public void SingleJobLeadsToNoGrouping()\n        {\n            var benchmarks1 = BenchmarkConverter.TypeToBenchmarks(typeof(Plain1));\n            var benchmarks2 = BenchmarkConverter.TypeToBenchmarks(typeof(Plain2));\n\n            var grouped = benchmarks1.BenchmarksCases.Union(benchmarks2.BenchmarksCases)\n                .GroupBy(benchmark => benchmark, new BenchmarkPartitioner.BenchmarkRuntimePropertiesComparer())\n                .ToArray();\n\n            Assert.Single(grouped); // we should have single exe!\n            Assert.Equal(benchmarks1.BenchmarksCases.Length + benchmarks2.BenchmarksCases.Length, grouped.Single().Count());\n        }\n\n        public class Plain1\n        {\n            [Benchmark] public void M1() { }\n            [Benchmark] public void M2() { }\n            [Benchmark] public void M3() { }\n        }\n\n        public class Plain2\n        {\n            [Benchmark] public void M1() { }\n            [Benchmark] public void M2() { }\n            [Benchmark] public void M3() { }\n        }\n\n        public class Plain3\n        {\n            [Benchmark] public void M1() { }\n            [Benchmark] public void M2() { }\n            [Benchmark] public void M3() { }\n        }\n\n        [Fact]\n        public void BenchmarksAreGroupedByJob()\n        {\n            var benchmarks = BenchmarkConverter.TypeToBenchmarks(typeof(AllRuntimes));\n\n            var grouped = benchmarks.BenchmarksCases\n                .GroupBy(benchmark => benchmark, new BenchmarkPartitioner.BenchmarkRuntimePropertiesComparer())\n                .ToArray();\n\n            Assert.Equal(3, grouped.Length); // Clr + Mono + Core\n\n            foreach (var grouping in grouped)\n                Assert.Equal(2, grouping.Count()); // M1 + M2\n        }\n\n        [SimpleJob(runtimeMoniker: RuntimeMoniker.Net462)]\n        [SimpleJob(runtimeMoniker: RuntimeMoniker.Mono)]\n        [SimpleJob(runtimeMoniker: RuntimeMoniker.Net50)]\n        public class AllRuntimes\n        {\n            [Benchmark] public void M1() { }\n            [Benchmark] public void M2() { }\n        }\n\n        [FactEnvSpecific(\"Full Framework is supported only on Windows\", EnvRequirement.WindowsOnly)]\n        public void CustomClrBuildJobsAreGroupedByVersion()\n        {\n            const string version = \"abcd\";\n\n            var config = ManualConfig.Create(DefaultConfig.Instance)\n                .AddJob(Job.Default.WithRuntime(ClrRuntime.CreateForLocalFullNetFrameworkBuild(version: version)))\n                .AddJob(Job.Default.WithRuntime(ClrRuntime.CreateForLocalFullNetFrameworkBuild(version: \"it's a different version\")))\n                .AddJob(Job.Default.WithRuntime(ClrRuntime.GetCurrentVersion()));\n\n            var benchmarks1 = BenchmarkConverter.TypeToBenchmarks(typeof(Plain1), config);\n            var benchmarks2 = BenchmarkConverter.TypeToBenchmarks(typeof(Plain2), config);\n\n            var grouped = benchmarks1.BenchmarksCases.Union(benchmarks2.BenchmarksCases)\n                .GroupBy(benchmark => benchmark, new BenchmarkPartitioner.BenchmarkRuntimePropertiesComparer())\n                .ToArray();\n\n            Assert.Equal(3, grouped.Length); // Job.Clr + Job.Clr(version) + Job.Clr(different)\n\n            foreach (var grouping in grouped)\n                Assert.Equal(3 * 2, grouping.Count()); // (M1 + M2 + M3) * (Plain1 + Plain2)\n        }\n\n        [Fact]\n        public void CustomTargetPlatformJobsAreGroupedByTargetFrameworkMoniker()\n        {\n            var net5Config = ManualConfig.Create(DefaultConfig.Instance)\n                .AddJob(Job.Default.WithToolchain(CsProjCoreToolchain.NetCoreApp50));\n            var net5WindowsConfig1 = ManualConfig.Create(DefaultConfig.Instance)\n                .AddJob(Job.Default.WithToolchain(CsProjCoreToolchain.From(new Toolchains.DotNetCli.NetCoreAppSettings(\n                    targetFrameworkMoniker: \"net5.0-windows\",\n                    runtimeFrameworkVersion: null!,\n                    name: \".NET 5.0\"))));\n            // a different INSTANCE of CsProjCoreToolchain that also targets \"net5.0-windows\"\n            var net5WindowsConfig2 = ManualConfig.Create(DefaultConfig.Instance)\n                .AddJob(Job.Default.WithToolchain(CsProjCoreToolchain.From(new Toolchains.DotNetCli.NetCoreAppSettings(\n                    targetFrameworkMoniker: \"net5.0-windows\",\n                    runtimeFrameworkVersion: null!,\n                    name: \".NET 5.0\"))));\n\n            var benchmarksNet5 = BenchmarkConverter.TypeToBenchmarks(typeof(Plain1), net5Config);\n            var benchmarksNet5Windows1 = BenchmarkConverter.TypeToBenchmarks(typeof(Plain2), net5WindowsConfig1);\n            var benchmarksNet5Windows2 = BenchmarkConverter.TypeToBenchmarks(typeof(Plain3), net5WindowsConfig2);\n\n            var grouped = benchmarksNet5.BenchmarksCases\n                .Union(benchmarksNet5Windows1.BenchmarksCases)\n                .Union(benchmarksNet5Windows2.BenchmarksCases)\n                .GroupBy(benchmark => benchmark, new BenchmarkPartitioner.BenchmarkRuntimePropertiesComparer())\n                .ToArray();\n\n            Assert.Equal(2, grouped.Length);\n\n            Assert.Single(grouped, group => group.Count() == 3); // Plain1 (3 methods) running against \"net5.0\"\n            Assert.Single(grouped, group => group.Count() == 6); // Plain2 (3 methods) and Plain3 (3 methods) running against \"net5.0-windows\"\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/RuntimeVersionDetectionTests.cs",
    "content": "﻿using BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Portability;\nusing System;\nusing System.Collections.Generic;\nusing System.IO;\nusing BenchmarkDotNet.Detectors;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests\n{\n    public class RuntimeVersionDetectionTests\n    {\n        [Theory]\n        [InlineData(\".NETCoreApp,Version=v2.0\", RuntimeMoniker.NetCoreApp20, \"netcoreapp2.0\")]\n        [InlineData(\".NETCoreApp,Version=v2.1\", RuntimeMoniker.NetCoreApp21, \"netcoreapp2.1\")]\n        [InlineData(\".NETCoreApp,Version=v2.2\", RuntimeMoniker.NetCoreApp22, \"netcoreapp2.2\")]\n        [InlineData(\".NETCoreApp,Version=v3.0\", RuntimeMoniker.NetCoreApp30, \"netcoreapp3.0\")]\n        [InlineData(\".NETCoreApp,Version=v3.1\", RuntimeMoniker.NetCoreApp31, \"netcoreapp3.1\")]\n        [InlineData(\".NETCoreApp,Version=v5.0\", RuntimeMoniker.Net50, \"net5.0\")]\n        [InlineData(\".NETCoreApp,Version=v6.0\", RuntimeMoniker.Net60, \"net6.0\")]\n        [InlineData(\".NETCoreApp,Version=v7.0\", RuntimeMoniker.Net70, \"net7.0\")]\n        [InlineData(\".NETCoreApp,Version=v8.0\", RuntimeMoniker.Net80, \"net8.0\")]\n        [InlineData(\".NETCoreApp,Version=v9.0\", RuntimeMoniker.Net90, \"net9.0\")]\n        [InlineData(\".NETCoreApp,Version=v10.0\", RuntimeMoniker.Net10_0, \"net10.0\")]\n        [InlineData(\".NETCoreApp,Version=v11.0\", RuntimeMoniker.Net11_0, \"net11.0\")]\n        [InlineData(\".NETCoreApp,Version=v123.0\", RuntimeMoniker.NotRecognized, \"net123.0\")]\n        public void TryGetVersionFromFrameworkNameHandlesValidInput(string frameworkName, RuntimeMoniker expectedTfm, string expectedMsBuildMoniker)\n        {\n            Assert.True(CoreRuntime.TryGetVersionFromFrameworkName(frameworkName, out var version));\n\n            var runtime = CoreRuntime.FromVersion(version);\n\n            Assert.Equal(expectedTfm, runtime.RuntimeMoniker);\n            Assert.Equal(expectedMsBuildMoniker, runtime.MsBuildMoniker);\n        }\n\n        [Theory]\n        [InlineData(null)]\n        [InlineData(\"\")]\n        [InlineData(\".NETCoreApp,Version=v\")]\n        [InlineData(\"just wrong\")]\n        public void TryGetVersionFromFrameworkNameHandlesInvalidInput(string? frameworkName)\n        {\n            Assert.False(CoreRuntime.TryGetVersionFromFrameworkName(frameworkName!, out _));\n        }\n\n        [Theory]\n        [InlineData(RuntimeMoniker.NetCoreApp21, \"netcoreapp2.1\", \"Microsoft .NET Framework\", \"4.6.27817.01 @BuiltBy: dlab14-DDVSOWINAGE101 @Branch: release/2.1 @SrcCode: https://github.com/dotnet/coreclr/tree/6f78fbb3f964b4f407a2efb713a186384a167e5c\")]\n        [InlineData(RuntimeMoniker.NetCoreApp22, \"netcoreapp2.2\", \"Microsoft .NET Framework\", \"4.6.27817.03 @BuiltBy: dlab14-DDVSOWINAGE101 @Branch: release/2.2 @SrcCode: https://github.com/dotnet/coreclr/tree/ce1d090d33b400a25620c0145046471495067cc7\")]\n        [InlineData(RuntimeMoniker.NetCoreApp30, \"netcoreapp3.0\", \"Microsoft .NET Core\", \"3.0.0-preview8-28379-12\")]\n        [InlineData(RuntimeMoniker.NetCoreApp31, \"netcoreapp3.1\", \"Microsoft .NET Core\", \"3.1.0-something\")]\n        [InlineData(RuntimeMoniker.Net50, \"net5.0\", \"Microsoft .NET Core\", \"5.0.0-alpha1.19415.3\")]\n        [InlineData(RuntimeMoniker.NotRecognized, \"net123.0\", \"Microsoft .NET Core\", \"123.0.0-future\")]\n        public void TryGetVersionFromProductInfoHandlesValidInput(RuntimeMoniker expectedTfm, string expectedMsBuildMoniker, string productName, string productVersion)\n        {\n            Assert.True(CoreRuntime.TryGetVersionFromProductInfo(productVersion, productName, out var version));\n\n            var runtime = CoreRuntime.FromVersion(version);\n\n            Assert.Equal(expectedTfm, runtime.RuntimeMoniker);\n            Assert.Equal(expectedMsBuildMoniker, runtime.MsBuildMoniker);\n        }\n\n        [Theory]\n        [InlineData(null, null)]\n        [InlineData(\"\", \"\")]\n        [InlineData(\"not\", \"ok\")]\n        [InlineData(\"Microsoft .NET Framework\", \"4.6.26614.01 @BuiltBy: dlab14-DDVSOWINAGE018 @Commit: a536e7eec55c538c94639cefe295aa672996bf9b\")] // this is an actual output for 2.0 but it simply does not contain enough info\n        public void TryGetVersionFromProductInfoHandlesInvalidInput(string? productName, string? productVersion)\n        {\n            Assert.False(CoreRuntime.TryGetVersionFromProductInfo(productVersion!, productName!, out _));\n        }\n\n        public static IEnumerable<object[]> FromNetCoreAppVersionHandlesValidInputArguments()\n        {\n            string directoryPrefix = Path.GetTempPath(); // this test runs on Unix, it can not be hardcoded due to / \\ difference\n\n            yield return new object[] { Path.Combine(directoryPrefix, \"2.0.9\") + Path.DirectorySeparatorChar, RuntimeMoniker.NetCoreApp20, \"netcoreapp2.0\" };\n            yield return new object[] { Path.Combine(directoryPrefix, \"2.1.12\") + Path.DirectorySeparatorChar, RuntimeMoniker.NetCoreApp21, \"netcoreapp2.1\" };\n            yield return new object[] { Path.Combine(directoryPrefix, \"2.2.6\") + Path.DirectorySeparatorChar, RuntimeMoniker.NetCoreApp22, \"netcoreapp2.2\" };\n            yield return new object[] { Path.Combine(directoryPrefix, \"3.0.0-preview8-28379-12\") + Path.DirectorySeparatorChar, RuntimeMoniker.NetCoreApp30, \"netcoreapp3.0\" };\n            yield return new object[] { Path.Combine(directoryPrefix, \"5.0.0-alpha1.19422.13\") + Path.DirectorySeparatorChar, RuntimeMoniker.Net50, \"net5.0\" };\n            yield return new object[] { Path.Combine(directoryPrefix, \"123.0.0\") + Path.DirectorySeparatorChar, RuntimeMoniker.NotRecognized, \"net123.0\" };\n        }\n\n        [Theory]\n        [MemberData(nameof(FromNetCoreAppVersionHandlesValidInputArguments))]\n        public void TryGetVersionFromRuntimeDirectoryHandlesValidInput(string runtimeDirectory, RuntimeMoniker expectedTfm, string expectedMsBuildMoniker)\n        {\n            Assert.True(CoreRuntime.TryGetVersionFromRuntimeDirectory(runtimeDirectory, out var version));\n\n            var runtime = CoreRuntime.FromVersion(version);\n\n            Assert.Equal(expectedTfm, runtime.RuntimeMoniker);\n            Assert.Equal(expectedMsBuildMoniker, runtime.MsBuildMoniker);\n        }\n\n        public static IEnumerable<object[]> TryGetVersionFromRuntimeDirectoryInvalidInputArguments()\n        {\n            yield return [null!];\n            yield return [string.Empty];\n            yield return [Path.Combine(Path.GetTempPath(), \"publish\")];\n            yield return [Path.Combine(Path.GetTempPath(), \"publish\") + Path.DirectorySeparatorChar];\n        }\n\n        [Theory]\n        [MemberData(nameof(TryGetVersionFromRuntimeDirectoryInvalidInputArguments))]\n        public void TryGetVersionFromRuntimeDirectoryHandlesInvalidInput(string runtimeDirectory)\n        {\n            Assert.False(CoreRuntime.TryGetVersionFromRuntimeDirectory(runtimeDirectory, out _));\n        }\n\n        [Fact]\n        public void CurrentRuntimeIsProperlyRecognized()\n        {\n            var runtime = RuntimeInformation.GetCurrentRuntime();\n\n#if NETFRAMEWORK\n            if (OsDetector.IsWindows())\n                Assert.True(runtime is ClrRuntime, $\"Actual runtime: {runtime}, tfm: {runtime.MsBuildMoniker}, moniker: {runtime.RuntimeMoniker}\");\n            else\n                Assert.True(runtime is MonoRuntime, $\"Actual runtime: {runtime}, tfm: {runtime.MsBuildMoniker}, moniker: {runtime.RuntimeMoniker}\");\n#elif NET10_0_OR_GREATER\n            Assert.True(runtime is CoreRuntime coreRuntime && coreRuntime.RuntimeMoniker == RuntimeMoniker.Net10_0, $\"Actual runtime: {runtime}, tfm: {runtime.MsBuildMoniker}, moniker: {runtime.RuntimeMoniker}\");\n#else\n            Assert.True(runtime is CoreRuntime coreRuntime && coreRuntime.RuntimeMoniker == RuntimeMoniker.Net80, $\"Actual runtime: {runtime}, tfm: {runtime.MsBuildMoniker}, moniker: {runtime.RuntimeMoniker}\");\n#endif\n        }\n    }\n}\n"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Serialization/DisassemblerModelSerializationTests.cs",
    "content": "﻿using AwesomeAssertions;\nusing BenchmarkDotNet.Disassemblers;\nusing BenchmarkDotNet.Serialization;\nusing BenchmarkDotNet.Tests.XUnit;\nusing Gee.External.Capstone;\nusing Gee.External.Capstone.Arm64;\nusing Iced.Intel;\nusing System.Linq;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests;\n\npublic class DisassemblerModelSerializationTests\n{\n    [Fact]\n    public void ClrMdArgsSerializationTest()\n    {\n        // Arrange\n        var model = new ClrMdArgs(\n            processId: 100, //  ProcessID field is not serialized/deserialized.\n            typeName: \"TypeName\", //  TypeName field is not serialized/deserialized.\n            methodName: \"MethodName\",\n            printSource: true,\n            maxDepth: 5,\n            syntax: \"Syntax\",\n            tfm: \"Tfm\",\n            filters: [\"filter1\", \"filter2\"],\n            resultsPath: \"/path/to/results\"\n        );\n\n        // Act\n        var json = BdnJsonSerializer.Serialize(model);\n        var result = BdnJsonSerializer.Deserialize<ClrMdArgs>(json);\n\n        // Assert\n        json.Should().NotBe(\"{}\");\n        result.Should().BeEquivalentTo(\n            model,\n            options => options\n                .IncludingInternalFields()\n                .ComparingByMembers<ClrMdArgs>() // Required to use Excluding for struct type. See: https://github.com/fluentassertions/fluentassertions/issues/937\n                .Excluding(x => x.ProcessId)\n                .Excluding(x => x.TypeName));\n    }\n\n    [Fact]\n    public void SharpSerializationTest()\n    {\n        var model = new Sharp\n        {\n            InstructionPointer = 1,\n            Text = \"Text\",\n            FilePath = \"FilePath\",\n            LineNumber = 2,\n        };\n\n        // Act\n        var json = BdnJsonSerializer.Serialize(model);\n        var result = BdnJsonSerializer.Deserialize<Sharp>(json);\n\n        // Assert\n        json.Should().NotBe(\"{}\");\n        result.Should().BeEquivalentTo(model);\n    }\n\n    [Fact]\n    public void MonoCodeSerializationTest()\n    {\n        // Arrange\n        var model = new MonoCode\n        {\n            InstructionPointer = 1,\n            Text = \"Text\",\n        };\n\n        // Act\n        var json = BdnJsonSerializer.Serialize(model);\n        var result = BdnJsonSerializer.Deserialize<MonoCode>(json);\n\n        // Assert\n        json.Should().NotBe(\"{}\");\n        result.Should().BeEquivalentTo(model);\n    }\n\n    [Fact]\n    public void IntelAsmSerializationTest()\n    {\n        // Arrange\n        var model = new IntelAsm\n        {\n            InstructionPointer = 1,\n            InstructionLength = 2,\n            ReferencedAddress = 3,\n            IsReferencedAddressIndirect = true,\n            Instruction = Instruction.Create(\n                Iced.Intel.Code.Xlat_m8,\n                new MemoryOperand(Register.RBX, Register.AL)\n            ),\n        };\n\n        // Act\n        var json = BdnJsonSerializer.Serialize(model);\n        var result = BdnJsonSerializer.Deserialize<IntelAsm>(json);\n\n        // Assert\n        Assert.NotEqual(\"{}\", json);\n        Assert.Equivalent(model, result, strict: true);\n    }\n\n    [FactEnvSpecific(\"ARM64 disassembler is not supported on .NET Framework or Windows+Arm environment\", EnvRequirement.NonFullFramework, EnvRequirement.NonWindowsArm)]\n    public void Arm64AsmSerializationTest()\n    {\n        // Arrange\n        byte[] instructionBytes = [0xE1, 0x0B, 0x40, 0xB9]; // ldr w1, [sp, #8]\n        var disassembleSyntax = DisassembleSyntax.Intel;\n\n        // Create instruction instance by using disassembler.\n        using var disassembler = CapstoneDisassembler.CreateArm64Disassembler(Arm64DisassembleMode.Arm);\n        disassembler.EnableInstructionDetails = true;\n        disassembler.DisassembleSyntax = disassembleSyntax;\n\n        // Act\n        var instructions = disassembler.Disassemble(instructionBytes);\n        var instruction = instructions.Single();\n\n        var model = new Arm64Asm\n        {\n            DisassembleSyntax = disassembleSyntax,\n            Instruction = instruction,\n            InstructionLength = instruction.Bytes.Length,\n            InstructionPointer = (ulong)instruction.Address,\n            ReferencedAddress = (instruction.Address > ushort.MaxValue) ? (ulong)instruction.Address : null,\n            IsReferencedAddressIndirect = true, // Test with dummy value\n        };\n\n        // Act\n        var json = BdnJsonSerializer.Serialize(model);\n        var result = BdnJsonSerializer.Deserialize<Arm64Asm>(json);\n\n        // Assert\n        json.Should().NotBe(\"{}\");\n\n        // Compare properties (Except  for`Instruction.Details.Operands` property that )\n        result.Should().NotBeNull();\n        result.Instruction.Should().NotBeNull();\n        result.Instruction.ToString().Should().Be(\"ldr w1, [sp, #8]\");\n\n        result.Should()\n              .BeEquivalentTo(model, options => options.Excluding(x => x.Instruction!.Details.Operands));\n    }\n\n    [Fact]\n    public void MapSerializationTest()\n    {\n        // Arrange\n        var model = new Map\n        {\n            SourceCodes =\n            [\n                new MonoCode\n                {\n                    Text = \"MonoCodeText1\",\n                    InstructionPointer = 1,\n                },\n                new Sharp\n                {\n                    Text = \"SharpText\" ,\n                    FilePath =\"FilePath\",\n                    LineNumber = 1,\n                    InstructionPointer = 2,\n                },\n                new MonoCode {\n                    Text = \"MonoCodeText2\",\n                    InstructionPointer = 2,\n                },\n            ]\n        };\n\n        // Act\n        var json = BdnJsonSerializer.Serialize(model);\n        var result = BdnJsonSerializer.Deserialize<Map>(json);\n\n        // Assert\n        json.Should().NotBe(\"{}\");\n        result.Should().BeEquivalentTo(model);\n    }\n\n    [Fact]\n    public void DisassembledMethodSerializationTest()\n    {\n        // Arrange\n        var model = new DisassembledMethod\n        {\n            Name = \"Name\",\n            CommandLine = \"CommandLine\",\n            NativeCode = 1,\n            Problem = \"Problem\",\n            Maps =\n            [\n                new Map()\n                {\n                    SourceCodes =\n                    [\n                        new MonoCode\n                        {\n                            InstructionPointer = 1,\n                            Text = \"MonoCode1\",\n                        },\n                    ]\n                },\n                new Map()\n                {\n                    SourceCodes =\n                    [\n                        new MonoCode\n                        {\n                            InstructionPointer = 2,\n                            Text = \"MonoCode2\",\n                        },\n                    ]\n                },\n            ]\n        };\n\n        // Act\n        var json = BdnJsonSerializer.Serialize(model);\n        var result = BdnJsonSerializer.Deserialize<DisassembledMethod>(json);\n\n        // Assert\n        json.Should().NotBe(\"{}\");\n        result.Should().BeEquivalentTo(model);\n    }\n\n    [Fact]\n    public void DisassemblyResultSerializationTest()\n    {\n        var model = new DisassemblyResult\n        {\n            AddressToNameMapping =\n            {\n                [1] = \"Name1\",\n                [2] = \"Name2\",\n                [3] = \"Name3\",\n            },\n            Errors = [\"Error1\", \"Error2\", \"Error3\"],\n            Methods =\n            [\n                new DisassembledMethod{Name= \"Method1\" },\n                new DisassembledMethod{Name= \"Method2\" },\n                new DisassembledMethod{Name= \"Method3\" },\n            ],\n            PointerSize = 1,\n        };\n\n        // Act\n        var json = BdnJsonSerializer.Serialize(model);\n        var result = BdnJsonSerializer.Deserialize<DisassemblyResult>(json);\n\n        // Assert\n        Assert.NotEqual(\"{}\", json);\n        Assert.Equivalent(model, result, strict: true);\n    }\n}\n"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Serialization/SummaryJsonSerializationTests.cs",
    "content": "﻿using AwesomeAssertions;\nusing BenchmarkDotNet.Serialization;\nusing System.Collections.Generic;\nusing System.Linq;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests;\n\npublic class SummarySerializationTests\n{\n    [Theory]\n    [InlineData(10.0, \"test\", double.NaN)]\n    public void SimpleJson_ReplaceUnsupportedNumericValues_Smoke(object val1, object val2, object val3)\n    {\n        //Arrange\n        var data = new List<object>()\n        {\n            val1, val2, val3\n        };\n\n        //Act\n        for (int i = 0; i < data.Count; i++)\n        {\n            data[i] = ReplaceUnsupportedNumericValues(data[i]);\n        }\n\n        //Assert\n        Assert.Equal(val1, data[0]);\n        Assert.Equal(val2, data[1]);\n        Assert.Equal(JSON_EMPTY_STRING, data[2]);\n    }\n\n    [Fact]\n    public void SimpleJson_SerializeObjectWithUnsupportedNumericValues_ReturnsValidJson()\n    {\n        //Arrange\n        var data = new Dictionary<string, object>\n        {\n            { \"Statistic1\", float.NaN},\n            { \"Statistic2\", float.NegativeInfinity },\n            { \"Statistic3\", float.PositiveInfinity },\n            { \"Statistic4\", double.NaN},\n            { \"Statistic5\", double.NegativeInfinity },\n            { \"Statistic6\", double.PositiveInfinity }\n        };\n\n        //Act\n        string json = BdnSimpleJsonSerializer.Serialize(data, indentJson: true);\n\n        //Assert\n        var expected =\n            \"\"\"\n            {\n              \"Statistic1\": \"\",\n              \"Statistic2\": \"\",\n              \"Statistic3\": \"\",\n              \"Statistic4\": \"\",\n              \"Statistic5\": \"\",\n              \"Statistic6\": \"\"\n            }\n            \"\"\";\n        Assert.Equal(expected, json, ignoreLineEndingDifferences: true);\n    }\n\n    private const string JSON_EMPTY_STRING = \"\\\"\\\"\";\n\n    private static object ReplaceUnsupportedNumericValues(object value)\n    {\n        switch (value)\n        {\n            case float.NaN:\n            case float.NegativeInfinity:\n            case float.PositiveInfinity:\n            case double.NaN:\n            case double.NegativeInfinity:\n            case double.PositiveInfinity:\n                return JSON_EMPTY_STRING;\n            default:\n                return value;\n        }\n    }\n}\n"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/SourceCodeHelperTests.cs",
    "content": "﻿using System;\nusing System.Reflection;\nusing BenchmarkDotNet.Helpers;\nusing Xunit;\nusing Xunit.Abstractions;\n\nnamespace BenchmarkDotNet.Tests\n{\n    // TODO: add decimal, typeof, CreateInstance, TimeValue, IntPtr, IFormattable\n    public class SourceCodeHelperTests\n    {\n        private readonly ITestOutputHelper output;\n\n        public SourceCodeHelperTests(ITestOutputHelper output) => this.output = output;\n\n        [Theory]\n        [InlineData(null, \"null\")]\n        [InlineData(false, \"false\")]\n        [InlineData(true, \"true\")]\n        [InlineData(\"string\", \"\\\"string\\\"\")]\n        [InlineData(\"string/\\\\\", @\"\"\"string/\\\\\"\"\")]\n        [InlineData('a', \"'a'\")]\n        [InlineData('\\\\', \"'\\\\\\\\'\")]\n        [InlineData(0.123f, \"0.123f\")]\n        [InlineData(0.123d, \"0.123d\")]\n        [InlineData(BindingFlags.Public, \"(global::System.Reflection.BindingFlags)(16)\")]\n        public void ToSourceCodeSimpleTest(object? original, string expected)\n        {\n            string actual = SourceCodeHelper.ToSourceCode(original);\n            output.WriteLine(\"ORIGINAL  : \" + original + \" (\" + original?.GetType() + \")\");\n            output.WriteLine(\"ACTUAL    : \" + actual);\n            output.WriteLine(\"EXPECTED  : \" + expected);\n            Assert.Equal(expected, actual);\n        }\n\n        [Fact]\n        public void SupportsGuid()\n        {\n            const string guidAsString = \"e9a42b02-d5df-448d-aa00-03f14749eb61\";\n            Assert.Equal($\"System.Guid.Parse(\\\"{guidAsString}\\\")\", SourceCodeHelper.ToSourceCode(Guid.Parse(guidAsString)));\n        }\n\n        [Fact]\n        public void CanEscapeJson()\n        {\n            const string expected = \"\\\"{ \\\\\\\"message\\\\\\\": \\\\\\\"Hello, World!\\\\\\\" }\\\"\";\n\n            var actual = SourceCodeHelper.ToSourceCode(\"{ \\\"message\\\": \\\"Hello, World!\\\" }\");\n\n            Assert.Equal(expected, actual);\n        }\n\n        [Fact]\n        public void CanEscapePath()\n        {\n            const string expected = @\"\"\"C:\\\\Projects\\\\BenchmarkDotNet\\\\samples\\\\BenchmarkDotNet.Samples\"\"\";\n\n            var actual = SourceCodeHelper.ToSourceCode(@\"C:\\Projects\\BenchmarkDotNet\\samples\\BenchmarkDotNet.Samples\");\n\n            Assert.Equal(expected, actual);\n        }\n\n        [Fact]\n        public void CanEscapeControlCharacters()\n        {\n            const string expected = @\"\"\" \\0 \\b \\f \\n \\t \\v \\\"\" a a a a { } \"\"\";\n\n            var actual = SourceCodeHelper.ToSourceCode(\" \\0 \\b \\f \\n \\t \\v \\\" \\u0061 \\x0061 \\x61 \\U00000061 { } \");\n\n            Assert.Equal(expected, actual);\n        }\n\n        [Theory]\n        [InlineData('\\0', @\"'\\0'\")]\n        [InlineData('\\b', @\"'\\b'\")]\n        [InlineData('\\f', @\"'\\f'\")]\n        [InlineData('\\n', @\"'\\n'\")]\n        [InlineData('\\t', @\"'\\t'\")]\n        [InlineData('\\v', @\"'\\v'\")]\n        [InlineData('\\'', @\"'\\''\")]\n        [InlineData('\\u0061', \"'a'\")]\n        [InlineData('\"', \"'\\\"'\")]\n        [InlineData('{', \"'{'\")]\n        [InlineData('}', \"'}'\")]\n        public void CanEscapeControlCharactersInChar(char original, string excepted)\n        {\n            var actual = SourceCodeHelper.ToSourceCode(original);\n\n            Assert.Equal(excepted, actual);\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/StringExtensionsTests.cs",
    "content": "﻿using System;\nusing System.IO;\nusing System.Text;\nusing BenchmarkDotNet.Extensions;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests\n{\n    public class StringExtensionsTests\n    {\n        [Fact]\n        public void AsValidFileNameReplacesAllInvalidFileNameCharactersWithTheirRepresentation()\n        {\n            foreach (char invalidPathChar in Path.GetInvalidFileNameChars())\n                Assert.Equal($\"char{(short) invalidPathChar}\", invalidPathChar.ToString().AsValidFileName());\n        }\n\n        [Fact]\n        public void AsValidFileNameDoesNotChangeValidFileNames()\n        {\n            const string validFileName = \"valid_File-Name.exe\";\n\n            Assert.Equal(validFileName, validFileName.AsValidFileName());\n        }\n\n        [Fact]\n        public void HtmlEncodeCharacters()\n        {\n            string expectedHtml = \"&lt;&#39;&gt;&quot;&amp;shouldntchange\";\n            string html = \"<'>\\\"&shouldntchange\";\n\n            Assert.Equal(expectedHtml, html.HtmlEncode());\n        }\n\n        [Theory]\n        [InlineData(null, \"\")]\n        [InlineData(\"\", \"\")]\n        [InlineData(\" \", \"\")]\n        [InlineData(\"-n win-x64\", \" -n win-x64\")]\n        [InlineData(\" -n win-x64\", \" -n win-x64\")]\n        [InlineData(\"-n win-x64 \", \" -n win-x64\")]\n        [InlineData(\" -n Win-x64 \", \" -n Win-x64\")]\n        [InlineData(\" a \", \" a\")]\n        [InlineData(\"        a        \", \" a\")]\n        [InlineData(\"   \\r\\n  a   \\r\\n\", \" a\")]\n        public void AppendArgumentMakesSureOneSpaceBeforeStringArgument(string? input, string expectedOutput)\n        {\n            var stringBuilder = new StringBuilder();\n            var result = stringBuilder.AppendArgument(input).ToString();\n\n            Assert.Equal(expectedOutput, result);\n        }\n\n        [Theory]\n        [InlineData(null, \"\")]\n        [InlineData(\"http://test.com/\", \" http://test.com/\")]\n        [InlineData(\" http://test.com/\", \" http://test.com/\")]\n        [InlineData(\"http://test.com/ \", \" http://test.com/\")]\n        [InlineData(\" http://test.com/ \", \" http://test.com/\")]\n        [InlineData(\"\\r\\n  http://test.com/  \\r\\n\", \" http://test.com/\")]\n        public void AppendArgumentMakesSureOneSpaceBeforeObjectArgument(string? input, string expectedOutput)\n        {\n            Uri? uri = input != null ? new Uri(input) : null; // Use Uri for our object type since that is what is used in code\n            var stringBuilder = new StringBuilder();\n            var result = stringBuilder.AppendArgument(uri).ToString();\n\n            Assert.Equal(expectedOutput, result);\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/SummaryStyleTests.cs",
    "content": "﻿using System.Globalization;\nusing BenchmarkDotNet.Columns;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Reports;\nusing Perfolizer.Horology;\nusing Perfolizer.Metrology;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests\n{\n    public class SummaryStyleTests\n    {\n        [Fact]\n        public void UserCanDefineCustomSummaryStyle()\n        {\n            var summaryStyle = new SummaryStyle\n            (\n                cultureInfo: CultureInfo.InvariantCulture,\n                printUnitsInHeader: true,\n                printUnitsInContent: false,\n                printZeroValuesInContent: true,\n                sizeUnit: SizeUnit.B,\n                timeUnit: TimeUnit.Millisecond\n            );\n\n            var config = ManualConfig.CreateEmpty().WithSummaryStyle(summaryStyle);\n\n            Assert.Equal(CultureInfo.InvariantCulture, config.SummaryStyle!.CultureInfo);\n            Assert.True(config.SummaryStyle.PrintUnitsInHeader);\n            Assert.False(config.SummaryStyle.PrintUnitsInContent);\n            Assert.True(config.SummaryStyle.PrintZeroValuesInContent);\n            Assert.Equal(SizeUnit.B, config.SummaryStyle.SizeUnit);\n            Assert.Equal(TimeUnit.Millisecond, config.SummaryStyle.TimeUnit);\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/TargetFrameworkVersionParsingTestscs.cs",
    "content": "﻿using BenchmarkDotNet.Disassemblers;\nusing System;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests\n{\n    public class TargetFrameworkVersionParsingTestscs\n    {\n        [Theory]\n        [InlineData(\"net461\", 4, 6, 1)]\n        [InlineData(\"net48\", 4, 8, -1)]\n        [InlineData(\"net7.0\", 7, 0, -1)]\n        [InlineData(\"net7.0-windows8\", 7, 0, -1)]\n        public void RuntimeVersionCanBeParsedFromTfm(string tfm, int major, int minor, int build)\n        {\n            Version version = State.ParseVersion(tfm);\n\n            Assert.Equal(major, version.Major);\n            Assert.Equal(minor, version.Minor);\n            Assert.Equal(build, version.Build);\n        }\n    }\n}\n"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/TestCultureInfo.cs",
    "content": "using System.Globalization;\nusing BenchmarkDotNet.Helpers;\n\nnamespace BenchmarkDotNet.Tests\n{\n    internal static class TestCultureInfo\n    {\n        public static readonly CultureInfo Instance;\n\n        static TestCultureInfo()\n        {\n            Instance = (CultureInfo) DefaultCultureInfo.Instance.Clone();\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/TheoryDataHelper.cs",
    "content": "using System.Collections.Generic;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests\n{\n    public static class TheoryDataHelper\n    {\n        public static TheoryData<string> Create(IEnumerable<string> values)\n        {\n            var data = new TheoryData<string>();\n            foreach (string value in values)\n                data.Add(value);\n            return data;\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/TypeFilterTests.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Reflection;\nusing Xunit;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.ConsoleArguments;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Loggers;\nusing BenchmarkDotNet.Tests;\nusing BenchmarkDotNet.Tests.Loggers;\nusing JetBrains.Annotations;\nusing Xunit.Abstractions;\nusing TypeFilter = BenchmarkDotNet.Running.TypeFilter;\n\nnamespace BenchmarkDotNet.Tests\n{\n    public class TypeFilterTests\n    {\n        public ITestOutputHelper Output { get; }\n\n        public TypeFilterTests(ITestOutputHelper output) => Output = output;\n\n        [Fact]\n        public void ReturnsNoBenchmarksForInvalidTypes()\n        {\n            var benchmarks = Filter([typeof(ClassC)], [\"--filter\", \"*\"]);\n\n            Assert.Empty(benchmarks);\n        }\n\n        [Fact]\n        public void CanFilterAllBenchmark()\n        {\n            var benchmarks = Filter([typeof(ClassA), typeof(ClassB)], [\"--filter\", \"*\"]);\n\n            Assert.Equal(5, benchmarks.Count);\n            Assert.Contains(\"ClassA.Method1\", benchmarks);\n            Assert.Contains(\"ClassA.Method2\", benchmarks);\n            Assert.Contains(\"ClassB.Method1\", benchmarks);\n            Assert.Contains(\"ClassB.Method2\", benchmarks);\n            Assert.Contains(\"ClassB.Method3\", benchmarks);\n        }\n\n        [Fact]\n        public void CanFilterAllBenchmarksDuringListAllBenchmarkCase()\n        {\n            var benchmarks = Filter([typeof(ClassA), typeof(ClassB)], [\"--list\", \"flat\"]);\n\n            Assert.Equal(5, benchmarks.Count);\n            Assert.Contains(\"ClassA.Method1\", benchmarks);\n            Assert.Contains(\"ClassA.Method2\", benchmarks);\n            Assert.Contains(\"ClassB.Method1\", benchmarks);\n            Assert.Contains(\"ClassB.Method2\", benchmarks);\n            Assert.Contains(\"ClassB.Method3\", benchmarks);\n        }\n\n        [Fact]\n        public void CanFilterBenchmarksDuringListAllBenchmarkCase()\n        {\n            var benchmarks = Filter([typeof(ClassA), typeof(ClassB)], [\"--list\", \"flat\", \"--filter\", \"*ClassB*\"]);\n\n            Assert.Equal(3, benchmarks.Count);\n            Assert.Contains(\"ClassB.Method1\", benchmarks);\n            Assert.Contains(\"ClassB.Method2\", benchmarks);\n            Assert.Contains(\"ClassB.Method3\", benchmarks);\n        }\n\n        [Fact]\n        public void CanSelectMethods()\n        {\n            var benchmarks = Filter([typeof(ClassA), typeof(ClassB)], [\"--filter\", \"*Method2\", \"*Method3\"]);\n\n            Assert.Equal(3, benchmarks.Count);\n            Assert.Contains(\"ClassA.Method2\", benchmarks);\n            Assert.Contains(\"ClassB.Method2\", benchmarks);\n            Assert.Contains(\"ClassB.Method3\", benchmarks);\n        }\n\n        [Fact]\n        public void CanSelectMethodsWithFullName()\n        {\n            var benchmarks = Filter(\n                [typeof(ClassA), typeof(ClassB)],\n                [\"--filter\", \"BenchmarkDotNet.Tests.ClassA.Method2\", \"BenchmarkDotNet.Tests.ClassB.Method3\"]);\n\n            Assert.Equal(2, benchmarks.Count);\n            Assert.Contains(\"ClassA.Method2\", benchmarks);\n            Assert.Contains(\"ClassB.Method3\", benchmarks);\n        }\n\n        [Fact]\n        public void CanSelectClassesUsingPatters()\n        {\n            var benchmarks = Filter(\n                [typeof(ClassA), typeof(ClassB)],\n                [\"--filter\", \"*ClassC*\", \"*ClassA*\"]);\n\n            // ClassC not matched as it has NO methods with the [Benchmark] attribute\n            Assert.Equal(2, benchmarks.Count);\n            Assert.Contains(\"ClassA.Method1\", benchmarks);\n            Assert.Contains(\"ClassA.Method2\", benchmarks);\n        }\n\n        [Fact]\n        public void CanNotSelectClassesUsingTypeNames()\n        {\n            var benchmarks = Filter(\n                [typeof(ClassA), typeof(ClassB)],\n                [\"--filter\", \"ClassC\", \"ClassA\"]);\n\n            Assert.Empty(benchmarks); // it's not supported anymore\n        }\n\n        [Fact]\n        public void CanSelectClassesWithFullName()\n        {\n            var benchmarks = Filter(\n                [typeof(ClassA), typeof(ClassB)],\n                [\"--filter\", \"BenchmarkDotNet.Tests.ClassC*\", \"BenchmarkDotNet.Tests.ClassA*\"]);\n\n            // ClassC not matched as it has NO methods with the [Benchmark] attribute\n            Assert.Equal(2, benchmarks.Count);\n            Assert.Contains(\"ClassA.Method1\", benchmarks);\n            Assert.Contains(\"ClassA.Method2\", benchmarks);\n        }\n\n        [Fact]\n        public void CanSelectClassesUsingPattern()\n        {\n            var benchmarks = Filter(\n                [typeof(ClassA), typeof(ClassB)],\n                [\"--filter\", \"BenchmarkDotNet.Tests.Class*A*\"]);\n\n            // ClassC not matched as it has NO methods with the [Benchmark] attribute\n            Assert.Equal(2, benchmarks.Count);\n            Assert.Contains(\"ClassA.Method1\", benchmarks);\n            Assert.Contains(\"ClassA.Method2\", benchmarks);\n        }\n\n        [Fact]\n        public void CanSelectAttributes()\n        {\n            var benchmarks = Filter(\n                [typeof(ClassA), typeof(ClassB), typeof(NOTTests.ClassD)],\n                [\"--attribute\", \"Run\"]);\n\n            Assert.Equal(3, benchmarks.Count);\n            Assert.Contains(\"ClassA.Method1\", benchmarks);\n            Assert.Contains(\"ClassA.Method2\", benchmarks);\n            Assert.Contains(\"ClassD.Method1\", benchmarks);\n        }\n\n        [Fact]\n        public void CanSelectAttributesWithFullName()\n        {\n            var benchmarks = Filter(\n                [typeof(ClassA), typeof(ClassB), typeof(NOTTests.ClassD)],\n                [\"--attribute\", \"DontRunAttribute\"]);\n\n            Assert.Equal(4, benchmarks.Count);\n            Assert.Contains(\"ClassB.Method1\", benchmarks);\n            Assert.Contains(\"ClassB.Method2\", benchmarks);\n            Assert.Contains(\"ClassB.Method3\", benchmarks);\n            Assert.Contains(\"ClassD.Method2\", benchmarks);\n        }\n\n        [Fact]\n        public void CanSelectNamespaces()\n        {\n            var benchmarks = Filter(\n                [typeof(ClassA), typeof(ClassB), typeof(NOTTests.ClassD)],\n                [\"--filter\", \"BenchmarkDotNet.Tests*\"]);\n\n            Assert.Equal(5, benchmarks.Count);\n            Assert.Contains(\"ClassA.Method1\", benchmarks);\n            Assert.Contains(\"ClassA.Method2\", benchmarks);\n            Assert.Contains(\"ClassB.Method1\", benchmarks);\n            Assert.Contains(\"ClassB.Method2\", benchmarks);\n            Assert.Contains(\"ClassB.Method3\", benchmarks);\n        }\n\n        [Fact]\n        public void ClassAndMethodsCanCombined()\n        {\n            var benchmarks = Filter(\n                [typeof(ClassA), typeof(ClassB), typeof(NOTTests.ClassD)],\n                [\"--filter\", \"*ClassA.Method2\", \"*ClassA.Method3\"]);\n\n            Assert.Single(benchmarks);\n            Assert.Contains(\"ClassA.Method2\", benchmarks);\n        }\n\n        [Fact]\n        public void MethodCanBeFilteredByParameters()\n        {\n            var benchmarks = Filter(\n                [typeof(ClassA), typeof(ClassB), typeof(ClassE), typeof(NOTTests.ClassD)],\n                [\"--filter\", \"BenchmarkDotNet.Tests.ClassE.Method1(value: 0)\"]);\n\n            Assert.Single(benchmarks);\n            Assert.Contains(\"ClassE.Method1\", benchmarks);\n        }\n\n        [Fact]\n        public void GenericTypesCanBeFilteredByDisplayName()\n        {\n            var benchmarks = Filter(\n                [typeof(SomeGeneric<>)],\n                [\"--filter\", \"*SomeGeneric<Int32>*\"]);\n\n            Assert.Single(benchmarks);\n            Assert.Contains(\"SomeGeneric<Int32>.Create\", benchmarks);\n        }\n\n        private HashSet<string> Filter(Type[] types, string[] args, ILogger? logger = null)\n        {\n            var nonNullLogger = logger ?? new OutputLogger(Output);\n\n            var config = ConfigParser.Parse(args, nonNullLogger);\n\n            var runnableTypes = TypeFilter.GetTypesWithRunnableBenchmarks(types, [], nonNullLogger);\n\n            return new HashSet<string>(TypeFilter.Filter(config.config!, runnableTypes.runnable)\n                .SelectMany(runInfo => runInfo.BenchmarksCases)\n                .Select(benchmark => $\"{benchmark.Descriptor.Type.GetDisplayName()}.{benchmark.Descriptor.WorkloadMethod.Name}\"));\n        }\n    }\n}\n\nnamespace BenchmarkDotNet.Tests\n{\n    public class RunAttribute : Attribute { }\n\n    public class DontRunAttribute : Attribute { }\n\n    [Run]\n    public class ClassA\n    {\n        [Benchmark]\n        public void Method1() { }\n\n        [Benchmark]\n        public void Method2() { }\n    }\n\n    [DontRun]\n    public class ClassB\n    {\n        [Benchmark]\n        public void Method1() { }\n\n        [Benchmark]\n        public void Method2() { }\n\n        [Benchmark]\n        public void Method3() { }\n    }\n\n    public class ClassC\n    {\n        // None of these methods are actually Benchmarks!!\n        [UsedImplicitly]\n        public void Method1() { }\n\n        [UsedImplicitly]\n        public void Method2() { }\n\n        [UsedImplicitly]\n        public void Method3() { }\n    }\n\n    [GenericTypeArguments(typeof(int))]\n    [GenericTypeArguments(typeof(string))]\n    public class SomeGeneric<T>\n    {\n        [Benchmark]\n        public T Create() => Activator.CreateInstance<T>();\n    }\n\n    [Run]\n    public class ClassE\n    {\n        public static IEnumerable<object> Values =>\n        [\n            uint.MinValue,\n            (uint)12345, // same value used by other tests to compare the perf\n            uint.MaxValue,\n        ];\n\n        [Benchmark]\n        [ArgumentsSource(nameof(Values))]\n        public string Method1(uint value) => value.ToString();\n    }\n}\n\nnamespace BenchmarkDotNet.NOTTests\n{\n    public class ClassD\n    {\n        [Run]\n        [Benchmark]\n        public void Method1() { }\n\n        [DontRun]\n        [Benchmark]\n        public void Method2() { }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Validators/CompilationValidatorTests.cs",
    "content": "﻿using BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Parameters;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Validators;\nusing System;\nusing System.Linq;\nusing System.Reflection;\nusing System.Reflection.Emit;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests.Validators\n{\n    public class CompilationValidatorTests\n    {\n        [Fact]\n        public void BenchmarkedMethodNameMustNotContainWhitespaces()\n        {\n            Delegate method = BuildDummyMethod<int>(\"Has Some Whitespaces\");\n\n            var config = new ManualConfig().CreateImmutableConfig();\n            var parameters = new ValidationParameters(\n                [\n                    BenchmarkCase.Create(\n                        new Descriptor(typeof(CompilationValidatorTests), method.Method),\n                        Job.Dry,\n                        ParameterInstances.Empty,\n                        config\n                        )\n                ], config);\n\n            var errors = CompilationValidator.FailOnError.Validate(parameters).Select(e => e.Message);\n\n            Assert.Contains(errors,\n                s => s.Equals(\n                    \"Benchmarked method `Has Some Whitespaces` contains illegal character(s) or uses C# keyword. Please use `[<Benchmark(Description = \\\"Custom name\\\")>]` to set custom display name.\"));\n        }\n\n        [Fact]\n        public void BenchmarkedMethodNameMustNotUseCsharpKeywords()\n        {\n            Delegate method = BuildDummyMethod<int>(\"typeof\");\n\n            var config = ManualConfig.CreateEmpty().CreateImmutableConfig();\n            var parameters = new ValidationParameters(\n                [\n                    BenchmarkCase.Create(\n                        new Descriptor(typeof(CompilationValidatorTests), method.Method),\n                        Job.Dry,\n                        ParameterInstances.Empty,\n                        config)\n                ], config);\n\n            var errors = CompilationValidator.FailOnError.Validate(parameters).Select(e => e.Message);\n\n            Assert.Contains(errors,\n                s => s.Equals(\n                    \"Benchmarked method `typeof` contains illegal character(s) or uses C# keyword. Please use `[<Benchmark(Description = \\\"Custom name\\\")>]` to set custom display name.\"));\n        }\n\n        [Theory]\n        /* BenchmarkDotNet can only benchmark public unsealed classes*/\n        [InlineData(typeof(BenchMarkPublicClass), false)]\n        [InlineData(typeof(BenchMarkPublicClass.PublicNestedClass), false)]\n        [InlineData(typeof(SealedClass.PublicNestedClass), false)]\n        [InlineData(typeof(OuterClass.PublicNestedClass), true)]\n        [InlineData(typeof(SealedClass), true)]\n        [InlineData(typeof(MyPrivateClass), true)]\n        [InlineData(typeof(MyPublicProtectedClass), true)]\n        [InlineData(typeof(MyPrivateProtectedClass), true)]\n        [InlineData(typeof(MyProtectedInternalClass), true)]\n        [InlineData(typeof(MyInternalClass), true)]\n        [InlineData(typeof(OuterClass), true)]\n        [InlineData(typeof(OuterClass.InternalNestedClass), true)]\n        [InlineData(typeof(BenchMarkPublicClass.InternalNestedClass), true)]\n        /* Generics Remaining */\n        public void Benchmark_Class_Modifers_Must_Be_Public(Type type, bool hasErrors)\n        {\n            var validationErrors = CompilationValidator.FailOnError.Validate(BenchmarkConverter.TypeToBenchmarks(type));\n\n            Assert.Equal(hasErrors, validationErrors.Any());\n        }\n\n        [Theory]\n        [InlineData(typeof(BenchmarkClassWithStaticMethod), true)]\n        [InlineData(typeof(BenchmarkClass<PublicClass>), false)]\n        public void Benchmark_Class_Methods_Must_Be_Non_Static(Type type, bool hasErrors)\n        {\n            var validationErrors = CompilationValidator.FailOnError.Validate(BenchmarkConverter.TypeToBenchmarks(type));\n\n            Assert.Equal(hasErrors, validationErrors.Any());\n        }\n\n        [Theory]\n        [InlineData(typeof(PublicClass), false)]\n        [InlineData(typeof(PublicClass.PublicNestedClass), false)]\n        [InlineData(typeof(PrivateClass), true)]\n        [InlineData(typeof(PrivateNestedClass), true)]\n        [InlineData(typeof(InternalClass), true)]\n        [InlineData(typeof(InternalClass.InternalNestedClass), true)]\n        [InlineData(typeof(PrivateProtectedClass), true)]\n        [InlineData(typeof(PrivateProtectedNestedClass), true)]\n        [InlineData(typeof(ProtectedInternalClass), true)]\n        [InlineData(typeof(ProtectedInternalClass.ProtectedInternalNestedClass), true)]\n        public void Benchmark_Class_Generic_Argument_Must_Be_Public(Type type, bool hasErrors)\n        {\n            // Arrange\n            var constructed = typeof(BenchmarkClass<>).MakeGenericType(type);\n\n            // Act\n            var validationErrors = CompilationValidator.FailOnError.Validate(BenchmarkConverter.TypeToBenchmarks(constructed))\n                                                               .ToList();\n\n            // Assert\n            Assert.Equal(hasErrors, validationErrors.Any());\n        }\n\n        private static Delegate BuildDummyMethod<T>(string name)\n        {\n            var dynamicMethod = new DynamicMethod(\n                name,\n                returnType: typeof(T),\n                parameterTypes: [typeof(T)]);\n\n            var cilGenerator = dynamicMethod.GetILGenerator();\n            cilGenerator.Emit(OpCodes.Ldarg_0); // load the argument\n            cilGenerator.Emit(OpCodes.Ret); // return whatever it is\n\n            return dynamicMethod.CreateDelegate(typeof(Func<T, T>));\n        }\n\n        private class PrivateNestedClass { }\n        private protected class PrivateProtectedNestedClass { }\n        private class PrivateClass { }\n        private protected class PrivateProtectedClass { }\n        protected internal class ProtectedInternalClass\n        {\n            protected internal class ProtectedInternalNestedClass { }\n        }\n\n        private class MyPrivateClass{ [Benchmark] public void PublicMethod(){} }\n\n        protected class MyPublicProtectedClass{ [Benchmark] public void PublicMethod(){} }\n\n        private protected class MyPrivateProtectedClass{ [Benchmark] public void PublicMethod(){} }\n\n        internal class MyInternalClass{ [Benchmark] public void PublicMethod(){} }\n\n        protected internal class MyProtectedInternalClass{ [Benchmark] public void PublicMethod() { } }\n        }\n\n    public class BenchmarkClassWithStaticMethod\n    {\n        [Benchmark]\n        public static void StaticMethod() { }\n    }\n\n    public class BenchmarkClass<T> where T : new()\n    {\n        [Benchmark]\n        public T New() => new T();\n    }\n\n    public class PublicClass\n    {\n        public class PublicNestedClass { }\n    }\n\n    internal class InternalClass\n    {\n        internal class InternalNestedClass { }\n    }\n\n    public sealed class SealedClass\n    {\n        [Benchmark] public void PublicMethod() { }\n\n        public class PublicNestedClass { [Benchmark] public void PublicMethod() { } }\n    }\n\n    internal class OuterClass\n    {\n        [Benchmark] public void PublicMethod(){}\n\n        internal class InternalNestedClass { [Benchmark] public void PublicMethod() { } }\n\n        public class PublicNestedClass { [Benchmark] public void PublicMethod() { } }\n    }\n\n    public class BenchMarkPublicClass\n    {\n        [Benchmark] public void PublicMethod(){}\n\n        public class PublicNestedClass { [Benchmark] public void PublicMethod() { } }\n\n        internal class InternalNestedClass { [Benchmark] public void PublicMethod() { } }\n    }\n}\n"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Validators/DeferredExecutionValidatorTests.cs",
    "content": "﻿using System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Validators;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests.Validators\n{\n    public class DeferredExecutionValidatorTests\n    {\n        public class ReturningIEnumerable\n        {\n            private IEnumerable field = Enumerable.Empty<int>();\n\n            [Benchmark] public IEnumerable Benchmark() => field;\n            [Benchmark] public Task<IEnumerable> BenchmarkTask() => Task.FromResult(field);\n            [Benchmark] public ValueTask<IEnumerable> BenchmarkValueTask() => new ValueTask<IEnumerable>(field);\n            [Benchmark] public ref IEnumerable BenchmarkRef() => ref field;\n            [Benchmark] public ref readonly IEnumerable BenchmarkReadOnlyRef() => ref field;\n        }\n\n        public class ReturningIEnumerableOfInt\n        {\n            private IEnumerable<int> field = [];\n\n            [Benchmark] public IEnumerable<int> Benchmark() => field;\n            [Benchmark] public Task<IEnumerable<int>> BenchmarkTask() => Task.FromResult(field);\n            [Benchmark] public ValueTask<IEnumerable<int>> BenchmarkValueTask() => new ValueTask<IEnumerable<int>>(field);\n            [Benchmark] public ref IEnumerable<int> BenchmarkRef() => ref field;\n            [Benchmark] public ref readonly IEnumerable<int> BenchmarkReadOnlyRef() => ref field;\n        }\n\n        public class ReturningIQueryable\n        {\n            private IQueryable field = Enumerable.Empty<int>().AsQueryable();\n\n            [Benchmark] public IQueryable Benchmark() => field;\n            [Benchmark] public Task<IQueryable> BenchmarkTask() => Task.FromResult(field);\n            [Benchmark] public ValueTask<IQueryable> BenchmarkValueTask() => new ValueTask<IQueryable>(field);\n            [Benchmark] public ref IQueryable BenchmarkRef() => ref field;\n            [Benchmark] public ref readonly IQueryable BenchmarkReadOnlyRef() => ref field;\n        }\n\n        public class ReturningIQueryableOfInt\n        {\n            private IQueryable<int> field = Enumerable.Empty<int>().AsQueryable();\n\n            [Benchmark] public IQueryable<int> Benchmark() => Enumerable.Empty<int>().AsQueryable();\n            [Benchmark] public Task<IQueryable<int>> BenchmarkTask() => Task.FromResult(field);\n            [Benchmark] public ValueTask<IQueryable<int>> BenchmarkValueTask() => new ValueTask<IQueryable<int>>(field);\n            [Benchmark] public ref IQueryable<int> BenchmarkRef() => ref field;\n            [Benchmark] public ref readonly IQueryable<int> BenchmarkReadOnlyRef() => ref field;\n        }\n\n        public class ReturningLazyOfInt\n        {\n            private Lazy<int> field = new Lazy<int>(() => 0);\n\n            [Benchmark] public Lazy<int> Benchmark() => field;\n            [Benchmark] public Task<Lazy<int>> BenchmarkTask() => Task.FromResult(field);\n            [Benchmark] public ValueTask<Lazy<int>> BenchmarkValueTask() => new ValueTask<Lazy<int>>(field);\n            [Benchmark] public ref Lazy<int> BenchmarkRef() => ref field;\n            [Benchmark] public ref readonly Lazy<int> BenchmarkReadOnlyRef() => ref field;\n        }\n\n        [Theory]\n        [InlineData(typeof(ReturningIEnumerable))]\n        [InlineData(typeof(ReturningIEnumerableOfInt))]\n        [InlineData(typeof(ReturningIQueryable))]\n        [InlineData(typeof(ReturningIQueryableOfInt))]\n        [InlineData(typeof(ReturningLazyOfInt))]\n        public void DeferredExecutionMeansError(Type returningDeferredExecutionResult)\n        {\n            var benchmarks = BenchmarkConverter.TypeToBenchmarks(returningDeferredExecutionResult);\n\n            var validationErrors = DeferredExecutionValidator.FailOnError.Validate(benchmarks).ToArray();\n\n            Assert.Equal(5, validationErrors.Count(error => error.IsCritical));\n        }\n\n        public class ReturningArray\n        {\n            private int[] field = [];\n\n            [Benchmark] public int[] Benchmark() => field;\n            [Benchmark] public Task<int[]> BenchmarkTask() => Task.FromResult(field);\n            [Benchmark] public ValueTask<int[]> BenchmarkValueTask() => new ValueTask<int[]>(field);\n            [Benchmark] public ref int[] BenchmarkRef() => ref field;\n            [Benchmark] public ref readonly int[] BenchmarkReadOnlyRef() => ref field;\n        }\n\n        public class ReturningDictionary\n        {\n            private Dictionary<int, int> field = [];\n\n            [Benchmark] public Dictionary<int, int> Benchmark() => field;\n            [Benchmark] public Task<Dictionary<int, int>> BenchmarkTask() => Task.FromResult(field);\n            [Benchmark] public ValueTask<Dictionary<int, int>> BenchmarkValueTask() => new ValueTask<Dictionary<int, int>>(field);\n            [Benchmark] public ref Dictionary<int, int> BenchmarkRef() => ref field;\n            [Benchmark] public ref readonly Dictionary<int, int> BenchmarkReadOnlyRef() => ref field;\n        }\n\n        [Theory]\n        [InlineData(typeof(ReturningArray))]\n        [InlineData(typeof(ReturningDictionary))]\n        public void MaterializedCollectionsAreOk(Type returningMaterializedResult)\n        {\n            var benchmarks = BenchmarkConverter.TypeToBenchmarks(returningMaterializedResult);\n\n            var validationErrors = DeferredExecutionValidator.FailOnError.Validate(benchmarks).ToArray();\n\n            Assert.Empty(validationErrors);\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Validators/ExecutionValidatorTests.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing System.Threading.Tasks.Sources;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Validators;\nusing JetBrains.Annotations;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests.Validators\n{\n    public class ExecutionValidatorTests\n    {\n        [Fact]\n        public void FailingConstructorsAreDiscovered()\n        {\n            var validationErrors = ExecutionValidator.FailOnError.Validate(BenchmarkConverter.TypeToBenchmarks(typeof(FailingConstructor))).ToList();\n\n            Assert.NotEmpty(validationErrors);\n            Assert.StartsWith(\"Unable to create instance of FailingConstructor\", validationErrors.Single().Message);\n            Assert.Contains(\"This one fails\", validationErrors.Single().Message);\n        }\n\n        public class FailingConstructor\n        {\n            public FailingConstructor() => throw new Exception(\"This one fails\");\n\n            [Benchmark]\n            public void NonThrowing() { }\n        }\n\n        [Fact]\n        public void FailingGlobalSetupsAreDiscovered()\n        {\n            var validationErrors = ExecutionValidator.FailOnError.Validate(BenchmarkConverter.TypeToBenchmarks(typeof(FailingGlobalSetup))).ToList();\n\n            Assert.NotEmpty(validationErrors);\n            Assert.StartsWith(\"Failed to execute [GlobalSetup]\", validationErrors.Single().Message);\n            Assert.Contains(\"This one fails\", validationErrors.Single().Message);\n        }\n\n        public class FailingGlobalSetup\n        {\n            [GlobalSetup]\n            public void Failing() => throw new Exception(\"This one fails\");\n\n            [Benchmark]\n            public void NonThrowing() { }\n        }\n\n        [Fact]\n        public void FailingGlobalCleanupsAreDiscovered()\n        {\n            var validationErrors = ExecutionValidator.FailOnError.Validate(BenchmarkConverter.TypeToBenchmarks(typeof(FailingGlobalCleanup))).ToList();\n\n            Assert.NotEmpty(validationErrors);\n            Assert.StartsWith(\"Failed to execute [GlobalCleanup]\", validationErrors.Single().Message);\n            Assert.Contains(\"This one fails\", validationErrors.Single().Message);\n        }\n\n        public class FailingGlobalCleanup\n        {\n            [GlobalCleanup]\n            public void Failing() => throw new Exception(\"This one fails\");\n\n            [Benchmark]\n            public void NonThrowing() { }\n        }\n\n        [Fact]\n        public void MultipleGlobalSetupsAreDiscovered()\n        {\n            var validationErrors = ExecutionValidator.FailOnError.Validate(BenchmarkConverter.TypeToBenchmarks(typeof(MultipleGlobalSetups))).ToList();\n\n            Assert.NotEmpty(validationErrors);\n            Assert.StartsWith(\"Only single [GlobalSetup] method is allowed per type\", validationErrors.Single().Message);\n        }\n\n        public class MultipleGlobalSetups\n        {\n            [GlobalSetup]\n            public void First() { }\n\n            [GlobalSetup]\n            public void Second() { }\n\n            [Benchmark]\n            public void NonThrowing() { }\n        }\n\n        [Fact]\n        public void MultipleGlobalCleanupsAreDiscovered()\n        {\n            var validationErrors = ExecutionValidator.FailOnError.Validate(BenchmarkConverter.TypeToBenchmarks(typeof(MultipleGlobalCleanups))).ToList();\n\n            Assert.NotEmpty(validationErrors);\n            Assert.StartsWith(\"Only single [GlobalCleanup] method is allowed per type\", validationErrors.Single().Message);\n        }\n\n        public class MultipleGlobalCleanups\n        {\n            [GlobalCleanup]\n            public void First() { }\n\n            [GlobalCleanup]\n            public void Second() { }\n\n            [Benchmark]\n            public void NonThrowing() { }\n        }\n\n        [Fact]\n        public void VirtualGlobalSetupsAreSupported()\n        {\n            Assert.False(OverridesGlobalSetup.WasCalled);\n            var validationErrors = ExecutionValidator.FailOnError.Validate(BenchmarkConverter.TypeToBenchmarks(typeof(OverridesGlobalSetup)));\n\n            Assert.True(OverridesGlobalSetup.WasCalled);\n            Assert.Empty(validationErrors);\n        }\n\n        public class BaseClassWithThrowingGlobalSetup\n        {\n            [GlobalSetup]\n            public virtual void GlobalSetup() => throw new Exception(\"Should not be executed when overridden\");\n\n            [Benchmark]\n            public void NonThrowing() { }\n        }\n\n        public class OverridesGlobalSetup : BaseClassWithThrowingGlobalSetup\n        {\n            public static bool WasCalled;\n\n            [GlobalSetup]\n            public override void GlobalSetup() => WasCalled = true;\n        }\n\n        [Fact]\n        public void VirtualGlobalCleanupsAreSupported()\n        {\n            Assert.False(OverridesGlobalCleanup.WasCalled);\n            var validationErrors = ExecutionValidator.FailOnError.Validate(BenchmarkConverter.TypeToBenchmarks(typeof(OverridesGlobalCleanup)));\n\n            Assert.True(OverridesGlobalCleanup.WasCalled);\n            Assert.Empty(validationErrors);\n        }\n\n        public class BaseClassWithThrowingGlobalCleanup\n        {\n            [GlobalCleanup]\n            public virtual void GlobalCleanup() => throw new Exception(\"Should not be executed when overridden\");\n\n            [Benchmark]\n            public void NonThrowing() { }\n        }\n\n        public class OverridesGlobalCleanup : BaseClassWithThrowingGlobalCleanup\n        {\n            public static bool WasCalled;\n\n            [GlobalCleanup]\n            public override void GlobalCleanup() => WasCalled = true;\n        }\n\n        [Fact]\n        public void NonFailingGlobalSetupsAreOmitted()\n        {\n            var validationErrors = ExecutionValidator.FailOnError.Validate(BenchmarkConverter.TypeToBenchmarks(typeof(GlobalSetupThatRequiresParamsToBeSetFirst)));\n\n            Assert.Empty(validationErrors);\n        }\n\n        public class GlobalSetupThatRequiresParamsToBeSetFirst\n        {\n            [Params(100)]\n            [UsedImplicitly]\n            public int Field;\n\n            [GlobalSetup]\n            public void Failing()\n            {\n                if (Field == default)\n                    throw new Exception(\"This should have never happened\");\n            }\n\n            [Benchmark]\n            public void NonThrowing() { }\n        }\n\n        [Fact]\n        public void NonFailingGlobalCleanupsAreOmitted()\n        {\n            var validationErrors = ExecutionValidator.FailOnError.Validate(BenchmarkConverter.TypeToBenchmarks(typeof(GlobalCleanupThatRequiresParamsToBeSetFirst)));\n\n            Assert.Empty(validationErrors);\n        }\n\n        public class GlobalCleanupThatRequiresParamsToBeSetFirst\n        {\n            [Params(100)]\n            [UsedImplicitly]\n            public int Field;\n\n            [GlobalCleanup]\n            public void Failing()\n            {\n                if (Field == default)\n                    throw new Exception(\"This should have never happened\");\n            }\n\n            [Benchmark]\n            public void NonThrowing() { }\n        }\n\n        [Fact]\n        public void MissingParamsAttributeThatMakesGlobalSetupsFailAreDiscovered()\n        {\n            var validationErrors = ExecutionValidator.FailOnError\n                .Validate(BenchmarkConverter.TypeToBenchmarks(typeof(FailingGlobalSetupWhichShouldHaveHadParamsForField)))\n                .ToList();\n\n            Assert.NotEmpty(validationErrors);\n            Assert.StartsWith(\"Failed to execute [GlobalSetup]\", validationErrors.Single().Message);\n        }\n\n        public class FailingGlobalSetupWhichShouldHaveHadParamsForField\n        {\n            [UsedImplicitly]\n            public int Field;\n\n            [GlobalSetup]\n            public void Failing()\n            {\n                if (Field == default)\n                    throw new Exception(\"Field is missing Params attribute\");\n            }\n\n            [Benchmark]\n            public void NonThrowing() { }\n        }\n\n        [Fact]\n        public void MissingParamsAttributeThatMakesGlobalCleanupsFailAreDiscovered()\n        {\n            var validationErrors = ExecutionValidator.FailOnError\n                .Validate(BenchmarkConverter.TypeToBenchmarks(typeof(FailingGlobalCleanupWhichShouldHaveHadParamsForField)))\n                .ToList();\n\n            Assert.NotEmpty(validationErrors);\n            Assert.StartsWith(\"Failed to execute [GlobalCleanup]\", validationErrors.Single().Message);\n        }\n\n        public class FailingGlobalCleanupWhichShouldHaveHadParamsForField\n        {\n            [UsedImplicitly]\n            public int Field;\n\n            [GlobalCleanup]\n            public void Failing()\n            {\n                if (Field == default)\n                    throw new Exception(\"Field is missing Params attribute\");\n            }\n\n            [Benchmark]\n            public void NonThrowing() { }\n        }\n\n        [Fact]\n        public void NonPublicFieldsWithParamsAreDiscovered()\n        {\n            var validationErrors = ExecutionValidator.FailOnError\n                .Validate(BenchmarkConverter.TypeToBenchmarks(typeof(NonPublicFieldWithParams)))\n                .ToList();\n\n            Assert.NotEmpty(validationErrors);\n            Assert.StartsWith(\"Fields marked with [Params] must be public\", validationErrors.Single().Message);\n        }\n\n        public class NonPublicFieldWithParams\n        {\n#pragma warning disable CS0649, BDN1202\n            [Params(1)]\n            [UsedImplicitly]\n            internal int Field;\n#pragma warning restore CS0649, BDN1202\n\n            [Benchmark]\n            public void NonThrowing() { }\n        }\n\n        [Fact]\n        public void FieldsWithoutParamsValuesAreDiscovered()\n        {\n            Assert.Empty(BenchmarkConverter.TypeToBenchmarks(typeof(FieldsWithoutParamsValues)).BenchmarksCases);\n        }\n\n        public class FieldsWithoutParamsValues\n        {\n#pragma warning disable BDN1300\n            [Params]\n#pragma warning restore BDN1300\n            [UsedImplicitly]\n            public int FieldWithoutValuesSpecified;\n\n            [Benchmark]\n            public void NonThrowing() { }\n        }\n\n        [Fact]\n        public void NonFailingBenchmarksAreOmitted()\n        {\n            var validationErrors = ExecutionValidator.FailOnError.Validate(BenchmarkConverter.TypeToBenchmarks(typeof(NonFailingBenchmark)));\n\n            Assert.Empty(validationErrors);\n        }\n\n        public class NonFailingBenchmark\n        {\n            [Benchmark]\n            public void NonThrowing() { }\n        }\n\n        [Fact]\n        public void FailingBenchmarksAreDiscovered()\n        {\n            var validationErrors = ExecutionValidator.FailOnError.Validate(BenchmarkConverter.TypeToBenchmarks(typeof(FailingBenchmark))).ToList();\n\n            Assert.NotEmpty(validationErrors);\n            Assert.Contains(validationErrors, error => error.Message.Contains(\"This benchmark throws\"));\n        }\n\n        public class FailingBenchmark\n        {\n            [Benchmark]\n            public void Throwing() => throw new Exception(\"This benchmark throws\");\n        }\n\n        [Fact]\n        public void MultipleParamsDoNotMultiplyGlobalSetup()\n        {\n            var validationErrors = ExecutionValidator.FailOnError.Validate(BenchmarkConverter.TypeToBenchmarks(typeof(MultipleParamsAndSingleGlobalSetup)));\n\n            Assert.Empty(validationErrors);\n        }\n\n        public class MultipleParamsAndSingleGlobalSetup\n        {\n            [Params(1, 2)]\n            [UsedImplicitly]\n            public int Field;\n\n            [GlobalSetup]\n            public void Single() { }\n\n            [Benchmark]\n            public void NonThrowing() { }\n        }\n\n        [Fact]\n        public void AsyncTaskGlobalSetupIsExecuted()\n        {\n            var validationErrors = ExecutionValidator.FailOnError.Validate(BenchmarkConverter.TypeToBenchmarks(typeof(AsyncTaskGlobalSetup))).ToList();\n\n            Assert.True(AsyncTaskGlobalSetup.WasCalled);\n            Assert.Empty(validationErrors);\n        }\n\n        public class AsyncTaskGlobalSetup\n        {\n            public static bool WasCalled;\n\n            [GlobalSetup]\n            public async Task GlobalSetup()\n            {\n                await Task.Delay(1);\n\n                WasCalled = true;\n            }\n\n            [Benchmark]\n            public void NonThrowing() { }\n        }\n\n        [Fact]\n        public void AsyncTaskGlobalCleanupIsExecuted()\n        {\n            var validationErrors = ExecutionValidator.FailOnError.Validate(BenchmarkConverter.TypeToBenchmarks(typeof(AsyncTaskGlobalCleanup))).ToList();\n\n            Assert.True(AsyncTaskGlobalCleanup.WasCalled);\n            Assert.Empty(validationErrors);\n        }\n\n        public class AsyncTaskGlobalCleanup\n        {\n            public static bool WasCalled;\n\n            [GlobalCleanup]\n            public async Task GlobalCleanup()\n            {\n                await Task.Delay(1);\n\n                WasCalled = true;\n            }\n\n            [Benchmark]\n            public void NonThrowing() { }\n        }\n\n        [Fact]\n        public void AsyncGenericTaskGlobalSetupIsExecuted()\n        {\n            var validationErrors = ExecutionValidator.FailOnError.Validate(BenchmarkConverter.TypeToBenchmarks(typeof(AsyncGenericTaskGlobalSetup))).ToList();\n\n            Assert.True(AsyncGenericTaskGlobalSetup.WasCalled);\n            Assert.Empty(validationErrors);\n        }\n\n        public class AsyncGenericTaskGlobalSetup\n        {\n            public static bool WasCalled;\n\n            [GlobalSetup]\n            public async Task<int> GlobalSetup()\n            {\n                await Task.Delay(1);\n\n                WasCalled = true;\n\n                return 42;\n            }\n\n            [Benchmark]\n            public void NonThrowing() { }\n        }\n\n        [Fact]\n        public void AsyncGenericTaskGlobalCleanupIsExecuted()\n        {\n            var validationErrors = ExecutionValidator.FailOnError.Validate(BenchmarkConverter.TypeToBenchmarks(typeof(AsyncGenericTaskGlobalCleanup))).ToList();\n\n            Assert.True(AsyncGenericTaskGlobalCleanup.WasCalled);\n            Assert.Empty(validationErrors);\n        }\n\n        public class AsyncGenericTaskGlobalCleanup\n        {\n            public static bool WasCalled;\n\n            [GlobalCleanup]\n            public async Task<int> GlobalCleanup()\n            {\n                await Task.Delay(1);\n\n                WasCalled = true;\n\n                return 42;\n            }\n\n            [Benchmark]\n            public void NonThrowing() { }\n        }\n\n        [Fact]\n        public void AsyncValueTaskGlobalSetupIsExecuted()\n        {\n            var validationErrors = ExecutionValidator.FailOnError.Validate(BenchmarkConverter.TypeToBenchmarks(typeof(AsyncValueTaskGlobalSetup))).ToList();\n\n            Assert.True(AsyncValueTaskGlobalSetup.WasCalled);\n            Assert.Empty(validationErrors);\n        }\n\n        public class AsyncValueTaskGlobalSetup\n        {\n            public static bool WasCalled;\n\n            [GlobalSetup]\n            public async ValueTask GlobalSetup()\n            {\n                await Task.Delay(1);\n\n                WasCalled = true;\n            }\n\n            [Benchmark]\n            public void NonThrowing() { }\n        }\n\n        [Fact]\n        public void AsyncValueTaskGlobalCleanupIsExecuted()\n        {\n            var validationErrors = ExecutionValidator.FailOnError.Validate(BenchmarkConverter.TypeToBenchmarks(typeof(AsyncValueTaskGlobalCleanup))).ToList();\n\n            Assert.True(AsyncValueTaskGlobalCleanup.WasCalled);\n            Assert.Empty(validationErrors);\n        }\n\n        public class AsyncValueTaskGlobalCleanup\n        {\n            public static bool WasCalled;\n\n            [GlobalCleanup]\n            public async ValueTask GlobalCleanup()\n            {\n                await Task.Delay(1);\n\n                WasCalled = true;\n            }\n\n            [Benchmark]\n            public void NonThrowing() { }\n        }\n\n        [Fact]\n        public void AsyncGenericValueTaskGlobalSetupIsExecuted()\n        {\n            var validationErrors = ExecutionValidator.FailOnError.Validate(BenchmarkConverter.TypeToBenchmarks(typeof(AsyncGenericValueTaskGlobalSetup))).ToList();\n\n            Assert.True(AsyncGenericValueTaskGlobalSetup.WasCalled);\n            Assert.Empty(validationErrors);\n        }\n\n        public class AsyncGenericValueTaskGlobalSetup\n        {\n            public static bool WasCalled;\n\n            [GlobalSetup]\n            public async ValueTask<int> GlobalSetup()\n            {\n                await Task.Delay(1);\n\n                WasCalled = true;\n\n                return 42;\n            }\n\n            [Benchmark]\n            public void NonThrowing() { }\n        }\n\n        [Fact]\n        public void AsyncGenericValueTaskGlobalCleanupIsExecuted()\n        {\n            var validationErrors = ExecutionValidator.FailOnError.Validate(BenchmarkConverter.TypeToBenchmarks(typeof(AsyncGenericValueTaskGlobalCleanup))).ToList();\n\n            Assert.True(AsyncGenericValueTaskGlobalCleanup.WasCalled);\n            Assert.Empty(validationErrors);\n        }\n\n        public class AsyncGenericValueTaskGlobalCleanup\n        {\n            public static bool WasCalled;\n\n            [GlobalCleanup]\n            public async ValueTask<int> GlobalCleanup()\n            {\n                await Task.Delay(1);\n\n                WasCalled = true;\n\n                return 42;\n            }\n\n            [Benchmark]\n            public void NonThrowing() { }\n        }\n\n        private class ValueTaskSource<T> : IValueTaskSource<T>, IValueTaskSource\n        {\n            private ManualResetValueTaskSourceCore<T> _core;\n\n            T IValueTaskSource<T>.GetResult(short token) => _core.GetResult(token);\n            void IValueTaskSource.GetResult(short token) => _core.GetResult(token);\n            ValueTaskSourceStatus IValueTaskSource<T>.GetStatus(short token) => _core.GetStatus(token);\n            ValueTaskSourceStatus IValueTaskSource.GetStatus(short token) => _core.GetStatus(token);\n            void IValueTaskSource<T>.OnCompleted(Action<object?> continuation, object? state, short token, ValueTaskSourceOnCompletedFlags flags) => _core.OnCompleted(continuation, state, token, flags);\n            void IValueTaskSource.OnCompleted(Action<object?> continuation, object? state, short token, ValueTaskSourceOnCompletedFlags flags) => _core.OnCompleted(continuation, state, token, flags);\n            public void Reset() => _core.Reset();\n            public short Token => _core.Version;\n            public void SetResult(T result) => _core.SetResult(result);\n        }\n\n        [Fact]\n        public void AsyncValueTaskBackedByIValueTaskSourceIsAwaitedProperly()\n        {\n            var validationErrors = ExecutionValidator.FailOnError.Validate(BenchmarkConverter.TypeToBenchmarks(typeof(AsyncValueTaskSource))).ToList();\n\n            Assert.True(AsyncValueTaskSource.WasCalled);\n            Assert.Empty(validationErrors);\n        }\n\n        public class AsyncValueTaskSource\n        {\n            private readonly ValueTaskSource<bool> valueTaskSource = new();\n\n            public static bool WasCalled;\n\n            [GlobalSetup]\n            public ValueTask GlobalSetup()\n            {\n                valueTaskSource.Reset();\n                Task.Delay(1).ContinueWith(_ =>\n                {\n                    WasCalled = true;\n                    valueTaskSource.SetResult(true);\n                });\n                return new ValueTask(valueTaskSource, valueTaskSource.Token);\n            }\n\n            [Benchmark]\n            public void NonThrowing() { }\n        }\n\n        [Fact]\n        public void AsyncGenericValueTaskBackedByIValueTaskSourceIsAwaitedProperly()\n        {\n            var validationErrors = ExecutionValidator.FailOnError.Validate(BenchmarkConverter.TypeToBenchmarks(typeof(AsyncGenericValueTaskSource))).ToList();\n\n            Assert.True(AsyncGenericValueTaskSource.WasCalled);\n            Assert.Empty(validationErrors);\n        }\n\n        public class AsyncGenericValueTaskSource\n        {\n            private readonly ValueTaskSource<int> valueTaskSource = new();\n\n            public static bool WasCalled;\n\n            [GlobalSetup]\n            public ValueTask<int> GlobalSetup()\n            {\n                valueTaskSource.Reset();\n                Task.Delay(1).ContinueWith(_ =>\n                {\n                    WasCalled = true;\n                    valueTaskSource.SetResult(1);\n                });\n                return new ValueTask<int>(valueTaskSource, valueTaskSource.Token);\n            }\n\n            [Benchmark]\n            public void NonThrowing() { }\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Validators/ParamsValidatorTests.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Diagnostics.CodeAnalysis;\nusing System.Linq;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Validators;\nusing Xunit;\nusing Xunit.Abstractions;\n#pragma warning disable CS0414\n\nnamespace BenchmarkDotNet.Tests.Validators\n{\n    [SuppressMessage(\"ReSharper\", \"ClassNeverInstantiated.Global\")]\n    [SuppressMessage(\"ReSharper\", \"MemberCanBePrivate.Global\")]\n    [SuppressMessage(\"ReSharper\", \"UnusedAutoPropertyAccessor.Local\")]\n    public class ParamsValidatorTests\n    {\n        private readonly ITestOutputHelper output;\n\n        public ParamsValidatorTests(ITestOutputHelper output)\n        {\n            this.output = output;\n        }\n\n        private void Check<T>(params string[] messageParts)\n        {\n            var typeToBenchmarks = BenchmarkConverter.TypeToBenchmarks(typeof(T));\n            Assert.NotEmpty(typeToBenchmarks.BenchmarksCases);\n\n            var validationErrors = ParamsValidator.FailOnError.Validate(typeToBenchmarks).ToList();\n            output.WriteLine(\"Number of validation errors: \" + validationErrors.Count);\n            foreach (var error in validationErrors)\n                output.WriteLine(\"* \" + error.Message);\n\n            Assert.Single(validationErrors);\n            foreach (string messagePart in messageParts)\n                Assert.Contains(messagePart, validationErrors.Single().Message);\n        }\n\n        private const string P = \"[Params]\";\n        private const string Pa = \"[ParamsAllValues]\";\n        private const string Ps = \"[ParamsSource]\";\n\n        [Fact] public void Const1Test() => Check<Const1>(nameof(Const1.Input), \"constant\", P);\n        [Fact] public void Const2Test() => Check<Const2>(nameof(Const2.Input), \"constant\", Pa);\n        [Fact] public void Const3Test() => Check<Const3>(nameof(Const3.Input), \"constant\", Ps);\n        [Fact] public void StaticReadonly1Test() => Check<StaticReadonly1>(nameof(StaticReadonly1.Input), \"readonly\", P);\n        [Fact] public void StaticReadonly2Test() => Check<StaticReadonly2>(nameof(StaticReadonly2.Input), \"readonly\", Pa);\n        [Fact] public void StaticReadonly3Test() => Check<StaticReadonly3>(nameof(StaticReadonly3.Input), \"readonly\", Ps);\n        [Fact] public void NonStaticReadonly1Test() => Check<NonStaticReadonly1>(nameof(NonStaticReadonly1.Input), \"readonly\", P);\n        [Fact] public void NonStaticReadonly2Test() => Check<NonStaticReadonly2>(nameof(NonStaticReadonly2.Input), \"readonly\", Pa);\n        [Fact] public void NonStaticReadonly3Test() => Check<NonStaticReadonly3>(nameof(NonStaticReadonly3.Input), \"readonly\", Ps);\n        [Fact] public void FieldMultiple1Test() => Check<FieldMultiple1>(nameof(FieldMultiple1.Input), \"single attribute\", P, Pa);\n        [Fact] public void FieldMultiple2Test() => Check<FieldMultiple2>(nameof(FieldMultiple2.Input), \"single attribute\", P, Ps);\n        [Fact] public void FieldMultiple3Test() => Check<FieldMultiple3>(nameof(FieldMultiple3.Input), \"single attribute\", Pa, Ps);\n        [Fact] public void FieldMultiple4Test() => Check<FieldMultiple4>(nameof(FieldMultiple4.Input), \"single attribute\", P, Pa, Ps);\n        [Fact] public void PropMultiple1Test() => Check<PropMultiple1>(nameof(PropMultiple1.Input), \"single attribute\", P, Pa);\n        [Fact] public void PropMultiple2Test() => Check<PropMultiple2>(nameof(PropMultiple2.Input), \"single attribute\", P, Ps);\n        [Fact] public void PropMultiple3Test() => Check<PropMultiple3>(nameof(PropMultiple3.Input), \"single attribute\", Pa, Ps);\n        [Fact] public void PropMultiple4Test() => Check<PropMultiple4>(nameof(PropMultiple4.Input), \"single attribute\", P, Pa, Ps);\n        [Fact] public void PrivateSetter1Test() => Check<PrivateSetter1>(nameof(PrivateSetter1.Input), \"setter is not public\", P);\n        [Fact] public void PrivateSetter2Test() => Check<PrivateSetter2>(nameof(PrivateSetter2.Input), \"setter is not public\", Pa);\n        [Fact] public void PrivateSetter3Test() => Check<PrivateSetter3>(nameof(PrivateSetter3.Input), \"setter is not public\", Ps);\n        [Fact] public void NoSetter1Test() => Check<NoSetter1>(nameof(NoSetter1.Input), \"no setter\", P);\n        [Fact] public void NoSetter2Test() => Check<NoSetter2>(nameof(NoSetter2.Input), \"no setter\", Pa);\n        [Fact] public void NoSetter3Test() => Check<NoSetter3>(nameof(NoSetter3.Input), \"no setter\", Ps);\n        [Fact] public void InternalField1Test() => Check<InternalField1>(nameof(InternalField1.Input), \"it's not public\", P);\n        [Fact] public void InternalField2Test() => Check<InternalField2>(nameof(InternalField2.Input), \"it's not public\", Pa);\n        [Fact] public void InternalField3Test() => Check<InternalField3>(nameof(InternalField3.Input), \"it's not public\", Ps);\n        [Fact] public void InternalProp1Test() => Check<InternalProp1>(nameof(InternalProp1.Input), \"setter is not public\", P);\n        [Fact] public void InternalProp2Test() => Check<InternalProp2>(nameof(InternalProp2.Input), \"setter is not public\", Pa);\n        [Fact] public void InternalProp3Test() => Check<InternalProp3>(nameof(InternalProp3.Input), \"setter is not public\", Ps);\n\n        public class Base\n        {\n            [Benchmark]\n            public void Foo() { }\n\n            public static IEnumerable<bool> Source() => [false, true];\n        }\n\n#pragma warning disable BDN1205\n        public class Const1 : Base\n        {\n            [Params(false, true)]\n            public const bool Input = false;\n        }\n#pragma warning restore BDN1205\n\n#pragma warning disable BDN1205\n        public class Const2 : Base\n        {\n            [ParamsAllValues]\n            public const bool Input = false;\n        }\n#pragma warning restore BDN1205\n\n#pragma warning disable BDN1205\n        public class Const3 : Base\n        {\n            [ParamsSource(nameof(Source))]\n            public const bool Input = false;\n        }\n#pragma warning restore BDN1205\n\n#pragma warning disable BDN1204\n        public class StaticReadonly1 : Base\n        {\n            [Params(false, true)]\n            public static readonly bool Input = false;\n        }\n#pragma warning restore BDN1204\n\n#pragma warning disable BDN1204\n        public class StaticReadonly2 : Base\n        {\n            [ParamsAllValues]\n            public static readonly bool Input = false;\n        }\n#pragma warning restore BDN1204\n\n#pragma warning disable BDN1204\n        public class StaticReadonly3 : Base\n        {\n            [ParamsSource(nameof(Source))]\n            public static readonly bool Input = false;\n        }\n#pragma warning restore BDN1204\n\n#pragma warning disable BDN1204\n        public class NonStaticReadonly1 : Base\n        {\n            [Params(false, true)]\n            public readonly bool Input = false;\n        }\n#pragma warning restore BDN1204\n\n#pragma warning disable BDN1204\n        public class NonStaticReadonly2 : Base\n        {\n            [ParamsAllValues]\n            public readonly bool Input = false;\n        }\n#pragma warning restore BDN1204\n\n#pragma warning disable BDN1204\n        public class NonStaticReadonly3 : Base\n        {\n            [ParamsSource(nameof(Source))]\n            public readonly bool Input = false;\n        }\n#pragma warning restore BDN1204\n\n#pragma warning disable BDN1207\n        public class PrivateSetter1 : Base\n        {\n            [Params(false, true)]\n            public bool Input { get; private set; }\n        }\n#pragma warning restore BDN1207\n\n#pragma warning disable BDN1207\n        public class PrivateSetter2 : Base\n        {\n            [ParamsAllValues]\n            public bool Input { get; private set; }\n        }\n#pragma warning restore BDN1207\n\n#pragma warning disable BDN1207\n        public class PrivateSetter3 : Base\n        {\n            [ParamsSource(nameof(Source))]\n            public bool Input { get; private set; }\n        }\n#pragma warning restore BDN1207\n\n#pragma warning disable BDN1207\n        public class NoSetter1 : Base\n        {\n            [Params(false, true)]\n            public bool Input { get; } = false;\n        }\n#pragma warning restore BDN1207\n\n#pragma warning disable BDN1207\n        public class NoSetter2 : Base\n        {\n            [ParamsAllValues]\n            public bool Input { get; } = false;\n        }\n#pragma warning restore BDN1207\n\n#pragma warning disable BDN1207\n        public class NoSetter3 : Base\n        {\n            [ParamsSource(nameof(Source))]\n            public bool Input { get; } = false;\n        }\n#pragma warning restore BDN1207\n\n#pragma warning disable BDN1202\n        public class InternalField1 : Base\n        {\n            [Params(false, true)]\n            internal bool Input = false;\n        }\n#pragma warning restore BDN1202\n\n#pragma warning disable BDN1202\n        public class InternalField2 : Base\n        {\n            [ParamsAllValues]\n            internal bool Input = false;\n        }\n#pragma warning restore BDN1202\n\n#pragma warning disable BDN1202\n        public class InternalField3 : Base\n        {\n            [ParamsSource(nameof(Source))]\n            internal bool Input = false;\n        }\n#pragma warning restore BDN1202\n\n#pragma warning disable BDN1203\n        public class InternalProp1 : Base\n        {\n            [Params(false, true)]\n            internal bool Input { get; set; }\n        }\n#pragma warning restore BDN1203\n\n#pragma warning disable BDN1203\n        public class InternalProp2 : Base\n        {\n            [ParamsAllValues]\n            internal bool Input { get; set; }\n        }\n#pragma warning restore BDN1203\n\n#pragma warning disable BDN1203\n        public class InternalProp3 : Base\n        {\n            [ParamsSource(nameof(Source))]\n            internal bool Input { get; set; }\n        }\n#pragma warning restore BDN1203\n\n#pragma warning disable BDN1200\n        public class FieldMultiple1 : Base\n        {\n            [Params(false, true)]\n            [ParamsAllValues]\n            public bool Input = false;\n        }\n#pragma warning restore BDN1200\n\n#pragma warning disable BDN1200\n        public class FieldMultiple2 : Base\n        {\n            [Params(false, true)]\n            [ParamsSource(nameof(Source))]\n            public bool Input = false;\n        }\n#pragma warning restore BDN1200\n\n#pragma warning disable BDN1200\n        public class FieldMultiple3 : Base\n        {\n            [ParamsAllValues]\n            [ParamsSource(nameof(Source))]\n            public bool Input = false;\n        }\n#pragma warning restore BDN1200\n\n#pragma warning disable BDN1200\n        public class FieldMultiple4 : Base\n        {\n            [Params(false, true)]\n            [ParamsAllValues]\n            [ParamsSource(nameof(Source))]\n            public bool Input = false;\n        }\n#pragma warning restore BDN1200\n\n#pragma warning disable BDN1201\n        public class PropMultiple1 : Base\n        {\n            [Params(false, true)]\n            [ParamsAllValues]\n            public bool Input { get; set; }\n        }\n#pragma warning restore BDN1201\n\n#pragma warning disable BDN1201\n        public class PropMultiple2 : Base\n        {\n            [Params(false, true)]\n            [ParamsSource(nameof(Source))]\n            public bool Input { get; set; }\n        }\n#pragma warning restore BDN1201\n\n#pragma warning disable BDN1201\n        public class PropMultiple3 : Base\n        {\n            [ParamsAllValues]\n            [ParamsSource(nameof(Source))]\n            public bool Input { get; set; }\n        }\n#pragma warning restore BDN1201\n\n#pragma warning disable BDN1201\n        public class PropMultiple4 : Base\n        {\n            [Params(false, true)]\n            [ParamsAllValues]\n            [ParamsSource(nameof(Source))]\n            public bool Input { get; set; }\n        }\n#pragma warning restore BDN1201\n\n#if NET5_0_OR_GREATER\n\n        [Fact] public void InitOnly1Test() => Check<InitOnly1>(nameof(InitOnly1.Input), \"init-only\", P);\n        [Fact] public void InitOnly2Test() => Check<InitOnly2>(nameof(InitOnly2.Input), \"init-only\", Pa);\n        [Fact] public void InitOnly3Test() => Check<InitOnly3>(nameof(InitOnly3.Input), \"init-only\", Ps);\n\n#pragma warning disable BDN1206\n        public class InitOnly1 : Base\n        {\n            [Params(false, true)]\n            public bool Input { get; init; }\n        }\n#pragma warning restore BDN1206\n\n#pragma warning disable BDN1206\n        public class InitOnly2 : Base\n        {\n            [ParamsAllValues]\n            public bool Input { get; init; }\n        }\n#pragma warning restore BDN1206\n\n#pragma warning disable BDN1206\n        public class InitOnly3 : Base\n        {\n            [ParamsSource(nameof(Source))]\n            public bool Input { get; init; }\n        }\n#pragma warning restore BDN1206\n\n#endif\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Validators/ReturnValueValidatorTests.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text.RegularExpressions;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Validators;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests.Validators\n{\n    public class ReturnValueValidatorTests\n    {\n        private const string ErrorMessagePrefix = \"Inconsistent benchmark return values\";\n\n        [Fact]\n        public void ThrowingBenchmarksAreDiscovered()\n        {\n            var validationErrors = ReturnValueValidator.FailOnError.Validate(BenchmarkConverter.TypeToBenchmarks(typeof(ThrowingBenchmark))).ToList();\n\n            Assert.Single(validationErrors);\n            Assert.Contains(\"Oops, sorry\", validationErrors.Single().Message);\n        }\n\n        public class ThrowingBenchmark\n        {\n            [Benchmark]\n            public void Foo() => throw new InvalidOperationException(\"Oops, sorry\");\n        }\n\n        [Fact]\n        public void InconsistentReturnValuesAreDiscovered()\n        {\n            var validationErrors = AssertInconsistent<InconsistentResults>();\n            Assert.Single(validationErrors);\n        }\n\n        public class InconsistentResults\n        {\n            [Benchmark]\n            public int Foo() => 42;\n\n            [Benchmark]\n            public int Bar() => 41;\n        }\n\n        [Fact]\n        public void NoDuplicateResultsArePrinted()\n        {\n            var validationErrors = AssertInconsistent<InconsistentResultsWithMultipleJobs>();\n            Assert.Single(validationErrors);\n\n            var allInstancesOfFoo = Regex.Matches(validationErrors.Single().Message, @\"\\bFoo\\b\");\n            Assert.Single(allInstancesOfFoo);\n        }\n\n        [DryJob, InProcess]\n        public class InconsistentResultsWithMultipleJobs\n        {\n            [Benchmark]\n            public int Foo() => 42;\n\n            [Benchmark]\n            public int Bar() => 41;\n        }\n\n        [Fact]\n        public void ConsistentReturnValuesAreOmitted()\n            => AssertConsistent<ConsistentResults>();\n\n        public class ConsistentResults\n        {\n            [Benchmark]\n            public int Foo() => 42;\n\n            [Benchmark]\n            public int Bar() => 42;\n        }\n\n        [Fact]\n        public void BenchmarksWithOnlyVoidMethodsAreOmitted()\n            => AssertConsistent<VoidMethods>();\n\n        public class VoidMethods\n        {\n            [Benchmark]\n            public void Foo() { }\n\n            [Benchmark]\n            public void Bar() { }\n        }\n\n        [Fact]\n        public void VoidMethodsAreIgnored()\n            => AssertConsistent<ConsistentResultsWithVoidMethod>();\n\n        public class ConsistentResultsWithVoidMethod\n        {\n            [Benchmark]\n            public int Foo() => 42;\n\n            [Benchmark]\n            public int Bar() => 42;\n\n            [Benchmark]\n            public void Baz() { }\n        }\n\n        [Fact]\n        public void ConsistentReturnValuesInParameterGroupAreOmitted()\n            => AssertConsistent<ConsistentResultsPerParameterGroup>();\n\n        public class ConsistentResultsPerParameterGroup\n        {\n            [Params(1, 2, 3)]\n            public int Value { get; set; }\n\n            [Benchmark]\n            public int Foo() => Value;\n\n            [Benchmark]\n            public int Bar() => Value;\n        }\n\n        [Fact]\n        public void InconsistentReturnValuesInParameterGroupAreDetected()\n        {\n            var validationErrors = AssertInconsistent<InconsistentResultsPerParameterGroup>();\n            Assert.Equal(2, validationErrors.Count);\n        }\n\n        public class InconsistentResultsPerParameterGroup\n        {\n            [Params(1, 2, 3)]\n            public int Value { get; set; }\n\n            [Benchmark]\n            public int Foo() => Value;\n\n            [Benchmark]\n            public int Bar() => 2;\n        }\n\n        [Fact]\n        public void ConsistentCollectionsAreOmitted()\n            => AssertConsistent<ConsistentCollectionReturnType>();\n\n        public class ConsistentCollectionReturnType\n        {\n            [Benchmark]\n            public List<int> Foo() => [1, 2, 3];\n\n            [Benchmark]\n            public int[] Bar() => [1, 2, 3];\n        }\n\n        [Fact]\n        public void InconsistentCollectionsAreDetected()\n            => AssertInconsistent<InconsistentCollectionReturnType>();\n\n        public class InconsistentCollectionReturnType\n        {\n            [Benchmark]\n            public List<int> Foo() => [1, 2, 3];\n\n            [Benchmark]\n            public int[] Bar() => [1, 42, 3];\n        }\n\n        [Fact]\n        public void ConsistentDictionariesAreOmitted()\n            => AssertConsistent<ConsistentDictionaryReturnType>();\n\n        public class ConsistentDictionaryReturnType\n        {\n            [Benchmark]\n            public Dictionary<string, int> Foo() => new Dictionary<string, int> { { \"Foo\", 1 }, { \"Bar\", 2 }, { \"Baz\", 3 } };\n\n            [Benchmark]\n            public Dictionary<string, int> Bar() => new Dictionary<string, int> { [\"Baz\"] = 3, [\"Foo\"] = 1, [\"Bar\"] = 2 };\n        }\n\n        [Fact]\n        public void InconsistentDictionariesAreDetected()\n            => AssertInconsistent<InconsistentDictionaryReturnType>();\n\n        public class InconsistentDictionaryReturnType\n        {\n            [Benchmark]\n            public Dictionary<string, int> Foo() => new Dictionary<string, int> { { \"Foo\", 1 }, { \"Bar\", 42 }, { \"Baz\", 3 } };\n\n            [Benchmark]\n            public Dictionary<string, int> Bar() => new Dictionary<string, int> { [\"Baz\"] = 3, [\"Foo\"] = 1, [\"Bar\"] = 2 };\n        }\n\n        [Fact]\n        public void ConsistentCustomEquatableImplementationIsOmitted()\n            => AssertConsistent<ConsistentCustomEquatableReturnType>();\n\n        public class ConsistentCustomEquatableReturnType\n        {\n            [Benchmark]\n            public CustomEquatableA Foo() => new CustomEquatableA();\n\n            [Benchmark]\n            public CustomEquatableB Bar() => new CustomEquatableB();\n        }\n\n        [Fact]\n        public void InconsistentCustomEquatableImplementationIsDetected()\n            => AssertInconsistent<InconsistentCustomEquatableReturnType>();\n\n        public class InconsistentCustomEquatableReturnType\n        {\n            [Benchmark]\n            public CustomEquatableA Foo() => new CustomEquatableA();\n\n            [Benchmark]\n            public CustomEquatableA Bar() => new CustomEquatableA();\n        }\n\n        public class CustomEquatableA : IEquatable<CustomEquatableB>\n        {\n            public bool Equals(CustomEquatableB? other) => other != null;\n\n            public override bool Equals(object? obj) => false; // Intentionally bad implementation\n\n            public override int GetHashCode() => 0;\n        }\n\n        public class CustomEquatableB : IEquatable<CustomEquatableA>\n        {\n            public bool Equals(CustomEquatableA? other) => other != null;\n\n            public override bool Equals(object? obj) => false; // Intentionally bad implementation\n\n            public override int GetHashCode() => 0;\n        }\n\n        [Fact]\n        public void ConsistentBenchmarksAlteringParameterAreOmitted()\n            => AssertConsistent<ConsistentAlterParam>();\n\n        public class ConsistentAlterParam\n        {\n            [Params(10, 20, 30)]\n            public int Value { get; set; }\n\n            [Benchmark]\n            public int Foo() => ++Value;\n\n            [Benchmark]\n            public int Bar() => ++Value;\n        }\n\n        private static void AssertConsistent<TBenchmark>()\n        {\n            var validationErrors = ReturnValueValidator.FailOnError.Validate(BenchmarkConverter.TypeToBenchmarks(typeof(TBenchmark))).ToList();\n\n            Assert.Empty(validationErrors);\n        }\n\n        private static List<ValidationError> AssertInconsistent<TBenchmark>()\n        {\n            var validationErrors = ReturnValueValidator.FailOnError.Validate(BenchmarkConverter.TypeToBenchmarks(typeof(TBenchmark))).ToList();\n\n            Assert.NotEmpty(validationErrors);\n            Assert.All(validationErrors, error => Assert.StartsWith(ErrorMessagePrefix, error.Message));\n\n            return validationErrors;\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Validators/RuntimeValidatorTests.cs",
    "content": "﻿using BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Toolchains.CsProj;\nusing BenchmarkDotNet.Validators;\nusing System.Linq;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests.Validators;\n\npublic class RuntimeValidatorTests\n{\n    [Fact]\n    public void SameRuntime_Should_Success()\n    {\n        // Arrange\n        var config = new TestConfig1().CreateImmutableConfig();\n        var runInfo = BenchmarkConverter.TypeToBenchmarks(typeof(DummyBenchmark), config);\n        var parameters = new ValidationParameters(runInfo.BenchmarksCases, config);\n\n        // Act\n        var errors = RuntimeValidator.DontFailOnError.Validate(parameters).Select(e => e.Message).ToArray();\n\n        // Assert\n        Assert.Empty(errors);\n    }\n\n    [Fact]\n    public void NullRuntimeMixed_Should_Failed()\n    {\n        // Arrange\n        var config = new TestConfig2().CreateImmutableConfig();\n        var runInfo = BenchmarkConverter.TypeToBenchmarks(typeof(DummyBenchmark), config);\n        var parameters = new ValidationParameters(runInfo.BenchmarksCases, config);\n\n        // Act\n        var errors = RuntimeValidator.DontFailOnError.Validate(parameters).Select(e => e.Message).ToArray();\n\n        // Assert\n        {\n            var expectedMessage = \"Job(Dry) doesn't have a Runtime characteristic. It's recommended to specify runtime by using WithRuntime explicitly.\";\n            Assert.Contains(expectedMessage, errors);\n        }\n        {\n            var expectedMessage = \"Job(Toolchain=.NET 11.0) doesn't have a Runtime characteristic. It's recommended to specify runtime by using WithRuntime explicitly.\";\n            Assert.Contains(expectedMessage, errors);\n        }\n    }\n\n    [Fact]\n    public void NotNullRuntimeOnly_Should_Success()\n    {\n        // Arrange\n        var config = new TestConfig3().CreateImmutableConfig();\n        var runInfo = BenchmarkConverter.TypeToBenchmarks(typeof(DummyBenchmark), config);\n        var parameters = new ValidationParameters(runInfo.BenchmarksCases, config);\n\n        // Act\n        var errors = RuntimeValidator.DontFailOnError.Validate(parameters).Select(e => e.Message).ToArray();\n\n        // Assert\n        Assert.Empty(errors);\n    }\n\n    public class DummyBenchmark\n    {\n        [Benchmark]\n        public void Benchmark()\n        {\n        }\n    }\n\n    // TestConfig that expicitly specify runtime.\n    private class TestConfig1 : ManualConfig\n    {\n        public TestConfig1()\n        {\n            var baseJob = Job.Dry;\n\n            WithOption(ConfigOptions.DisableOptimizationsValidator, true);\n            AddColumnProvider(DefaultConfig.Instance.GetColumnProviders().ToArray());\n\n            AddJob(baseJob.WithToolchain(CsProjCoreToolchain.NetCoreApp80));\n            AddJob(baseJob.WithToolchain(CsProjCoreToolchain.NetCoreApp90));\n        }\n    }\n\n    // TestConfig that contains job that don't specify runtime.\n    private class TestConfig2 : ManualConfig\n    {\n        public TestConfig2()\n        {\n            var baseJob = Job.Dry;\n\n            WithOption(ConfigOptions.DisableOptimizationsValidator, true);\n            AddColumnProvider(DefaultConfig.Instance.GetColumnProviders().ToArray());\n\n            AddJob(baseJob.WithToolchain(CsProjCoreToolchain.NetCoreApp80));\n            AddJob(baseJob.WithToolchain(CsProjCoreToolchain.NetCoreApp90)\n                          .WithRuntime(CoreRuntime.Core90));\n\n            // Validate error message for auto generated jobid.\n            AddJob(Job.Default.WithToolchain(CsProjCoreToolchain.NetCoreApp11_0));\n        }\n    }\n\n    // TestConfig that expicitly specify runtime.\n    private class TestConfig3 : ManualConfig\n    {\n        public TestConfig3()\n        {\n            var baseJob = Job.Dry;\n\n            WithOption(ConfigOptions.DisableOptimizationsValidator, true);\n            AddColumnProvider(DefaultConfig.Instance.GetColumnProviders().ToArray());\n\n            AddJob(baseJob.WithToolchain(CsProjCoreToolchain.NetCoreApp80)\n                          .WithRuntime(CoreRuntime.Core80)); ;\n            AddJob(baseJob.WithToolchain(CsProjCoreToolchain.NetCoreApp90)\n                          .WithRuntime(CoreRuntime.Core90));\n        }\n    }\n}\n"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/Validators/SetupCleanupValidatorTests.cs",
    "content": "﻿using System.Linq;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Validators;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests.Validators\n{\n    public class SetupCleanupValidatorTests\n    {\n        public class BlankTargetClass\n        {\n            [GlobalSetup] public void SetupA() { }\n            [GlobalSetup] public void SetupB() { }\n            [Benchmark] public void Benchmark() { }\n        }\n\n        [Fact]\n        public void InvalidGlobalSetupTooManyBlankTargets()\n        {\n            var validationErrors = SetupCleanupValidator.FailOnError.Validate(\n                BenchmarkConverter.TypeToBenchmarks(typeof(BlankTargetClass))).ToArray();\n\n            var count = validationErrors.Count(v =>\n                v.IsCritical && v.Message.Contains(\"[GlobalSetupAttribute]\") && v.Message.Contains(\"Blank\"));\n\n            Assert.Equal(1, count);\n        }\n\n        public class ExplicitTargetClass\n        {\n            [GlobalSetup(Target = nameof(Benchmark))] public void SetupA() { }\n            [GlobalSetup(Target = nameof(Benchmark))] public void SetupB() { }\n            [Benchmark] public void Benchmark() { }\n        }\n\n        [Fact]\n        public void InvalidGlobalSetupTooManyExplicitTargets()\n        {\n            var validationErrors = SetupCleanupValidator.FailOnError.Validate(\n                BenchmarkConverter.TypeToBenchmarks(typeof(ExplicitTargetClass))).ToArray();\n\n            var count = validationErrors.Count(v =>\n                v.IsCritical && v.Message.Contains(\"[GlobalSetupAttribute]\") && v.Message.Contains(\"Target = Benchmark\"));\n\n            Assert.Equal(1, count);\n        }\n    }\n}\n"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/XUnit/EnvRequirement.cs",
    "content": "namespace BenchmarkDotNet.Tests.XUnit;\n\npublic enum EnvRequirement\n{\n    WindowsOnly,\n    NonWindows,\n    NonWindowsArm,\n    NonLinux,\n    NonLinuxArm,\n    FullFrameworkOnly,\n    NonFullFramework,\n    DotNetCoreOnly,\n    NeedsPrivilegedProcess\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/XUnit/EnvRequirementChecker.cs",
    "content": "using BenchmarkDotNet.Environments;\nusing System;\nusing System.Linq;\nusing System.Runtime.InteropServices;\nusing System.Security.Principal;\nusing BdnRuntimeInformation = BenchmarkDotNet.Portability.RuntimeInformation;\n\nnamespace BenchmarkDotNet.Tests.XUnit;\n\npublic static class EnvRequirementChecker\n{\n    public static string? GetSkip(params EnvRequirement[] requirements) => requirements.Select(GetSkip).FirstOrDefault(skip => skip != null);\n\n    internal static string? GetSkip(EnvRequirement requirement) => requirement switch\n    {\n        EnvRequirement.WindowsOnly => RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? null : \"Windows-only test\",\n        EnvRequirement.NonWindows => !RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? null : \"Non-Windows test\",\n        EnvRequirement.NonWindowsArm => !RuntimeInformation.IsOSPlatform(OSPlatform.Windows) || !IsArm() ? null : \"Non-Windows+Arm test\",\n        EnvRequirement.NonLinux => !RuntimeInformation.IsOSPlatform(OSPlatform.Linux) ? null : \"Non-Linux test\",\n        EnvRequirement.NonLinuxArm => !RuntimeInformation.IsOSPlatform(OSPlatform.Linux) || !IsArm() ? null : \"Non-Linux+Arm test\",\n        EnvRequirement.FullFrameworkOnly => BdnRuntimeInformation.IsFullFramework ? null : \"Full .NET Framework-only test\",\n        EnvRequirement.NonFullFramework => !BdnRuntimeInformation.IsFullFramework ? null : \"Non-Full .NET Framework test\",\n        EnvRequirement.DotNetCoreOnly => BdnRuntimeInformation.IsNetCore ? null : \".NET/.NET Core-only test\",\n        EnvRequirement.NeedsPrivilegedProcess => IsPrivilegedProcess() ? null : \"Needs authorization to perform security-relevant functions\",\n        _ => throw new ArgumentOutOfRangeException(nameof(requirement), requirement, \"Unknown value\")\n    };\n\n    private static bool IsPrivilegedProcess()\n    {\n#if NET462\n        using WindowsIdentity currentUser = WindowsIdentity.GetCurrent();\n        return new WindowsPrincipal(currentUser).IsInRole(WindowsBuiltInRole.Administrator);\n#else\n        return Environment.IsPrivilegedProcess;\n#endif\n    }\n\n    private static bool IsArm()\n        => BdnRuntimeInformation.GetCurrentPlatform() is Platform.Arm64 or Platform.Arm or Platform.Armv6;\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/XUnit/EnvRequirementCheckerTests.cs",
    "content": "using System;\nusing System.Linq;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests.XUnit;\n\npublic class EnvRequirementCheckerTests\n{\n    [Fact]\n    public void AllEnvRequirementsAreSupported()\n    {\n        foreach (var envRequirement in Enum.GetValues(typeof(EnvRequirement)).Cast<EnvRequirement>())\n            EnvRequirementChecker.GetSkip(envRequirement);\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/XUnit/FactEnvSpecific.cs",
    "content": "using Xunit;\n\nnamespace BenchmarkDotNet.Tests.XUnit;\n\npublic class FactEnvSpecificAttribute : FactAttribute\n{\n    public FactEnvSpecificAttribute(params EnvRequirement[] requirements)\n    {\n        Skip = EnvRequirementChecker.GetSkip(requirements);\n    }\n\n    public FactEnvSpecificAttribute(string reason, params EnvRequirement[] requirements)\n    {\n        string? skip = EnvRequirementChecker.GetSkip(requirements);\n        if (skip != null)\n            Skip = $\"{skip} ({reason})\";\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/XUnit/SmartAssert.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Text;\n\nnamespace BenchmarkDotNet.Tests.XUnit\n{\n    public static class SmartAssert\n    {\n        public static void Equal<T>(IReadOnlyList<T> expected, IReadOnlyList<T> actual)\n        {\n            Exception CreateException(string comment)\n            {\n                var builder = new StringBuilder();\n                builder.AppendLine($\"Failure ({comment})\");\n                builder.AppendLine(\"*** Expected ***\");\n                for (int i = 0; i < expected.Count; i++)\n                    builder.AppendLine($\"[{i}]: {expected[i]}\");\n                builder.AppendLine(\"*** Actual ***\");\n                for (int i = 0; i < actual.Count; i++)\n                    builder.AppendLine($\"[{i}]: {actual[i]}\");\n                return new Exception(builder.ToString());\n            }\n\n            if (expected.Count != actual.Count)\n                throw CreateException(\"Length mismatch\");\n            for (int i = 0; i < expected.Count; i++)\n                if (!Equals(expected[i], actual[i]))\n                    throw CreateException($\"Element mismatch (index={i})\");\n        }\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/XUnit/TheoryEnvSpecific.cs",
    "content": "using Xunit;\n\nnamespace BenchmarkDotNet.Tests.XUnit;\n\npublic class TheoryEnvSpecificAttribute : TheoryAttribute\n{\n    public TheoryEnvSpecificAttribute(params EnvRequirement[] requirements)\n    {\n        Skip = EnvRequirementChecker.GetSkip(requirements);\n    }\n\n    public TheoryEnvSpecificAttribute(string reason, params EnvRequirement[] requirements)\n    {\n        string? skip = EnvRequirementChecker.GetSkip(requirements);\n        if (skip != null)\n            Skip = $\"{skip} ({reason})\";\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/dotMemory/DotMemoryTests.cs",
    "content": "using System;\nusing BenchmarkDotNet.Diagnostics.dotMemory;\nusing BenchmarkDotNet.Jobs;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests.dotMemory;\n\npublic class DotMemoryTests\n{\n    [Fact]\n    public void AllRuntimeMonikerAreKnown()\n    {\n        var diagnoser = new DotMemoryDiagnoser();\n        foreach (RuntimeMoniker moniker in Enum.GetValues<RuntimeMoniker>())\n            diagnoser.IsSupported(moniker); // Just check that it doesn't throw exceptions\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/dotTrace/DotTraceTests.cs",
    "content": "using System;\nusing BenchmarkDotNet.Diagnostics.dotTrace;\nusing BenchmarkDotNet.Jobs;\nusing Xunit;\n\nnamespace BenchmarkDotNet.Tests.dotTrace;\n\npublic class DotTraceTests\n{\n    [Fact]\n    public void AllRuntimeMonikerAreKnown()\n    {\n        var diagnoser = new DotTraceDiagnoser();\n        foreach (RuntimeMoniker moniker in Enum.GetValues<RuntimeMoniker>())\n            diagnoser.IsSupported(moniker); // Just check that it doesn't throw exceptions\n    }\n}"
  },
  {
    "path": "tests/BenchmarkDotNet.Tests/xunit.runner.json",
    "content": "﻿{\n  \"shadowCopy\": false,\n  \"methodDisplay\": \"method\",\n  \"diagnosticMessages\": true,\n  \"longRunningTestSeconds\": 3\n}"
  },
  {
    "path": "tests/CodeCoverage.config",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Configuration>\n  <!-- Available Options: https://github.com/microsoft/codecoverage/blob/main/docs/configuration.md -->\n  <CoverageFileName>coverage.cobertura.xml</CoverageFileName>\n  <Format>cobertura</Format>\n  <IncludeTestAssembly>false</IncludeTestAssembly>\n  <DeterministicReport>true</DeterministicReport>\n  <CollectFromChildProcesses>true</CollectFromChildProcesses>\n  <CodeCoverage>\n    <ModulePaths>\n      <Include>\n        <ModulePath>.*BenchmarkDotNet\\.dll$</ModulePath>\n        <ModulePath>.*BenchmarkDotNet.*\\.dll$</ModulePath>\n      </Include>\n      <Exclude>\n        <!-- Exclude third party DLLs -->\n        <ModulePath>.*Argon\\.dll$</ModulePath>\n        <ModulePath>.*DiffEngine\\.dll$</ModulePath>\n        <ModulePath>.*EmptyFiles\\.dll$</ModulePath>\n        <ModulePath>.*Microsoft\\.CodeAnalysis\\.Analyzer\\.Testing\\.dll$</ModulePath>\n        <ModulePath>.*Microsoft\\.CodeAnalysis\\.CSharp\\.Analyzer\\.Testing\\.dll$</ModulePath>\n        <ModulePath>.*Verify\\.dll$</ModulePath>\n        <ModulePath>.*Verify\\.Xunit\\.dll$</ModulePath>\n\n        <!-- Exclude test DLLs -->\n        <ModulePath>.*BenchmarkDotNet\\.Analyzers\\.Tests\\.dll$</ModulePath>\n        <ModulePath>.*BenchmarkDotNet\\.Tests\\.dll$</ModulePath>\n        <ModulePath>.*BenchmarkDotNet\\.IntegrationTests\\.dll$</ModulePath>\n\n        <!-- Exclude auto generated project DLLs -->\n        <ModulePath>.*IntegrationTests.*\\.dll$</ModulePath>\n        <ModulePath>.*Dry.*\\.dll$</ModulePath>\n        <ModulePath>.*FSharp.Core\\.dll$</ModulePath>\n      </Exclude>\n    </ModulePaths>\n    <Attributes>\n      <Exclude>\n        <Attribute>^System\\.CodeDom\\.Compiler\\.GeneratedCodeAttribute$</Attribute>\n      </Exclude>\n    </Attributes>\n    <Sources>\n      <Exclude>\n        <Source>.*\\\\[^\\\\]*\\CodeAnnotations\\.cs</Source>\n        <Source>.*\\\\[^\\\\]*\\.g\\.cs</Source>\n        <Source>.*\\\\[^\\\\]*\\.notcs</Source>\n      </Exclude>\n    </Sources>\n    <!-- Disable following settings. Because C++ code is not contained (See: https://github.com/microsoft/codecoverage/blob/main/README.md#get-started)-->\n    <EnableStaticNativeInstrumentation>False</EnableStaticNativeInstrumentation>\n    <EnableDynamicNativeInstrumentation>False</EnableDynamicNativeInstrumentation>\n  </CodeCoverage>\n</Configuration>\n"
  },
  {
    "path": "tests/Directory.Build.props",
    "content": "<Project>\n  <PropertyGroup>\n    <GenerateDocumentationFile>false</GenerateDocumentationFile>\n    <IsPackable>false</IsPackable>\n  </PropertyGroup>\n\n  <PropertyGroup>\n    <!-- Set SolutionDir property to suppress warning that raised by Verify.Xunit solution discovery feature. -->\n    <SolutionDir>$([System.IO.Path]::GetDirectoryName($(MSBuildThisFileDirectory)))</SolutionDir>\n  </PropertyGroup>\n\n  <!-- ProjectReferences are not transitive, so we need to directly include the analyzers for all test projects. -->\n  <ItemGroup Condition=\"'$(AssemblyName)' != 'BenchmarkDotNet.Analyzers.Tests'\">\n    <ProjectReference Include=\"$(MSBuildThisFileDirectory)..\\src\\BenchmarkDotNet.Analyzers\\BenchmarkDotNet.Analyzers.csproj\" ReferenceOutputAssembly=\"false\" OutputItemType=\"Analyzer\" />\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "tests/runClassicTests.cmd",
    "content": "@echo off\n\necho -----------------------------\necho Running dotnet restore\necho -----------------------------\n\ncall dotnet restore \"BenchmarkDotNet.IntegrationTests\\BenchmarkDotNet.IntegrationTests.csproj\"\n\nif NOT %ERRORLEVEL% == 0 (\n    echo Dotnet restore has failed\n    goto end\n)\n\necho -----------------------------\necho Running .NET 4.6.1 Unit tests\necho -----------------------------\n\ncall dotnet test \"BenchmarkDotNet.Tests\\BenchmarkDotNet.Tests.csproj\" --configuration Release --framework net461\n\nif NOT %ERRORLEVEL% == 0 (\n    echo .NET 4.6.1 Unit tests has failed\n    goto end\n)\n\n\necho -----------------------------\necho Running .NET 4.6.1 Integration tests\necho -----------------------------\n\ncall dotnet test \"BenchmarkDotNet.IntegrationTests\\BenchmarkDotNet.IntegrationTests.csproj\" --configuration Release --framework net461\n\nif NOT %ERRORLEVEL% == 0 (\n    echo .NET 4.6.1 Integration tests has failed\n    goto end\n)\n\necho -----------------------------\necho All tests has passed for .NET 4.6.1\necho -----------------------------\n\n:end"
  },
  {
    "path": "tests/runCoreTests.cmd",
    "content": "@echo off\n\necho -----------------------------\necho Running dotnet restore\necho -----------------------------\n\ncall dotnet restore \"BenchmarkDotNet.IntegrationTests\\BenchmarkDotNet.IntegrationTests.csproj\"\n\nif NOT %ERRORLEVEL% == 0 (\n    echo Dotnet restore has failed\n    goto end\n)\n\necho -----------------------------\necho Running Core 8.0 Unit tests\necho -----------------------------\n\ncall dotnet test \"BenchmarkDotNet.Tests\\BenchmarkDotNet.Tests.csproj\" --configuration Release --framework net8.0\n\nif NOT %ERRORLEVEL% == 0 (\n    echo Core 8.0 Unit tests has failed\n    goto end\n)\n\necho -----------------------------\necho Running 8.0 Integration tests\necho -----------------------------\n\ncall dotnet test \"BenchmarkDotNet.IntegrationTests\\BenchmarkDotNet.IntegrationTests.csproj\" --configuration Release --framework net8.0\n\nif NOT %ERRORLEVEL% == 0 (\n    echo Core 8.0 Integration tests has failed\n    goto end\n)\n\necho -----------------------------\necho All tests has passed for Core\necho -----------------------------\n\n:end"
  },
  {
    "path": "tests/runCoreTests.sh",
    "content": "#!/usr/bin/env bash\ndotnet test BenchmarkDotNet.Tests/BenchmarkDotNet.Tests.csproj --configuration Release --framework net8.0 2>&1 | tee tests.log\ndotnet test BenchmarkDotNet.IntegrationTests/BenchmarkDotNet.IntegrationTests.csproj --configuration Release --framework net8.0 2>&1 | tee integration-tests.log\n"
  }
]